I am using ATmega32A and 24c16A EEPROM for testing an I2C code. For every state transition, controller responds by changing the status register TWSR
. After start condition is transmitted, EEPROM responds and then also for Device address and write instruction (SLA+R/W), status register updates fine. But when I transmit next 8 bits, instead of ACK (Data byte sent ACK), status changes to repeated start. The code is given below. I never could find the possible solution to make it work.
int main(void)
{
init();
twi_start();
twi_write_device_address();
twi_write_data(0x08); // Data-write Memory transmission
twi_write_data('U'); // Data transmission
twi_stop();
}
void twi_start(void)
{
// Clear TWI interrupt flag, Put start condition on SDA, Enable TWI
TWCR|= (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR & (1<<TWINT))); // Wait till start condition is transmitted
while((TWSR & 0xF8)!= 0x08); // Check for the acknowledgment (start transmitted)
}
void twi_write_device_address()
{
TWDR=0b10101110; // Device address and write instruction
TWCR|=(1<<TWINT)|(1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
while((TWSR & 0xF8)!= 0x18); // Check for the acknowledgment (SLA+W transmitted)
}
void twi_write_data(unsigned char data)
{
TWDR=data; // put data in TWDR
TWCR|=(1<<TWINT)|(1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
while((TWSR & 0xF8) != 0x28); // Check for the acknowledgment (Data written)
}
void twi_stop()
{
// Clear TWI interrupt flag, Put stop condition on SDA, Enable TWI
TWCR|= (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
while(!(TWCR & (1<<TWSTO))); // Wait till stop condition is transmitted
}
Instead of 0x28, 0x10 is updated in the status register while calling twi_write_data(data)
function.