How to Handle I2C ACK and NACK in Embedded C Correctly
ACK and NACK by checking the I2C status register after each byte transfer. If an ACK is received, continue communication; if a NACK occurs, stop or retry the transfer to avoid errors.Why This Happens
When communicating over I2C, the master expects an ACK (acknowledge) from the slave after sending each byte. If the slave does not respond with ACK, it sends a NACK (not acknowledge). This usually means the slave did not receive the data or is not ready. If the code does not check for these signals, the master may continue sending data incorrectly, causing communication failure.
void i2c_write_byte(uint8_t data) { I2C_DATA_REG = data; // Send data while (!(I2C_STATUS_REG & TX_COMPLETE)); // Wait for transmission // Missing ACK check here } // Usage // i2c_write_byte(0x50); // No ACK check, may fail silently
The Fix
After sending a byte, check the I2C status register for the ACK bit. If NACK is detected, stop the transfer or retry. This ensures the master knows if the slave accepted the data and can handle errors gracefully.
bool i2c_write_byte(uint8_t data) {
I2C_DATA_REG = data; // Send data
while (!(I2C_STATUS_REG & TX_COMPLETE)); // Wait for transmission
if (I2C_STATUS_REG & NACK_RECEIVED) { // Check for NACK
i2c_stop(); // Stop communication
return false; // Indicate failure
}
return true; // ACK received, continue
}
// Usage
if (!i2c_write_byte(0x50)) {
// Handle error: retry or abort
}Prevention
Always check the I2C status register after each byte transfer to detect ACK or NACK. Use timeouts to avoid infinite waits. Implement retries or error handling when NACK occurs. Use clear function names and comments to make the code easy to maintain.
Enable I2C interrupts if supported to handle ACK/NACK asynchronously for better efficiency.
Related Errors
Common related errors include:
- Bus hang: Not releasing the bus after
NACKcauses the I2C bus to freeze. - Wrong slave address: Causes immediate
NACKon address phase. - Missing stop condition: Leads to incomplete transactions and bus errors.
Fixes involve checking status bits, sending stop conditions properly, and verifying slave addresses.