Electronic – Using internal pull-ups for I2C on PIC18F


I'm working with a PIC18F46J53 and it was working quite well without any troubles. Suddenly, I found a hindrance on my path.

I used RB4 and RB5 pins as I2C bus pins for communicating with an EEPROM (24LC256). And I pulled up the bus lines using external 10k on both SDA and SCL.

Whenever I initialize TRISB pins RB4 and RB5 as inputs a solid 3.2v will appear across them as I2C bus. But recently a problem popped up on my board: one pin, SCL, shows ~3.2V whereas SDA shows 0.8V – I2C,then, didn't work anymore. I cross checked the I/O pin configuration and when I enabled the internal pull-ups on the PORTB the voltage on SDA rose up to 2.0v and I2C worked fine with EEPROM.

From the datasheet:

RBPU: PORTB Pull-up Enable bit

1 = All PORTB pull-ups are disabled
0 = PORTB pull-ups are enabled by individual port latch values

To fix the problem I trust both pins SDA and SCL must have 2.8-3.2 V on the bus when configured as input. But it seems to be working with 2.0V on the SDA pin and 2.9V on SCL.

I would like your inputs to this problem if you have countered any difficulties like this before.

Where should I search to fix the problem? It's working for now but I trust I would have missed something in any case. When and how should one use pull-ups? I have used both external and internal in this case to get I2C working. What is the best way to do so?

Best Answer

Don't use internal pull-ups for I2C. Use external resistors.
In other words, it's a design error when you attempt to use internal pull-ups for I2C (pretty much on any microcontroller).

The datasheet says that internal pull-up current is 50μA min and 400μA max. First, look at the huge variability of the pull-up current. Second, even 400μA is too weak for I2C. Even a 2.5kΩ resistor with Vcc=3.3V would generate a 1.3mA pull-up current.

Related threads:
What happens if I omit the pullup resistors on I2C lines? The O.P. was using internal pull-ups without knowing it. Illuminating oscilloscope plots in that thread.
Is there a correct resistance value for I2C pull-up resistors?