Topic 7 : I2C Interface
Problem 1 : Design two embedded systems using ATMEGA32 (working at 8Mhz) communicate together by I2C serial interface. One system
work as the Master I2C Transmitter, One system work as the I2C Slave Receiver. The Master I2C Microcontoller has 8 buttons, The Slave I2C
Microcontoller has LEDs. Wrrite the C program to control the two system, When button0 is pressed the Master system will send character ‘0’ to
slave system, When button1 is pressed the Master system will send character ‘1’ to slave system . When the slave system receiving new
character from the I2C interface the system will toggle the relevant LED ( for example when the character received is ‘0’ LED0 will be toggled,
when the character received is ‘1’ LED1 will be toggled).
Transmit
#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
void Clock_Set(){
TWSR = 0; // No prescaler
TWBR = 72; // SCL frequency is 50K for XTAL = 8M
void Start(void){
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTA); // Clear TWINT Flag
while ((TWCR & 0x80) == 0); // wait for TWINT Flag to become 1
void Write(unsigned char aByte){
TWDR = aByte;
TWCR = (1<<TWINT)|(1<<TWEN);
while ((TWCR & 0x80) == 0);
}
unsigned char Read(unsigned char ack){
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);
while ((TWCR & 0x80) == 0); return TWDR;
void Stop(){ TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); }
int main (void){
DDRD = 0x00; // PORTA is Output Port
PORTD=0xFF; //Pull up resistors
Clock_Set();
while(1)
if((PIND & 1<<0)==0) //If BT0 is pressed
Start(); // transmit START condition
Write(0b11010000+0); // transmit SLA + W(0)
Write(0); // transmit data
Stop(); // transmit STOP condition
//-----------
if((PIND & 1<<1)==0) //If BT1 is pressed
Start(); // transmit START condition
Write(0b11010000+0); // transmit SLA + W(0)
Write(1); // transmit data
Stop(); // transmit STOP condition
//--------------
if((PIND & 1<<2)==0) //If BT3 is pressed
{
;
Start(); // transmit START condition
Write(0b11010000+0); // transmit SLA + W(0)
Write(2); // transmit data
Stop(); // transmit STOP condition
if((PIND & 1<<3)==0) //If BT4 is pressed
Start(); // transmit START condition
Write(0b11010000+0); // transmit SLA + W(0)
Write(3); // transmit data
Stop(); // transmit STOP condition
if((PIND & 1<<4)==0) //If BT5 is pressed
Start(); // transmit START condition
Write(0b11010000+0); // transmit SLA + W(0)
Write(4); // transmit data
Stop(); // transmit STOP condition
if((PIND & 1<<5)==0) //If BT6 is pressed
Start(); // transmit START condition
Write(0b11010000+0); // transmit SLA + W(0)
Write(5); // transmit data
Stop(); // transmit STOP condition
}
if((PIND & 1<<6)==0) //If BT7 is pressed
Start(); // transmit START condition
Write(0b11010000+0); // transmit SLA + W(0)
Write(6); // transmit data
Stop(); // transmit STOP condition
if((PIND & 1<<7)==0) //If BT8 is pressed
Start(); // transmit START condition
Write(0b11010000+0); // transmit SLA + W(0)
Write(7); // transmit data
Stop(); // transmit STOP condition
return 0 ; }
Receive
#include <avr/io.h>
#include <avr/delay.h>
void Address_Set(unsigned char address){
TWAR = address;
void Listen(unsigned char ack){
TWCR = (1<<TWINT)|(1<<TWEN)|(ack<<TWEA);
while ((TWCR & 0x80) == 0);
}
unsigned char Read(unsigned char ack){
TWCR = (1<<TWINT)|(1<<TWEN)|(ack<<TWEA);
while ((TWCR & 0x80) == 0);
return TWDR;
void Write(unsigned char aByte){
TWDR = aByte;
TWCR = (1<<TWINT)|(1<<TWEN);
while ((TWCR & 0x80) == 0);
int main (){
DDRD = 0xFF; // PORTA is output
Address_Set(0b11010000); // enable slave at address
// 01101000 and do not accept general call
while(1){
Listen(1); // send ACK when master connects
PORTD = 1<<Read(1); // receive byte and send ACK
return 0 ;
Problem 2 : Convert the C Program of Master I2C Microcontroller into AVR Assembly code.
Dài quá không làm ạ