Initialization of MASTER means to set the TWI clock frequency (SCL). It is done by setting bit rate in TWBR and pre scaler bits in TWSR.
Fig. 2: Equation Of TWI Clock Frequency to initialize the Master in AVR
void TWI_init_master(void) // Function to initialize master
{
TWBR=0x01; // Bit rate
TWSR=(0<<TWPS1)|(0<<TWPS0); // Setting prescalar bits
// SCL freq= F_CPU/(16+2(TWBR).4^TWPS)
}
Step 2: Send start condition
The start condition in TWI is explained before. The AVR microcontroller has in built registers which makes this job much easier.
1. Clear TWINT flag by writing a logic one to it.
2. Set TWSTA bit to send start condition.
3. Set TWEN bit to initialize the TWI.
4. Monitor the status of TWINT flag.
5. Check the ACK byte (using while condition since the SCL frequency is very small as compared to micro controller clock frequency). The ACK byte can be compared by monitoring the status of TWSR.
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 acknowledgement
}
Step 3: Send the slave address, data direction bit (write) and wait for the ACK signal
1. Put the seven bit slave address and the direction control bit in TWDR.
2. Clear TWINT flag.
3. Enable TWI by writing logic one to TWEN bit.
4. Monitor the status of TWINT flag, the TWINT flag will get cleared when the data in TWDR is been transmitted.
5. Check for the correct acknowledgement.
void TWI_read_address(unsigned char data)
{
TWDR=data; // Address and read instruction
TWCR=(1<<TWINT)|(1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte received
while((TWSR & 0xF8)!= 0x40); // Check for the acknoledgement
}
Step 4: Send the 8-bit data and wait for the ACK
Fig. 4: Data transfer in TWI of AVR
1. Put the 8 bit data in TWDR.
8 bits = 7 bit slave address + Data direction bit (write = 0).
2. Clear TWINT flag.
3. Set TWEN bit to enable TWI.
4. Monitor the status of TWINT flag to get data transmission completed.
5. Check for the acknowledgement.
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 acknoledgement
}
Step 5: Send the STOP condition
Fig.5: TWI STOP Condition Bit
To send the stop condition use TWSTO
1. Clear TWINT flag.
2. Set TWEN bit
3. Write logic one to TWSTO bit so send STOP condition on SDA and SCL line.
4. Monitor the status of TWSTO bit, as TWSO bit get cleared means the stop condition has been transmitted.
void TWI_stop(void)
{
// 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
}
Up till here the data transmission from slave side is complete, the MASTER is working in mode one. As per the objective the data received by MASTER is displayed on PORTB. The flow chart for MASTER as a Transmitter (mode one) is given below.
Fig. 6: Flow Chart of MASTER as Transmitter in TWI Interfacing using AVR
From here the MASTER would be working in mode two i.e., MASTER becomes a receiver. The AVR TWI works in mode 2.
Step 6: Send the START condition on bus lines
This step is as similar to the previous one.
Note: In the Step 6 the START condition is sent after the STOP condition. If one more start condition is sent before the STOP condition in between then it is called as repetitive start condition. The repetitive start condition is same as the START condition but the only difference is between the acknowledgements. For more details about repetitive start refer to the data sheet. If the data is sent continuously in same direction then there would be no need of start condition, repetitive start or stop condition in between. The second data can be transmitted just after receiving the acknowledgement of first data byte (as shown in the above flow chart).
Step 7: Send the slave address and data direction bit (read) and wait for the ACK signal
1. Put the 8 bit data in TWDR.
8 bits = 7 bit slave address + Data direction bit (read = 1).
2. Clear TWINT flag.
3. Set TWEN bit to enable TWI.
4. Monitor the status of TWINT flag to get data transmission completed.
5. Check acknowledgement.
void TWI_read_address(unsigned char data)
{
TWDR=data; // Address and read instruction
TWCR=(1<<TWINT)|(1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte received
while((TWSR & 0xF8)!= 0x40); // Check for the acknoledgement
}
Step 8: Read the data from SDA bus
1. Clear TWINT flag
2. Set TWEN bit, enable TWI
3. Monitor the status of TWINT flag, as the TIWNT flag get set indicates the value in TWDR has been received.
4. Check for the acknowledgement. If the master wants to receive the last byte from slave, the status of TWSR register will be 0x58. After receiving the last byte either a repetitive start condition is issued by the master to continue the communication or a stop condition must be given by the master to stop the communication process. Else if the master wants to keep on receiving more byte from slave the status of TWSR register will be 0x50.
To acknowledge salve about last byte TWEA bit is used while transmitting the data. If TWEA bit is set, reception continuous from the MASTER side. And if TWEA bit is low, MASTER orders slave to send the last byte.
5. Get the received data. And send it on PORTB.
void TWI_read_data(void)
{
TWCR=(1<<TWINT)|(1<<TWEN); // Clear TWI interrupt flag,Enable TWI
while (!(TWCR & (1<<TWINT))); // Wait till complete TWDR byte transmitted
while((TWSR & 0xF8) != 0x58); // Check for the acknoledgement
recv_data=TWDR;
PORTB=recv_data;
}
Step 9: Send STOP condition
The stop condition is already explained.
Fig. 7: Flow Chart of MASTER as Receiver in TWI Interfacing using AVR
Code explanation for SLAVE controller:
Step 1: Initialization of the Slave controller
Initialization of the slave controller is done by assigning address to the slave. The seven bit slave address is filled in TWI slave Address Register (TWAR). The LSB of TWAR i.e., TWGCE bit is use to enable the slave to acknowledge for the general call address (0x00).
void TWI_init_slave(void) // Function to initilaize slave
{
TWAR=0x20; // Fill slave address to TWAR
}
Step 2: Check the status of TWSR register
If the value of TWSR is 0x60, it means the data sent by the master in the next step is meant to read by this particular slave only and the slave sends back the acknowledgement to the master corresponding to the read operation. If the TWSR status is 0x70 the SLAVE is requested to read the data at the general call (0x00). At this stage the SLAVE acts as receiver. The AVR TWI is working in mode 3.
1. Clear TWIN flag.
2. Enable TWI.
3. Set TEWA to receive acknowledgement.
4. Monitor the status of TWINT flag.
5. Match the status of TWSR. If the status is 0x60 read data or else jump to (1)
void TWI_match_read_slave(void) //Function to match the slave address and slave dirction bit(read)
{
while((TWSR & 0xF8)!= 0x60) // Loop till correct acknoledgement have been received
{
// Get acknowlegement, Enable TWI, Clear TWI interrupt flag
TWCR=(1<<TWEA)|(1<<TWEN)|(1<<TWINT);
while (!(TWCR & (1<<TWINT))); // Wait for TWINT flag
}
}
Step 3: Read data
Read the data sent by the MASTER.
1. Clear TWINT flag.
2. Enable TWI.
3. Set TWEA for receiving ACK.
4. Get the data form TWDR, display it on PORTB.
void TWI_read_slave(void)
{
// Clear TWI interrupt flag,Get acknowlegement, Enable TWI
TWCR= (1<<TWINT)|(1<<TWEA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))); // Wait for TWINT flag
while((TWSR & 0xF8)!=0x80); // Wait for acknowledgement
recv_data=TWDR; // Get value from TWDR
PORTB=recv_data; // send the receive value on PORTB
}
Fig. 8: Slave as Receiver in TWI Interfacing using AVR
From here the slave becomes a transmitter on the request of master to send data. The AVR TWI works in mode 4.
Step 4: Check the status of TWSR register
If the value of TWSR is 0xA8, it means the master wants to receive data from the particular slave and the slave sends back the acknowledgement to the master corresponding to the write operation.
1. Clear TWIN flag.
2. Enable TWI.
3. Set TEWA to receive acknowledgement.
4. Monitor the status of TWINT flag.
5. Match the status of TWSR. If the status is 0xA8 send data or else jump to (1)
void TWI_match_write_slave(void) //Function to match the slave address and slave dirction bit(write)
{
while((TWSR & 0xF8)!= 0xA8) // Loop till correct acknoledgement have been received
{
// Get acknowlegement, Enable TWI, Clear TWI interrupt flag
TWCR=(1<<TWEA)|(1<<TWEN)|(1<<TWINT);
while (!(TWCR & (1<<TWINT))); // Wait for TWINT flag
}
}
Step 5: Write the data on SDA bus
1. Put the data in TWDR.
2. Enable TWI.
3. Cleat the TWINT flag.
4. Monitor the TWINT flag. As it get cleared signifies the data has been send.
5. Check for the ACK. Since the TWEA bit was not set during writing data on SDA bus, it signifies master that this is the last data to be send and in turn it receives a NOT ACK and the status of TWSR is becomes 0xC0. And if the TWEA bit was set during the data transmission it receives an ACK and the status of TWSR is becomes 0xB8. For more details refer to the data sheet.
void TWI_write_slave(void) // Function to write data
{
TWDR= write_data; // Fill TWDR register whith the data to be sent
TWCR= (1<<TWEN)|(1<<TWINT); // Enable TWI, Clear TWI interrupt flag
while((TWSR & 0xF8) != 0xC0); // Wait for the acknowledgement
}
Fig. 9: Slave as Transmitter in TWI Interfacing using AVR
I am a highly skilled and motivated individual with a Master's degree in Computer Science. I have extensive experience in technical writing and a deep understanding of SEO practices.
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish.ACCEPTPrivacy Policy
Manage consent
Privacy Overview
This website uses cookies to improve your experience while you navigate through the website. Out of these, the cookies that are categorized as necessary are stored on your browser as they are essential for the working of basic functionalities of the website. We also use third-party cookies that help us analyze and understand how you use this website. These cookies will be stored in your browser only with your consent. You also have the option to opt-out of these cookies. But opting out of some of these cookies may affect your browsing experience.
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.