0
0
Embedded Cprogramming~20 mins

I2C acknowledge and NACK behavior in Embedded C - Practice Problems & Coding Challenges

Choose your learning style9 modes available
Challenge - 5 Problems
πŸŽ–οΈ
I2C ACK/NACK Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
I2C Master Transmit: What happens after sending address?
Consider this embedded C code snippet for an I2C master transmitting a slave address. What is the expected behavior if the slave acknowledges (ACK) the address?

i2c_start();
i2c_send_address(0x50, I2C_WRITE);
if (i2c_check_ack()) {
    // Slave acknowledged
    i2c_send_data(0xA5);
} else {
    // Slave did not acknowledge
    i2c_stop();
}

What happens after i2c_send_address if the slave sends an ACK?
Embedded C
i2c_start();
i2c_send_address(0x50, I2C_WRITE);
if (i2c_check_ack()) {
    i2c_send_data(0xA5);
} else {
    i2c_stop();
}
AThe master immediately sends a stop condition without sending data.
BThe master sends the data byte 0xA5 to the slave.
CThe master waits indefinitely for a NACK from the slave.
DThe master resets the I2C bus due to error.
Attempts:
2 left
πŸ’‘ Hint
Remember, an ACK means the slave is ready to receive data.
❓ Predict Output
intermediate
2:00remaining
I2C Slave Receive: What does NACK indicate?
In an I2C slave device, after receiving a data byte from the master, the slave sends an ACK or NACK. What does it mean if the slave sends a NACK after a data byte?

Choose the correct interpretation.
AThe slave is signaling it cannot accept more data or an error occurred.
BThe slave is requesting the master to resend the last byte.
CThe slave is initiating a bus reset.
DThe slave is ready to receive more data bytes.
Attempts:
2 left
πŸ’‘ Hint
NACK usually means stop or error in communication.
πŸ”§ Debug
advanced
3:00remaining
Why does this I2C master code hang after sending data?
Examine this I2C master code snippet. The code hangs after sending the first data byte. Identify the cause.

i2c_start();
i2c_send_address(0x68, I2C_WRITE);
if (!i2c_check_ack()) {
    i2c_stop();
    return;
}
i2c_send_data(0x12);
while (!i2c_check_ack()) {
    // wait for ACK
}
i2c_send_data(0x34);
i2c_stop();
AThe master waits for an ACK after sending the first data byte, but the slave never sends it, causing an infinite loop.
BThe start condition is not sent properly, so the slave never responds.
CThe stop condition is sent too early, causing bus reset.
DThe address sent is incorrect, so the slave ignores data bytes.
Attempts:
2 left
πŸ’‘ Hint
Check the loop waiting for ACK after sending data.
🧠 Conceptual
advanced
2:30remaining
I2C NACK on last byte: What is the master’s role?
In an I2C read operation, the master reads multiple bytes from the slave. According to the I2C protocol, the master must send an ACK after each byte except the last one, after which it sends a NACK.

Why does the master send a NACK after the last byte?
ATo reset the I2C bus for the next communication.
BTo request the slave to resend the last byte.
CTo indicate the master wants to end the read operation.
DTo signal the slave to continue sending more data bytes.
Attempts:
2 left
πŸ’‘ Hint
Think about how the master tells the slave it is done reading.
❓ Predict Output
expert
3:00remaining
What is the output of this I2C slave ACK/NACK simulation code?
This embedded C code simulates an I2C slave device sending ACK or NACK based on received data. What is the output?

#include <stdio.h>

int i2c_slave_receive_byte(int byte) {
    if (byte == 0xFF) {
        // Invalid data, send NACK
        return 0; // NACK
    } else {
        // Valid data, send ACK
        return 1; // ACK
    }
}

int main() {
    int data[] = {0x10, 0x20, 0xFF, 0x30};
    for (int i = 0; i < 4; i++) {
        int ack = i2c_slave_receive_byte(data[i]);
        if (ack) {
            printf("ACK ");
        } else {
            printf("NACK ");
        }
    }
    return 0;
}
Embedded C
#include <stdio.h>

int i2c_slave_receive_byte(int byte) {
    if (byte == 0xFF) {
        return 0; // NACK
    } else {
        return 1; // ACK
    }
}

int main() {
    int data[] = {0x10, 0x20, 0xFF, 0x30};
    for (int i = 0; i < 4; i++) {
        int ack = i2c_slave_receive_byte(data[i]);
        if (ack) {
            printf("ACK ");
        } else {
            printf("NACK ");
        }
    }
    return 0;
}
AACK NACK ACK ACK
BNACK ACK ACK NACK
CNACK NACK NACK NACK
DACK ACK NACK ACK
Attempts:
2 left
πŸ’‘ Hint
Check which byte triggers NACK in the function.