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 one master 2 slaves

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



Joined: 23 Sep 2010
Posts: 13

View user's profile Send private message

i2c one master 2 slaves
PostPosted: Wed Dec 08, 2010 6:25 am     Reply with quote

Hi all... I have a master (18F452) and two slave (18F877A) chips. When I use the i2c communication with one master and one slave individually, it works perfectly (thanks to forum). But when i try to use it with two slaves it fails. It seems the communication stucks in the second slave's write condition. I saw there are lots of threads like mine (expecially http://www.ccsinfo.com/forum/viewtopic.php?t=39242) but I couldn't fix my problem. I am testing my project both in Proteus and board. The results are the same. I checked a million times and pretty sure about my hardware (pull-up resistors, connections etc.).

My compiler version is 4.110

Master code
Code:
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, FORCE_HW, FORCE_SW)

#define SLAVE1_WRT_ADDR   0x12
#define SLAVE1_READ_ADDR  0x13

#define SLAVE2_WRT_ADDR   0x24
#define SLAVE2_READ_ADDR  0x25

void i2c_first (){
   int i;   
   i2c_start();
   i2c_write(SLAVE1_READ_ADDR);
   delay_ms(100);
   end=i2c_read(0); 
   i2c_stop();
   delay_ms(1000);
}

void i2c_second (){
   int i;
   i2c_start();
   i2c_write(SLAVE2_READ_ADDR);
   delay_ms(100);
   end2=i2c_read(0);
   i2c_stop();
   delay_ms(1000);
}

void main()
{
   while(1)
   {
     
      if(input(PIN_A0)) {
         delay_ms(500);
         i2c_first();
      }
      if(!input(PIN_A0)){
         delay_ms(500);
         i2c_second();
      } 
     
   }
}


Slave code
Code:
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x12)

#INT_SSP
void ssp_interrupt()
{
   int8 incoming, state;
   
   state = i2c_isr_state();
   
   if(state < 0x80)     // Master is sending data
   {
      incoming = i2c_read();
   }

   if((state >= 0x80))   // Master is requesting data from slave
   {     
      i2c_write(0x13);       
   }
  }
}

void main ()
{   
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);

   while(1){
   
   }
}


Slave2 code
Code:
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x24)

#INT_SSP
void ssp_interrupt()
{
   int8 incoming, state;
   
   state = i2c_isr_state();
   
   if(state < 0x80)     // Master is sending data
   {
      incoming = i2c_read();
   }

   if((state >= 0x80))   // Master is requesting data from slave
   {     
      i2c_write(0x25);       
   }
  }
}

void main ()
{   
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);

   while(1){
   
   }
}


Can anyone help me with this?
temtronic



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

View user's profile Send private message

PostPosted: Wed Dec 08, 2010 6:50 am     Reply with quote

First, I'm not sure how you figure it isn't working right. All Master does is talk to the one of the slaves,depending on the condition of a pin. There is no obvious feedback (LED, LCD) to say what is happening..

I'd have a bytes worth of LEDs on a port to display the I2C data being read back from the slaves(..end..end2 variables) in Main().

Second, have you swapped the slaves' I2C addresses? Since you say #1 is fine, recode it as #2 and test .Do the same for #2 as #1, This will show if the fault follows the chip(hardware) or program(software).

Third, I wouldn't put any faith in Proteus as simulations aren't the Real World. That being said, you say the hardware isn't working right either.

Fourth,I'm not a PIC18 series guy, but maybe some conflict with periperals,xtal selection,etc. or a die errata ???

Fifth, I'd have the slaves send back different data and see the results,again on the LEDs, to be sure it's not a wiring problem,maybe a timing issue ?
Oblivion



Joined: 23 Sep 2010
Posts: 13

View user's profile Send private message

PostPosted: Wed Dec 08, 2010 7:18 am     Reply with quote

Thanks for your concern, temtronic...

Of course i have LEDs and a LCD on my project but i didn't post those codes here to simplify my problem. I can see the results on both LEDs, LCD and proteus's i2c tester.

The order or addresses of the slaves don't change the result.

And i tried to send different data from the slaves but it didn't change anything either.

Yes it may be a timing issue. Because of that i tried to put delays nearly every line of the codes. But it didn't helped....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Dec 08, 2010 12:09 pm     Reply with quote

Post your real test programs. The i2c programs shown in the link
http://www.ccsinfo.com/forum/viewtopic.php?t=39242
are full test programs. They have the #include for the PIC, #fuses,
#use delay, all variable declarations, etc. Your code is missing all of that.

Quote:
I am testing my project both in Proteus and board.

Proteus may not work.

Are all the PICs (master and two slaves) on the same board ?
Post a description of the hardware.

Post a list of all connections between the 3 PICs (master and two slaves).

What is the value of the two pull-up resistors on the SDA and SCL lines ?

What's the Vdd voltage of the PICs ?
Oblivion



Joined: 23 Sep 2010
Posts: 13

View user's profile Send private message

PostPosted: Thu Dec 09, 2010 1:16 am     Reply with quote

Thanks for your reply...

Master code:
Code:
#include <18f452.h>

#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7) 
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)

#include "LCD_4x20.c"
   
#define SLAVE1_WRT_ADDR   0x12
#define SLAVE1_READ_ADDR  0x13

#define SLAVE2_WRT_ADDR   0x24
#define SLAVE2_READ_ADDR  0x25

int8 data1,data2,end,end2;

void i2c_first (){
   i2c_start();
   i2c_write(SLAVE1_READ_ADDR);
   delay_ms(100);
   data1=i2c_read();
   end=i2c_read(0); 
   i2c_stop();
   delay_ms(1000);
}

void i2c_second (){
   i2c_start();
   i2c_write(SLAVE2_READ_ADDR);
   delay_ms(100);
   data2=i2c_read();
   end2=i2c_read(0);
   i2c_stop();
   delay_ms(1000);
}

void main()
{
   while(1)
   {
     
      if(input(PIN_A0)) {
         delay_ms(500);
         i2c_first();
      }
      if(!input(PIN_A0)){
         delay_ms(500);
         i2c_second();
      } 
     
      printf(lcd_putc," [ %x %x  ] \r\n", data1,data2);
   }
}


Slave1 code:
Code:
#include <16F877a.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x12)

#INT_SSP
void ssp_interrupt()
{
   int8 incoming, state;
   
   state = i2c_isr_state();
   
   if(state < 0x80)     // Master is sending data
   {
      incoming = i2c_read();
   }

   if((state >= 0x80))   // Master is requesting data from slave
   {
      output_high(PIN_D0);     
      i2c_write(0x13);       
   }
   if(state>=0x82) output_low(PIN_D0);
   
  }
}

void main ()
{   
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);

   while(1){
   
   }
}


Slave2 code:
Code:
#include <16F877a.h>
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x24)

#INT_SSP
void ssp_interrupt()
{
   int8 incoming, state;
   
   state = i2c_isr_state();
   
   if(state < 0x80)     // Master is sending data
   {
      incoming = i2c_read();
   }

   if((state >= 0x80))   // Master is requesting data from slave
   {
      output_high(PIN_D0);     
      i2c_write(0x25);       
   }
   if(state>=0x82) output_low(PIN_D0);
   
  }
}

void main ()
{   
   enable_interrupts(INT_SSP);
   enable_interrupts(GLOBAL);

   while(1){
   
   }
}



All my equipment are on the same board. And i use the this board with my other (working) projects.

I used 4.7k pull-up resistors on the SDA and SCL lines (Just 2 resistors).

Vdd voltage is 5V.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Dec 09, 2010 1:31 am     Reply with quote

Quote:
#include <18f452.h>

#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)

Using the XT fuse with a 20 MHz crystal, tells me that you're running
this in Proteus. I don't think Proteus cares about using the correct
oscillator fuse.

But Proteus simply cannot be trusted to work for every situation.
Here is a thread, where he has to upgrade to Proteus vs. 7.6
to make an i2c slave project work correctly:
http://www.ccsinfo.com/forum/viewtopic.php?t=32368&start=36
Oblivion



Joined: 23 Sep 2010
Posts: 13

View user's profile Send private message

PostPosted: Thu Dec 09, 2010 6:21 am     Reply with quote

Quote:
But Proteus simply cannot be trusted to work for every situation.
Here is a thread, where he has to upgrade to Proteus vs. 7.6
to make an i2c slave project work correctly:
http://www.ccsinfo.com/forum/viewtopic.php?t=32368&start=36


I am using v7.7 but you're right. Proteus cannot be trusted.

But can you see any mistakes on my codes? I hope i'm mistaking something in software. Are there any suggestions you can give to me?
temtronic



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

View user's profile Send private message

PostPosted: Thu Dec 09, 2010 6:44 am     Reply with quote

get RID of Proteus !!!
It is NOT the Real World !!
Sorry for sounding like a broken record , but this is yet another reason why I do NOT use Proteus or any other simulator.
They do NOT work 100% like hardware.

Maybe this forum needs another folder for just Proteus users...
or.. a fill in the blank form that has PIC type, CCS version, voltages, real or simulation' fields....

It would be helpful in the future to state you're using Proteus or real hardware, so old guys like me that only use real hardware don't bother with stupid simulation software that is impossible to debug and fix.

Btw the mistake in your software is inside Proteus.
plainas1234



Joined: 28 Jun 2011
Posts: 3
Location: Anadia

View user's profile Send private message

PostPosted: Sat Jul 02, 2011 10:19 am     Reply with quote

Staff now thank you for sharing your knowledge in the forum, I'm making a project that involves many analog inputs and so I will use three microcontrollers, up to this code works already, but I'd like to know if you can send a pic slave two 8-bit data that is two bytes and receive the master with 2 i2c_read I've tried this but when I stop the slave pic. I am doing testing on real hardware.

Example of code that did:

code master -> read slave1:
Code:

void i2c_first (){
   i2c_start();
   i2c_write(SLAVE1_READ_ADDR);
   delay_ms(100);
   data1=i2c_read();
   data3=i2c_read();    // ->>  change that caused errors
   end=i2c_read(0);
   i2c_stop();

code slave -> send master:

void i2c_first (){
   i2c_start();
   i2c_write(SLAVE1_READ_ADDR);
   delay_ms(100);
   data1=i2c_read();
   data3=i2c_read();    // ->> change that caused errors
   end=i2c_read(0);
   i2c_stop();
   delay_ms(100);
}
   delay_ms(100);
}


I would appreciate a response because this project is very important to me.
Thank you for your attention ...
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