2
\$\begingroup\$

I'm working on bit-banged I²C for the ATmega328PB. I've been seeing a lot of noise (ringing and cross-talk) on the lines but thought it was just my test probes, etc. However, when using the MCU's native I²C the noise disappears. Can anyone suggest why this is occurring and how I might fix it?

FWIW, my bit-banged I²C code is working fine but the noise is a bit worrisome. From the 'scope traces (taken ~300 µs apart) it looks like the native I²C is driving the lines harder but I don't see anything in the MCU registers to tweak that.

Clean (native I²C) Dirty (bit-banged I²C)
Clean Dirty
Clean close-up Dirty close-up

Edit: Per @Big6's suggestion I added a 220 Ω resistor between the MCU pin and the 4.7k Ω pull-up resistor on the clock line (doing the data line as well would involve more substantial rework). The signal's a lot cleaner now (see below; clock is cyan). I may switch the resistors to 2.2k or 3.3k Ω for the pull-ups and 470 Ω for the series ones which I suspect would further improve things.

Native I²C with inline resistor Bit-banged I²C with inline resistor
Native with a 220 Ω resistor on one line Bit-banged with a 220 Ω resistor on one line
\$\endgroup\$
10
  • 1
    \$\begingroup\$ are you set up open drain? \$\endgroup\$ Nov 2, 2021 at 23:16
  • 1
    \$\begingroup\$ What is the size of your pull up resistors? You can try a series termination resistor in line with your SCL and SDA lines, try, say, 1/10th of the pull up values, and see what happens to the ringing. Your fall time is fast enough to cause the ringing \$\endgroup\$
    – Big6
    Nov 2, 2021 at 23:23
  • 1
    \$\begingroup\$ Try, for example, 220 ohm as inline resistors (right at the output of the lines and before the pull ups) and measure at the junction between the inline resistors and the pullups \$\endgroup\$
    – Big6
    Nov 2, 2021 at 23:28
  • 1
    \$\begingroup\$ @Big6 I can do that for one of the lines but for the other one the rework will be a bit more involved. Just doing one of the lines though should suffice to see if that'd fix things. (In case it makes a difference the lines are ~25 mm long) \$\endgroup\$ Nov 2, 2021 at 23:34
  • 1
    \$\begingroup\$ Don't know about that particular microcontroller, but controllers that I have worked with have "flexible" I/O pins that let software selectively enable internal pull up resistors, pull down resistors, "high" drive current, "low" drive, etc. (I don't remember what else.) Is it possible that your program that "bit-bangs" the pin configures it differently from the way it is configured by your program that uses the peripheral? Consider that your IDE may be using different default configurations depending on whether your setup allocates the pin to the peripheral or enables it for GPIO. \$\endgroup\$ Nov 3, 2021 at 1:31

1 Answer 1

2
\$\begingroup\$

You can try a series termination resistor in line with your SCL and SDA lines, try, say, 1/10th of the pull up values, and see what happens to the ringing. Your fall time is fast enough to cause the ringing. The inline series resistors will slow down your fall times as a tradeoff to damping out the ringing but the fall time will most likely still remain within specs (<300ns).

Try, for example, 220 ohm as inline resistors (right at the output of the lines and before the pull ups) and measure at the junction between the inline resistors and the pullups.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.