Electronic – PIC16F SSPADD Causing SCL To Go Low Early

ci2cpic

I am not able to communicate with my RTC (PCF8563). I am trying to communicate with it using a PIC16F876 over the I2C bus. The code below is all I am doing in my main(). I am unable to receive an ACK from the RTC. For some reason, when I set SSPADD it creates an additional START condition which is throwing off everything. I am positive it is the SSPADD , as a step through and removing it shows. Can anyone explain this? I have, by sending two START conditions, had it stop and recognize the correct address. In that situation SDA remains HIGH. If I set SSPADD before I enable SEN it will not send anything. Both pins are connected to +5V through a 2.2kohm resistor (also experimented with 10kohm).

TRISC = 0b00011000; //RC3-RC4 INPUTS
SSPM3 = 1; //set as I2C master
SSPM2 = 0;
SSPM1 = 0;
SSPM0 = 0;
SMP = 1; //disable slew rate control (running at 100khz)
SSPEN = 1; //enable serial port

SEN = 1; //create START condition
SSPADD = 0x09; //set baud rate to 100khz
SSPBUF = 0xA2; //buffer in number

Screenshot from logic analyzer: SCL on top, SDA on bottom:

enter image description here

Best Answer

From your code it looks like you are not waiting for SSPIF after setting the SEN. If I understand the data sheet correctly, you need to wait for SSPIF before attempting any 'next' operation, where START, ADDRESS, DATA and STOP are all operations. So it should be something like:

Start
wait for SSPIF and clear it
Send Addresss
wait for SSPIF and clear it
loop while more bytes:
  Send a byte
  wait for SSPIF and clear it
Stop

SSPIF was meant to be used from an interrupt handler, but you need a way to know that an operation is finished, so you might use it any way. If there is another signal that indicates the IIC operation is finished, you can use it as well.

Why I think your code 'almost' works is because setting SSPADD after SEN, gives the IIC engine time to complete START, so then sending the address works even though you did not wait for SSPIF. If you remove SSPADD (or move it), then two operations, START and ADDRESS are too close together, and the IIC engine ignores the ADDRESS command.