|
|
View previous topic :: View next topic |
Author |
Message |
Oblivion
Joined: 23 Sep 2010 Posts: 13
|
i2c one master 2 slaves |
Posted: Wed Dec 08, 2010 6:25 am |
|
|
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
|
|
Posted: Wed Dec 08, 2010 6:50 am |
|
|
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
|
|
Posted: Wed Dec 08, 2010 7:18 am |
|
|
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
|
|
Posted: Wed Dec 08, 2010 12:09 pm |
|
|
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
|
|
Posted: Thu Dec 09, 2010 1:16 am |
|
|
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
|
|
Posted: Thu Dec 09, 2010 1:31 am |
|
|
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
|
|
Posted: Thu Dec 09, 2010 6:21 am |
|
|
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
|
|
Posted: Thu Dec 09, 2010 6:44 am |
|
|
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
|
|
Posted: Sat Jul 02, 2011 10:19 am |
|
|
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 ... |
|
|
|
|
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
|