View previous topic :: View next topic |
Author |
Message |
tom_hanks
Joined: 04 Apr 2007 Posts: 20
|
I2C Write- no ACK |
Posted: Wed Apr 18, 2007 2:38 am |
|
|
I am using two I2C in single PIC..one sw and following is hw one...
Write function is not genrating a ack signal...
can u suggest the possible reason, please
Code: |
void write_i2c(unsigned char trans_byte)
{
unsigned char write_collision = 1;
while (PIC_SSPSTAT & PIC_SSPSTAT_BIT_BF)
{output_high (PIN_A4);}
while (write_collision)
{
PIC_SSPCON = PIC_SSPCON & 0x7F;
PIC_SSPBUF = transmit_byte;
if (PIC_SSPCON & PIC_SSPCON_BIT_WCOL)
{
write_collision = 1;
}
else {write_collision = 0;}
}
PIC_SSPCON = PIC_SSPCON_BIT_CKP;
PIC_PIR1 = 0x47 & PIC_PIR1; //clear the interrupt flag
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Wed Apr 18, 2007 3:57 am |
|
|
First obvious comment. If a write collision occurs, this will hang. You have to clear WCOL yourself. As it stands, if this bit gets set, it'll stay permanently in the loop...
ACK, is enabled, by bit 4 of SSPCON2. The actual bit sent, is bit5 (so you can ACK, or NACK by changing this). It is the _receiving_ device in I2C, that generates the ACK/NACK. The'write' function, will not generate an ACK/NACK. It is the device at the other end, which needs to handle this
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
tom_hanks
Joined: 04 Apr 2007 Posts: 20
|
|
Posted: Wed Apr 18, 2007 7:54 am |
|
|
I am using P16F818, there is no SSPCON2 reg.
hence i am generating the ACK with the help of SSPIF,BF... |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Wed Apr 18, 2007 8:27 am |
|
|
The comment still applies, that the writing device doesn't generate ACK...
The 818, will automatically generate an ACK, when it is the receiving device, and the shift register data is transferred to the buffer, with an address match already flagged.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Wed Apr 18, 2007 8:39 am |
|
|
When communicating, via I2C, the Master is the one that generates the SCL(clock) pulses. The Master is the device that talks 'to' all of the other I2C devices on the bus, even if you just have one Slave. the Master will tell the Slave that it wants to write data to it or read data from it.
The Master can send out commands all day long but it has no idea if the Slave is receiving it's commands unless there is a 'handshaking' between the two devices. This is what the ACK or NOACK is for. The ACK is generated by the Slave device. This tells the Master that the Slave has received and understood what the Master is telling it. If there is a NOACK, or otherwise, no response from the Slave then the Master knows that the Slave did not receive it's command or is simply not listening.
The only time the Master will generate the ACK is when the Master is reading data from the Slave. This will tell the Slave that the data has reached the Master and it is okay to continue. When the Master sends a NOACK, after a read, this will tell the Slave that the Master is finished reading data and the reading is now finished.
Ronald |
|
![](templates/subSilver/images/spacer.gif) |
tom_hanks
Joined: 04 Apr 2007 Posts: 20
|
|
Posted: Mon Apr 23, 2007 8:49 am |
|
|
I mean the due the improper software, ACK is not being generated by Master.
Code: |
void write_i2c(unsigned char transmit_byte)
{
unsigned char write_collision = 1;
if(PIC_PIR1 & PIC_PIR1_BIT_SSPIF)
{
if(PIC_SSPSTAT & PIC_SSPSTAT_BIT_BF)
{ while (write_collision) {
PIC_SSPCON = PIC_SSPCON & 0x7F;
PIC_SSPBUF = transmit_byte;
if (PIC_SSPCON & PIC_SSPCON_BIT_WCOL)
{write_collision = 1;}
else {write_collision = 0;}
}
}
}
PIC_SSPCON = PIC_SSPCON_BIT_CKP; //| Release the clock.
PIC_PIR1 = 0x47 & PIC_PIR1; //clear the interrupt flag
} |
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Mon Apr 23, 2007 10:01 am |
|
|
rnielsen wrote: | When communicating, via I2C, the Master is the one that generates the SCL(clock) pulses. The Master is the device that talks 'to' all of the other I2C devices on the bus, even if you just have one Slave. the Master will tell the Slave that it wants to write data to it or read data from it.
The Master can send out commands all day long but it has no idea if the Slave is receiving it's commands unless there is a 'handshaking' between the two devices. This is what the ACK or NOACK is for. The ACK is generated by the Slave device. This tells the Master that the Slave has received and understood what the Master is telling it. If there is a NOACK, or otherwise, no response from the Slave then the Master knows that the Slave did not receive it's command or is simply not listening.
The only time the Master will generate the ACK is when the Master is reading data from the Slave. This will tell the Slave that the data has reached the Master and it is okay to continue. When the Master sends a NOACK, after a read, this will tell the Slave that the Master is finished reading data and the reading is now finished.
Ronald |
Exactly.
Simplify this though, it is always the _receiving_ device (whether master or slave), that develops the ACK/NACK. Hence the I2C_WRITE function shown (a data _transmission_), will never generate an ACK.
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
tom_hanks
Joined: 04 Apr 2007 Posts: 20
|
|
Posted: Thu May 03, 2007 2:53 am |
|
|
Hello Experts,
Finally I found out the that I have to do I2C bus recovery.
It happens when master fails a read operation in a slave...
solution:
reset the slave device or do a bus recovery sequence to leave the "slave transmitter mode"
till now i got this info, and looking for bus recovery method....
can u suggest any quick method for bus recovery by master |
|
![](templates/subSilver/images/spacer.gif) |
|