Consider this embedded C function that reads a byte from an I2C device register. What value does data hold after calling read_i2c_register(0x50, 0x10) if the device returns 0xAB at register 0x10?
uint8_t read_i2c_register(uint8_t device_addr, uint8_t reg_addr) {
uint8_t data = 0;
i2c_start();
i2c_write(device_addr << 1); // Write mode
i2c_write(reg_addr);
i2c_start();
i2c_write((device_addr << 1) | 1); // Read mode
data = i2c_read_nack();
i2c_stop();
return data;
}
uint8_t data = read_i2c_register(0x50, 0x10);Remember that the function reads the byte from the device register after sending the register address.
The function sends the device address with write mode, then the register address, then restarts with read mode and reads the byte. The device returns 0xAB at register 0x10, so data is 0xAB.
This code snippet tries to read a byte from an I2C device but misses a critical step. Which step is missing?
i2c_start(); i2c_write(device_addr << 1); // Write mode // Missing step here i2c_start(); i2c_write((device_addr << 1) | 1); // Read mode uint8_t data = i2c_read_nack(); i2c_stop();
Think about how the device knows which register you want to read.
Before restarting in read mode, the master must write the register address to tell the device which register to read from. Without this, the device won't know what data to send.
This code snippet causes the I2C bus to hang during reading. Identify the cause.
i2c_start(); i2c_write(device_addr << 1); // Write mode i2c_write(reg_addr); i2c_start(); i2c_write((device_addr << 1) | 1); // Read mode uint8_t data = i2c_read_ack(); i2c_stop();
Think about how the master signals the end of reading bytes.
When reading the last byte from an I2C device, the master must send a NACK to signal no more data is needed. Using i2c_read_ack() sends an ACK, causing the device to wait for more data and hanging the bus.
Identify the option that fixes the syntax error in this code snippet.
uint8_t read_byte(uint8_t device_addr, uint8_t reg_addr) {
uint8_t data;
i2c_start();
i2c_write(device_addr << 1);
i2c_write(reg_addr);
i2c_start();
i2c_write((device_addr << 1) | 1);
data = i2c_read_nack();
i2c_stop();
return data;
}Look carefully at the line endings for missing punctuation.
The function call i2c_start() on line 3 is missing a semicolon, causing a syntax error. Adding the semicolon fixes it.
This function reads multiple bytes from an I2C device starting at a register. How many bytes does it read?
void read_i2c_bytes(uint8_t device_addr, uint8_t start_reg, uint8_t *buffer, uint8_t length) {
i2c_start();
i2c_write(device_addr << 1); // Write mode
i2c_write(start_reg);
i2c_start();
i2c_write((device_addr << 1) | 1); // Read mode
for (uint8_t i = 0; i < length; i++) {
if (i < length - 1) {
buffer[i] = i2c_read_ack();
} else {
buffer[i] = i2c_read_nack();
}
}
i2c_stop();
}
uint8_t data_buffer[5];
read_i2c_bytes(0x50, 0x20, data_buffer, 5);Check the loop and the length parameter passed.
The function reads length bytes, which is 5 in this call. It reads 4 bytes with ACK and the last byte with NACK, totaling 5 bytes.