I just failed to understand what the role TWINT plays in TWI communication. Firstly, I look up the datasheet of Atmega328p which describes TWINT as following.
This bit is set by hardware when the TWI has finished its current job and expects application
software response. If the I-bit in SREG and TWIE in TWCR are set, the MCU will jump to the
TWI Interrupt Vector. While the TWINT Flag is set, the SCL low period is stretched. The TWINT
Flag must be cleared by software by writing a logic one to it. Note that this flag is not automatically
cleared by hardware when executing the interrupt routine. Also note that clearing this flag
starts the operation of the TWI, so all accesses to the TWI Address Register (TWAR), TWI Status
Register (TWSR), and TWI Data Register (TWDR) must be complete before clearing this
When I read this on the first time, I thought that TWINT looks like an "indicator" that we should write 1 to TWINT to start TWI and waiting for it go 0 which shows TWI finished its job. But when I look at code about TWI on forum, I found they all look like (copied from this thread)
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN); // Send Start while (!(TWCR & (1<<TWINT))); // Wait for TWINT set to 1 /* ....... */ TWCR = (1<<TWINT) | (1<<TWEN); //start transmission
It seems that we are setting TWINT to 1 to trigger the TWI, but after that we still wait it to go high which confuses me quite a lot. So how does the microcontroller know when to start transmission by TWINT indeed? Thanks.