JumppingJack
Joined: 05 Jul 2006 Posts: 1
|
I2C Communication problem - master read from two slaves |
Posted: Wed Jul 05, 2006 2:37 pm |
|
|
Excuse me for my English. I want that a PIC 16f877 (master) reads bytes from two slaves 16f877. I use Proteus to simulate it. When the master reads from only slave, my routine works perfectly. When I use the routine below, the master reads the first byte from the first slave called. Next, the master only read 0xFF.
To block a specific slave, I use /* and */ and test my code.
For example:
Slave 1 Buffer´s: [0xC7 0x23 0x56 0xA9]
Slave 2 Buffer´s: [0x45 0x32 0xAF 0xDE]
If I block the Slave 2, the master continually reads from Slave 1:
0xC7, 0x23, 0x56, 0xA9, 0xC7, 0x23, 0x56, 0xA9,0xC7...
If I block the Slave 1, the master continually reads from Slave 2:
0x45, 0x32, 0xAF, 0xDE,0x45, 0x32, 0xAF, 0xDE,0x45...
But if I block none of them, the master read:
0xC7, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF...
Might anybody help me?
Code: |
//Master Code
#include <16f877>
#fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3,SLOW,FORCE_HW)
void main(void){
byte buffer1=0, buffer2=0, dado1,dado2;
while(TRUE){
i2c_start();
i2c_write(0xa0);
delay_ms(10);
i2c_write(buffer1);
delay_ms(10);
i2c_start();
i2c_write(0xa1);
delay_ms(10);
dado1=i2c_read(0);
i2c_stop();
printf("\n Escravo 1 buffer %i %u\r",buffer1,dado1);
if(++buffer1==10) buffer1=0;
delay_ms(2000);
/*
i2c_start();
i2c_write(0xb0);
delay_ms(10);
i2c_write(buffer2);
delay_ms(10);
i2c_start();
i2c_write(0xb1);
delay_ms(10);
dado2=i2c_read(0);
i2c_stop();
printf("\n Escravo 2 buffer %i %u\r",buffer2,dado2);
if(++buffer2==10) buffer2=0;
delay_ms(2000);
*/
}
}
// Slave address 0xA0
#include <16f877>
#fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#include <lcd>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0, slow)
typedef enum {NOTHING, CONTROL_READ,
ADDRESS_READ, READ_COMMAND_READ} I2C_STATE;
I2C_STATE fState;
BYTE address, buffer[0x10];
#INT_SSP
void ssp_interupt(){
BYTE incoming;
if (i2c_poll() == FALSE){
if (fState == ADDRESS_READ){ //i2c_poll() returns false on the
i2c_write (buffer[address]);//interupt receiving the second
fState = NOTHING; //command byte for random read operation
}
}
else{
incoming = i2c_read();
if (fState == NOTHING){
fState = CONTROL_READ;
}
else
if (fState == CONTROL_READ) {
address = incoming;
fState = ADDRESS_READ;
}
else
if (fState == ADDRESS_READ) {
buffer[address] = incoming;
fState = NOTHING;
}
}
}
void main ()
{
int i=0;
fState = NOTHING;
address = 0x00;
do{
buffer[i] = i;
i+=1;
}while (i<10);
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
while (TRUE) {
}
}
//Slave Address 0x0B
#include <16f877>
#fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP
#use delay(clock=4000000)
#include <lcd>
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xb0, slow)
typedef enum {NOTHING, CONTROL_READ,
ADDRESS_READ, READ_COMMAND_READ} I2C_STATE;
I2C_STATE fState;
BYTE address, buffer[0x10];
#INT_SSP
void ssp_interupt(){
BYTE incoming;
output_bit (pin_b0, true);
if (i2c_poll() == FALSE){
if (fState == ADDRESS_READ){ //i2c_poll() returns false on the
i2c_write (buffer[address]);//interupt receiving the second
fState = NOTHING; //command byte for random read operation
}
}
else{
incoming = i2c_read();
if (fState == NOTHING){
fState = CONTROL_READ;
}
else
if (fState == CONTROL_READ) {
address = incoming;
fState = ADDRESS_READ;
}
else
if (fState == ADDRESS_READ) {
buffer[address] = incoming;
fState = NOTHING;
}
}
}
void main ()
{
int i=0;
fState = NOTHING;
address = 0x00;
do{
buffer[i] = 2*i;
i+=1;
}while (i<10);
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
while (TRUE) {
}
} |
|
|