CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

I2C master with multiple slaves

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
rfjhh



Joined: 31 Mar 2011
Posts: 51
Location: Mexico

View user's profile Send private message

I2C master with multiple slaves
PostPosted: Tue Jun 20, 2017 9:18 am     Reply with quote

I'm designing a project with a master and 10 or more slaves using I2C protocol. The communication with a single slave works well. But when I begin to connect the second slave, the program desn't work. I found a discussion for a similar problem, but nothing helpful for me .

The codes are as follows:
For Slaves, the code is the same, just the address changes.

MASTER
Code:

#include <16f887.h>
#fuses NOWDT, INTRC_IO, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, CPD, NOWRT, PUT
#use delay(clock=8MHz)
#use i2c(Master, fast, sda=PIN_C4,scl=PIN_C3)
#include <lcd.c>   
#use fast_io(A)                   
#use fast_io(B)
#use fast_io(E)

int8 leer_i2c(int8 dir_esc)
 
{
    int8 dato=0;
    i2c_start ();           //Inicio comunicacion
    delay_us(100);
    i2c_write (dir_esc);    //Direccion del esclavo
    delay_us(100);
    dato = i2c_read(0);    //Leemos en la direccion apuntada anteriormente
    delay_us(100);
    i2c_stop ();            //Fin de la comunicacion
    return(dato);
}

void main()
{
   int8 valor1, valor2;
   set_tris_a(0xff);
   set_tris_e(0xfe);
   lcd_init();
   lcd_gotoxy(1,1);
   printf(lcd_putc, "I2C");
   for(;;)
   {      
      lcd_gotoxy(1,2);
      printf(lcd_putc, "Valor = ");
      valor1 = leer_i2c(0x11);    // 0x10|1 => 0001000 1
      lcd_gotoxy(9,2);
      printf(lcd_putc, "%3u", valor1);
      delay_ms(50);
      valor2 = leer_i2c(0x13);    // 0x12|1 => 0001001 1
      lcd_gotoxy(13,2);
      printf(lcd_putc, "%3u", valor2);
      delay_ms(500);
   }
}


SLAVES
Code:

#include <16f886.h>
#fuses NOWDT, INTRC_IO, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, CPD, NOWRT, PUT
#use delay(clock=8MHz)
#use i2c(SLAVE, fast=100000, sda=PIN_C4, scl=PIN_C3, address=0x12, FORCE_HW)  // for slave 2, for slave 1 address = 0x10
#use fast_io(A)                   
#use fast_io(B)

int8 state, Direc_master, dato;

#int_SSP
void  SSP_isr(void)
{
   dato = input_b();
   state = i2c_isr_state();
      if(state == 0x80)      // Maestro espera datos
   {
      output_high(PIN_A0);      // just for tensting
      delay_ms(200);
      output_low(PIN_A0);
      delay_ms(200);
       i2c_write(dato);
   }
}

void main()
{
   set_tris_b(0xff);
   set_tris_a(0xf0);
   enable_interrupts(INT_SSP);
   enable_interrupts(global);
   output_a(0x00);
   while(1)
   {}
}

Another remark: When I work with a single slave connected to the bus, the communication works well, but if I connect the second slave to the bus (even if I don't perform a read in the master) the system doesn't work.

I included a blinking signal in RA0 to test the entrance to interrupt routine.

Thanks for your help.
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jun 20, 2017 11:01 am     Reply with quote

quick answer...

First, I would load PCM P's 'I2C Scanner' found in the Code Library and confirm your hardware setup is correct. Depending on number of slaves, distance and wiring you'll need to select the correct I2C pullup resistors.

If his program does see all of the slaves, then it's down to your code. Having delays of any kind within an ISR is very, very bad to do. ISRs need to be short and fast, simply set a 'flag' and have main() do the required action.

Jay
rfjhh



Joined: 31 Mar 2011
Posts: 51
Location: Mexico

View user's profile Send private message

PostPosted: Tue Jun 20, 2017 12:15 pm     Reply with quote

At this moment I'm working with Proteus before to do it physically.
Ttelmah



Joined: 11 Mar 2010
Posts: 19520

View user's profile Send private message

PostPosted: Tue Jun 20, 2017 1:17 pm     Reply with quote

Totally pointless.

Proetus's PIC simulator has lots of problems. You can have designs it'll say will work, that won't in the real world, and designs that do work in the real world, that it says won't. So you can spend ages using this to test PIC code, and then have to do it all again when you get to the real chip....

Some comments:

Your PIC is on address 0x12 for write, and 0x13 for read. Yet you have one of your routines talking to address 0x11.
A slave does not have a speed.
The slave for state 0x80, needs to read the received byte, holding the ACK low, and then load the byte to write.
Code:
I2c_read(2); //hold ACK
I2c_write(byte_to_send);

It must always read when a byte is sent, or the hardware can become locked.
temtronic



Joined: 01 Jul 2010
Posts: 9229
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Tue Jun 20, 2017 5:12 pm     Reply with quote

re:
Quote:
... I'm working with Proteus ....

hahaha..

From my encounters with Proteus (and those shown here...), it should be tossed into the 'trash bin' and 'scrubbed' from any serious programmer's PC. There aren't enough hours in the day or space in this forum to say WHY it's a waste of time. It's the 'silly' details it doesn't deal with, like xtal and caps......., wrong voltages, no power supply connections, sigh....

Jay
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group