|
|
View previous topic :: View next topic |
Author |
Message |
LEVENT
Joined: 04 May 2006 Posts: 16
|
i2c master&slave problem |
Posted: Fri Apr 04, 2008 10:39 am |
|
|
hi everbody.
I want to communicate 2 PIC with each other as one of them is master and the other one ise slave.I have written simple code to send data array from master to slave PIC and I send data from slave to master PIC..Everything is ok..
But when I tried this condition,slave PIC does not responded : I read data array from slave by master PIC.And after that I send i2c_stop and i2c_start() from master PIC to slave to write data array to slave PIC.But when I observe the registers (in the slave PIC) , I saw that i2c_state is also 0x84 ( in slave ) so I think that slave PIC try to write data to master PIC when still master PIC try to write data to slave PIC at the same time.Have anybody had and solved this problem? How can solve this problem?This order very important for me because of my project.My order :
1- data send to Master PIC form Slave PIC.
2- delay for some applications of Master PIC.
3- data( previous applications results ) send to Slave PIC from Master PIC.
Thanx... |
|
|
Matro Guest
|
|
Posted: Fri Apr 04, 2008 10:45 am |
|
|
Sorry but the explanation of your problem is very hard to understand.
Since you didn't post your code it will be difficult to help you.
If the basic commands "write to slave" and "read from slave" works fine, so you just have to perform it in the correct order.
You can post significant parts of your code to further help.
Matro. |
|
|
LEVENT
Joined: 04 May 2006 Posts: 16
|
|
Posted: Fri Apr 04, 2008 11:35 am |
|
|
this codes work fine :
************************************
Master PIC side :
************************************
#include <16F877.h>
// fuses
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS
#FUSES NOPROTECT //Code not protected from reading
#use delay(clock=20000000)
#use I2C(master, sda=PIN_C4, scl=PIN_C3, address=0xa0, FORCE_HW)
void main()
{
int8 ack1, ack2, ack3;
int i = 0, buf[60], recbuf[60];
i2c_start();
i2c_write(0xc0); // send slave address
for(i=0; i<60; i++)
{
i2c_write(buf[i]);
}
delay_ms(1); i2c_start();
i2c_write(0xc1);
for(i=0; i<60; i++)
{
recbuf[i] = i2c_read();
}
i2c_stop();
}
**************************************
And Slave PIC side :
**************************************
#include <16F877.h>
// fuses
#FUSES NOWDT
#FUSES HS
#FUSES NOPROTECT
#use delay(clock=20000000)
#use I2C(slave, sda=PIN_C4, scl=PIN_C3, address=0xc0, FORCE_HW)
int i = 0, j = 0, recbuf[60];
#INT_SSP
void i2c_isr()
{
i2c_state = i2c_isr_state();
if( i2c_state < 0x80 )
{
recbuf[i] = i2c_read();
i++;
}
if ( i2c_state >= 0x80 )
{
i2c_write( recbuf[j] );
j++;
}
}
void main()
{
enable_interrupts(global);
enable_interrupts(int_ssp);
for(;;);
}
But when I changed order of send-receive like this, not work :
************************************
Master PIC side :
************************************
#include <16F877.h>
// fuses
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS
#FUSES NOPROTECT //Code not protected from reading
#use delay(clock=20000000)
#use I2C(master, sda=PIN_C4, scl=PIN_C3, address=0xa0, FORCE_HW)
void main()
{
int8 ack1, ack2, ack3;
int i = 0, buf[60], recbuf[60];
i2c_start();
i2c_write(0xc1);
for(i=0; i<60; i++)
{
recbuf[i] = i2c_read();
}
i2c_stop();
delay_ms(1);
i2c_start();
ack1 = i2c_write(0xc0); // send slave address
for(i=0; i<60; i++) {
i2c_write(buf[i]);
}
delay_ms(1);
}
**************************************
And Slave PIC side :
**************************************
#include <16F877.h>
// fuses
#FUSES NOWDT
#FUSES HS
#FUSES NOPROTECT
#use delay(clock=20000000)
#use I2C(slave, sda=PIN_C4, scl=PIN_C3, address=0xc0, FORCE_HW)
int i, j, recbuf[60];
#INT_SSP
void i2c_isr()
{
i2c_state = i2c_isr_state();
if( i2c_state < 0x80 )
{
recbuf[i] = i2c_read();
i++;
}
if ( i2c_state >= 0x80 )
{
i2c_write( recbuf[j] );
j++;
}
}
void main()
{
enable_interrupts(global);
enable_interrupts(int_ssp);
for(;;);
}
May be I wrote some missing or wrong codes there but I tried to write the codes to expain the work order of two PIC that I didn't explain fine at my previous mesage.
thanx |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Apr 04, 2008 11:44 am |
|
|
I didn't look at your code in detail (please use the Code button in the
future, and Preview your post to see that it's in a Code Block).
But I saw two things:
1. Add the NOLVP fuse to all your programs, or you risk a lock-up.
Do this in all programs.
2. In your Master code, the last i2c_read() operation in a sequence
of reads, must do a "NACK" ("not acknowledge"). This is part of
the i2c specification. In CCS, this is done by using a 0x00 parameter.
Example:
|
|
|
Guest
|
|
Posted: Sat Apr 05, 2008 4:16 am |
|
|
PCM programmer wrote: |
...
2. In your Master code, the last i2c_read() operation in a sequence
of reads, must do a "NACK" ("not acknowledge"). This is part of
the i2c specification. In CCS, this is done by using a 0x00 parameter.
Example:
|
And this is a big source of i2c bugs since if the slave doesn't recieve a NACK but a ACK it will stretch the clock and the communication will be locked.
Very good an analysis of the code!
Matro. |
|
|
WASSIM
Joined: 01 Apr 2008 Posts: 5
|
|
|
|
|
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
|