|
|
View previous topic :: View next topic |
Author |
Message |
zeeshan ahmed
Joined: 02 Dec 2010 Posts: 22
|
need help with i2c communication |
Posted: Thu Mar 31, 2011 4:16 am |
|
|
Greetings,
I'm working on i2c communication between 2 PIC (18f252), one is master other is slave. My problem is that when I send 2 or more data bytes from master, the slave pic receives only last byte sent by the master, and displays it over RS232.
I'm using 18f252 and running at 20MHz. CCS version is 4.093.
For master pic I'm using this code.
Code: |
i2c_start();
i2c_write(0xA0);
delay_ms(1);
i2c_write(0x00);
delay_ms(1);
i2c_write(9);
delay_ms(1);
i2c_write(8);
i2c_stop();
|
Slave code is
Code: |
#use i2c(SLAVE,slow, SDA=PIN_C4, SCL=PIN_C3, address=0xa0)
int i,data;
#INT_SSP NOCLEAR
void SSP_isr(void)
{
BYTE state, dummy;
output_toggle(pin_c1);
state = i2c_isr_state();
clear_interrupt(int_SSP);
if (state < 0x80) // Master is sending data
{ // First received byte is address
if(state == 1){
data= i2c_read();
printf("data is %d\r\n",data);
i=1;}
else dummy = i2c_read() ; //clear BF flag
}
else if (state == 0x80) // Master is requesting data
{
i2c_write('x');
}
}
void main ()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
i=0;
while (TRUE) {
}
}
|
I have tested my hardware and it is working OK, if I send single byte.
And plz tell, what would happen if I use [data= i2c_read(0)] in i2c slave code to acknowledge master PIC.
I checked the data and clock pin using oscillioscope and it seems that slave is not acknowledging the MASTER.
Please help.. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Thu Mar 31, 2011 5:24 am |
|
|
Several comments:
1) Get rid of the clock rate in the slave setup. Slaves do not have a 'speed'. Only the master has this setting, and having one in the slave could result in things being wrongly configured.
2) Get rid of the 'clear_interrupt' in the slave. You do not want this cleared till _after_ the byte has been read (it says 'there is a byte available'), and the compiler already handles this for you, automatically clearing the interrupt when you leave the routine. Get rid of the NOCLEAR on the interrupt handler.
3) Get rid of the printf in the slave. If you want to print, do it is the _main_ loop. Set a flag in the slave, and print when this is seen.
Problem here is _time_. Assuming the baud rate is 9600bps, each byte you send from a printf, takes just over 1mSec. You are printing up to 13 characters. 13+mSec. Data _will_ have been lost.
Repeat the mantra fifty times. Interrupt handlers should do _just_ what is needed by the interrupt, and do this as fast as possible. Anything else is likely to stop them working....
The '0' is needed when the master has to stop after the last byte. This reverses the sense of the 'ACK' to say 'last byte'.
Best Wishes |
|
|
|
|
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
|