Diagnosing I2C Bus Communication Failures in Embedded C Systems
When an I²C master reports no ACK, the bus may be stuck, mis‑wired, or clocked too fast. This guide walks through the symptoms, common causes, step‑by‑step checks, fixes, and when to involve support.
20 Sept 2026, 01:28 UTC

Recognizable Condition
During a repeated start or a read operation the master’s status register shows NO_ACK and the bus remains idle. The SDA line stays low and no acknowledgment pulse is observed on the next clock edge.
Common Causes (Cause Table)
| Cause | Description |
|---|---|
| Missing or incorrect pull‑up resistors | Bus stuck at logic 0 due to absent or oversized pull‑ups. |
| Clock speed too high | Slave misses edges, data corruption occurs. |
| Wrong slave address or format | Master sends an address the slave never recognizes. |
| Slave powered down or non‑responsive | Device is in reset or voltage drop state. |
| Bus contention from another master or miswired peripheral | Other device drives the line. |
| Firmware misconfiguration | Incorrect register values or clock division. |
Ordered Checks
- Verify Power Supply
- Measure VCC on the I²C bus with a multimeter.
- Expected: 3.3 V or 5 V depending on the device spec.
- Risk: If the voltage is below the slave’s minimum, the device may not respond.
- Check Pull‑Up Resistors
- Confirm that both SDA and SCL have pull‑ups of the recommended value (typically 4.7 kΩ for 100 kHz, 10 kΩ for 400 kHz).
- Use a multimeter to verify that the lines rise to VCC when idle.
- Risk: Oversized pull‑ups (e.g., 100 kΩ) may not pull the line high fast enough for high‑speed modes.
- Capture Bus Waveform
- Attach a logic analyzer or oscilloscope to SDA and SCL.
- Look for the ACK pulse: a low on SDA for one clock cycle after the address byte.
- Expected: Clear start, address, ACK, data, ACK, stop.
- Validate Clock Speed
- Check the master’s I2C clock divider register.
- Example: On a STM32 HAL,
hi2c1.Init.ClockSpeed = 100000;for 100 kHz. - Risk: Setting >400 kHz on a 100 kHz slave will cause missed edges.
- Confirm Slave Address
- Ensure the master uses the correct 7‑bit or 10‑bit address format.
- Example:
uint16_t addr = 0x50; // 7‑bit address 0x50 - Verify with a datasheet or a known good I2C scanner program.
- Test with Minimal Firmware
- Flash a verified, minimal I2C read routine.
- If the minimal firmware works, the issue lies in the original code.
- Check for Bus Contention
- Disconnect all peripherals except the master and the target slave.
- Re‑run the test to see if the ACK appears.
Fixes Tied to Findings
- Power Issue: Add a voltage regulator or fix the power rail.
- Pull‑Up Problem: Replace or add resistors to the recommended value.
- Clock Speed Too High: Reduce
ClockSpeedor adjust the prescaler. - Address Mismatch: Correct the address constant in the master firmware.
- Non‑responsive Slave: Power‑cycle the device or check its reset pin.
- Firmware Corruption: Re‑flash with a clean build and verify register writes.
- Bus Contention: Isolate the offending peripheral or re‑configure its pins.
Concrete Example – Minimal I2C Read (STM32 HAL)
#include <stm32f4xx_hal.h>
I2C_HandleTypeDef hi2c1;
void SystemClock_Config(void);
static void MX_I2C1_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_I2C1_Init();
uint8_t data;
HAL_StatusTypeDef ret = HAL_I2C_Master_Receive(&hi2c1, 0x50 << 1, &data, 1, HAL_MAX_DELAY);
if(ret == HAL_OK)
{
// data received successfully
}
else
{
// handle error
}
while(1);
}
static void MX_I2C1_Init(void)
{
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000; // 100 kHz
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0x00;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0x00;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
HAL_I2C_Init(&hi2c1);
}
Verification Checklist
- Logic analyzer shows a proper ACK pulse.
- Master status register reports
HAL_OK. - Voltage on SDA/SCL is within spec during idle.
- No error flags in the I2C peripheral registers.
Escalation Criteria
If after completing all checks the bus still fails to acknowledge, consider:
- Replacing the slave device (hardware fault).
- Testing the master on a different board or with a different MCU.
- Consulting the device manufacturer’s support or errata sheet.
- Using a different I2C driver/library to rule out firmware bugs.
Limitations
This guide assumes a standard 7‑bit address I2C bus operating at 100 kHz or 400 kHz. High‑speed modes (>1 MHz) or multi‑master configurations may require additional checks such as bus arbitration analysis or clock stretching support.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.