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

strange i2c behavior!

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



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

strange i2c behavior!
PostPosted: Tue Jul 10, 2012 11:07 am     Reply with quote

Hi everybody.

I'm doing a project connecting two pic microcontroller using i2c protocol.
Master sends data to slave, when slave receives it, it turns on led on port b depending on the data sent.

But the problem is when slave gets the data sent by master it turns on leds on different sequence.

What i need is, first when i send 'a' , all leds should go on, and I'm ok with that.

When i send 'b' all 4 leds on left side should be on ! but it doesn't happen instate slave will turn on leds mixed, which is supposed to happen when i send 'd' not 'b' !!!

so my question is why is this happening, i guess it should go the order i have written on my code but it's jumping to the the last command!! ???

By the way my code below, I hope people would help me:

master:
Code:

#include <16F877.H>

#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP 
#use delay(clock=4M) 
#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3)

#define SLAVE_WRT_ADDR   0xa0
#define SLAVE_READ_ADDR  0xa1

void main()
{
   
   while(1)
   {
      //send a, all LED ON
      i2c_start();
      i2c_write(0xA0); //address of slave
      i2c_write(0x00); //0 means we writing
      i2c_write('a'); //send data
      //delay_ms(100);
      i2c_stop();  delay_ms(100); //sending is done
     
       //send  b, LED ON left 4 ones
      i2c_start();
      i2c_write(0xA0);
      i2c_write(0x00);
      i2c_write('b');
      //delay_ms(100);   
      i2c_stop(); delay_ms(100);
     
      //send c, LED ON right 4 ones
      i2c_start();
      i2c_write(0xA0);
      i2c_write(0x00);
      i2c_write('c');
      //delay_ms(100);   
      i2c_stop(); delay_ms(100);
     
      //send d, LED ON mix
      i2c_start();
      i2c_write(0xA0);
      i2c_write(0x00);
      i2c_write('d'); 
      //delay_ms(100);   
      i2c_stop(); delay_ms(100);
   }
}

Slave:
Code:

#include <16F877.H>
//#fuses INTRC_IO, NOWDT, NOPROTECT, NOBROWNOUT, PUT, NOMCLR, NOCPD, NOPUT
#fuses XT,NOWDT,PUT,BROWNOUT,NOLVP
#use delay(clock=4M) 
//#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0xa0)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0xa0)

//0x80 = 128, a0 = 160, a1 = 161

int8 incoming = 0, state;

BYTE address, buffer[0x10];

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

    if(state == 1)                    //First received byte is address
        address = incoming;
    if(state == 2)                    //Second received byte is data
        buffer[address] = incoming;
  }

switch(incoming) //test sent value by master
{
case 'a': //if it was 'a', turn on all leds on
   output_b(0b11111111);
   delay_ms(1000);
   break;

case 'b': //if it was 'b', turn on 4 leds left side
   output_b(0b11110000);
   delay_ms(1000);
   break;

case 'c': //if it was 'c', turn on 4 leds right side
   output_b(0b00001111);
   delay_ms(1000);
   break;

case 'd':  //if it was 'd', turn on leds mix
   output_b(0b01010101);
   delay_ms(1000);
   break;
}

}

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

while(1)
{
}

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Tue Jul 10, 2012 11:53 am     Reply with quote

Just for a start, get rid of all the delay_ms() statements in your #int_ssp
routine.

If you want delays between the events, you should put the
delay_ms(1000) statements in your Master code (instead of 100 ms).
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

cool!!!
PostPosted: Wed Jul 11, 2012 7:47 am     Reply with quote

Thank you PCM programmer it worked when i did what you said great.

But i have a few questions i hope you help me with them.

first why do we always define two addresses in the master for example in many code about i2c i see you doing this:

#define SLAVE1_WRT_ADDR 0x12

#define SLAVE1_READ_ADDR 0x13

i know the first one is the address of the slave but what is the other one??

because as i know in i2c each device has its own unique address so we can use it when writing or reading from the devices!!!


and my second question is:

How to do bidirectional communication in i2c, like in my code above i can only write to the slave and make the slave response to the command sent, how can i do the bidirectional with i2c??


i think you have done the same but using spi protocol in different topic in this forum, i wish to do the same with i2c but don't even know!!

sorry about that PCM programmer, i'm a beginner starting with this confusing protocol.
temtronic



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

View user's profile Send private message

PostPosted: Wed Jul 11, 2012 8:30 am     Reply with quote

You should really download and read the I2C protocol/system information.
Usually the I2C devices will have a few pages of how the I2C bus works and of course you can go to philips( nxp ...now) and get tons of information from them , as them started it decades ago !

The more you read and understand about the I2C the better,faster and easier it'll be for you to cut code.

I'd also download PCM prgmr's I2C test program as well, A great little tool to help everyone using I2C devices !!
It's in the code library, I think...just search and it'll 'pop up'.

hth
jay
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

PostPosted: Wed Jul 11, 2012 10:28 am     Reply with quote

temtronic wrote:
You should really download and read the I2C protocol/system information.
Usually the I2C devices will have a few pages of how the I2C bus works and of course you can go to philips( nxp ...now) and get tons of information from them , as them started it decades ago !

The more you read and understand about the I2C the better,faster and easier it'll be for you to cut code.

I'd also download PCM prgmr's I2C test program as well, A great little tool to help everyone using I2C devices !!
It's in the code library, I think...just search and it'll 'pop up'.

hth
jay





Thank you temtronic for your answers, i actually read about i2c but you know it's really different than other protocols such as spi and rs232, my problem is i get confused about addressing in i2c.
Ttelmah



Joined: 11 Mar 2010
Posts: 19480

View user's profile Send private message

PostPosted: Wed Jul 11, 2012 11:40 am     Reply with quote

I2C, physically has a _seven bit_ address sent as the top seven bits of a byte. The byte has the read/write bit in it's low bit. So for each device there are two consecutive bytes, one to write to the device, and the other to read.
Now, the original I2C data had the 'address' given as just the seven bits, which then had to be rotated left by one, and combined with the read/write bit. However later manufacturers generally switched to using the two separate read and write addresses.

Best Wishes
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

Thanks
PostPosted: Thu Jul 12, 2012 3:45 pm     Reply with quote

Thank you Ttelmah and everybody who helped me.

Can anyone please show how to do bidirectional communication using I2C??
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Jul 12, 2012 4:17 pm     Reply with quote

Here is a sample program which shows how to request and read data
from an i2c slave PIC:
http://www.ccsinfo.com/forum/viewtopic.php?t=39242&start=6
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

thanks
PostPosted: Thu Jul 12, 2012 5:25 pm     Reply with quote

PCM programmer wrote:
Here is a sample program which shows how to request and read data
from an i2c slave PIC:
http://www.ccsinfo.com/forum/viewtopic.php?t=39242&start=6


thank you PCM programmer, useful link.
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Fri Jul 13, 2012 1:43 am     Reply with quote

I2C is "bi-directional": information can go both ways. It is also Master/slave, in any communication one device has to be the master, which starts things off, and one has to be a slave, responding to commands from the master. Slaves only talk when talked to, they cannot send whenever they want to

It is possible to have multi-master I2C where there is more than one master on a 12C bus. It is apparently possible to get the PIC to work in multi-master I2C, but I've never seen any code that successfully deos it. Its not simple, not easy, and probably not worth doing unless you absolutely need to do it for serious commercial applications. Its very hard to make this work correctly and you need to have a really good grasp of how I2C works, which clearly at this stage you don't have, as if you did you would not have asked this question!

So what do you do? Well, the first question you need to as is why you want to send data both ways at will? What's the requirement? If you really need to then consider CAN, or even just ordinary serial instead.

RF Developer
semmoor



Joined: 09 May 2012
Posts: 46
Location: KSA

View user's profile Send private message Send e-mail MSN Messenger

Thanks dear
PostPosted: Fri Jul 13, 2012 4:24 pm     Reply with quote

RF_Developer wrote:
I2C is "bi-directional": information can go both ways. It is also Master/slave, in any communication one device has to be the master, which starts things off, and one has to be a slave, responding to commands from the master. Slaves only talk when talked to, they cannot send whenever they want to

It is possible to have multi-master I2C where there is more than one master on a 12C bus. It is apparently possible to get the PIC to work in multi-master I2C, but I've never seen any code that successfully deos it. Its not simple, not easy, and probably not worth doing unless you absolutely need to do it for serious commercial applications. Its very hard to make this work correctly and you need to have a really good grasp of how I2C works, which clearly at this stage you don't have, as if you did you would not have asked this question!

So what do you do? Well, the first question you need to as is why you want to send data both ways at will? What's the requirement? If you really need to then consider CAN, or even just ordinary serial instead.

RF Developer


Thank you RF_Developer, i enjoyed reading what you wrote, useful info, you're right about, why do i want to send data both ways?

just curiosity to be honest.

i love playing with microcontrollers and i enjoy doing that.

thanks again.
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