|
|
View previous topic :: View next topic |
Author |
Message |
semmoor
Joined: 09 May 2012 Posts: 46 Location: KSA
|
strange i2c behavior! |
Posted: Tue Jul 10, 2012 11:07 am |
|
|
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
|
|
Posted: Tue Jul 10, 2012 11:53 am |
|
|
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
|
cool!!! |
Posted: Wed Jul 11, 2012 7:47 am |
|
|
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: 9229 Location: Greensville,Ontario
|
|
Posted: Wed Jul 11, 2012 8:30 am |
|
|
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
|
|
Posted: Wed Jul 11, 2012 10:28 am |
|
|
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: 19520
|
|
Posted: Wed Jul 11, 2012 11:40 am |
|
|
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
|
Thanks |
Posted: Thu Jul 12, 2012 3:45 pm |
|
|
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
|
|
|
semmoor
Joined: 09 May 2012 Posts: 46 Location: KSA
|
thanks |
Posted: Thu Jul 12, 2012 5:25 pm |
|
|
thank you PCM programmer, useful link. |
|
|
RF_Developer
Joined: 07 Feb 2011 Posts: 839
|
|
Posted: Fri Jul 13, 2012 1:43 am |
|
|
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
|
Thanks dear |
Posted: Fri Jul 13, 2012 4:24 pm |
|
|
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. |
|
|
|
|
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
|