10 years, 8 months ago.

PIC16 to I2C Communication Issues

Hi,

I'm having a few issues with communication between a PIC16F877A and an MBED.

I will post some code later, but in the meantime I have a few questions;

Pull-ups, will the value effect the operation? I currently have tried 10k and 4.7k. They are tied to a 4.5v line, so I wasn't sure if I should be using a 3.3v supply as the MBED generally uses 3.3v?

Also, addressing, I understand the 7bit/8bit addressing, my PIC starts an I2C and reports (via logic analyser) that it has sent the address and received an ACK from the MBED. However in the MBED code, the slave.recieve() returns 0, which is Not Addressed. I am currently using an address of 0x00 to keep it simple. I wasn't sure how the PIC was getting an ACK, unless the line is taking too long to return high?

Do I also need any capacitors to help stabilise any lines?

Thanks James

Here is a screen shot of the Logic Analyser results from the PIC with the MBED attached, for some reason the MBED fails to ACK.

/media/uploads/jamesjnr/screen_shot_2014-04-08_at_20.09.51.png

Here is the code for MBED I2C, I have kept it simple so that when the MBED is addressed it lights up an LED.

#include <mbed.h>
I2CSlave slave(p28,p27); //Configure I2C slave
DigitalOut red_led(LED1); //red led
Serial pc(USBTX,USBRX);

int main() {
   
   slave.address(0x7E);
       while (1) { 
       int i;     

            //test for I2C, and act accordingly
           i = slave.receive();
           //pc.printf("Slave value  :    %d \n\r" ,i);
           if (i == 3){ 
           //pc.printf("Slave addressed  :    %d \n\r" ,i);
               red_led=1;
        
           }
       }
}
posted by James R 08 Apr 2014

If you do it like this, your PIC will need to write to 0x3F on the PIC if it uses 7-bit addressing. If it uses 8-bit you will need 0x7E also. In the end there are only two options, try them both ;).

I see from the example code (https://mbed.org/users/mbed_official/code/mbed/docs/tip/classmbed_1_1I2CSlave.html) you should be able to use WriteGeneral when PIC sends 0x00. Easiest is to just receive, and enable an LED when it is not equal to nodata.

posted by Erik - 08 Apr 2014

Hey, thanks for pointing out the 4th option on the receive command. So now I have it sending back the ACK and setting the LED on. Now I need to get the PIC to send a value over and the MBED read it. I'll let you know how I get on. P.s I couldn't get the addresses to work, so I'm using 0x00 and checking for i !=0.

posted by James R 08 Apr 2014

1 Answer

10 years, 8 months ago.

Pull-up is needed or mbed libs will hang on I2C communication. Value of 4K7 to 3V3 should work but depends a bit on the wire load. I do not recommend pull-up to 5V. When you have to communicate with a 5V device you should use a level converter like this. Dont use any capacitors on the I2C lines. That will only make things worse. The mbed slave libs are not that mature and seem to have some strange behaviour. The analyser will confirm when the message is ACKed: the SDA should be pulled low by the slave on the 9th clockpulse.

He has an LPC1768, personally I wouldn't bother with level shifters: The LPC1768 is 5V tolerant so no reason not to use pull-ups to 5V. And otherwise most 5V devices accept 3.3V as logic high, so pull-ups to 3.3V will then do.

@James, 0x00 is not a valid I2C address, it is the general call address. So better use another one.

posted by Erik - 08 Apr 2014

Thanks.

With the addressing can I not use general address with the PIC and MBED?

If not is there some difference between the addressing, should the values I assign be different. The PIC uses 7 bit's with R/W. If I say program the PIC with 0xFE it sends 7 bits of 1, plus the 0 for the write. In the MBED code should this then be 0xFE as well, I notice the MBED uses 8 bits and ignores LSB. So should it be 0xFE or 0x7F?

posted by James R 08 Apr 2014