Home > Atmel AVR > USART (Serial) on AVR (Interrupt Driven)

USART (Serial) on AVR (Interrupt Driven)

Tutorial on using the USART with Interrupts
By 09/11/10 [Last Edited by Joseph 10/01/11]
BOOKMARK
LOGIN
REGISTER
We can take the previous tutorial a slight step forward and use interrupts. This method of using the USART has a huge advantage, we no longer have to keep calling rxbyte() to check for incoming data. Instead, when data is received, the processor gets interrupted, and the 'Interrupt Service Routine' or macro subroutine is run. This means we can do something entirely different in our main code, and not have to worry if the USART is being checked or not. Code:

// Include library files 
#include <avr/io.h> 
#define F_CPU 8000000UL //Define crystal/RC osc frequency 
#include <avr/interrupt.h> 

// Prototypes 
void init_usart(unsigned int baud); 
void txbyte(unsigned char data); 
unsigned char rxbyte(void); 

// Let's go 

int main(void) 
{ 
   init_usart(51); //Init the USART (Serial) for 8Mhz clock at 9600 Baud 
   sei(); //Enable interrupts 
   while(1) //Loop forever 
   { 
      //Do some entirely different thing 
   } 
} 


void init_usart(unsigned int baud) 
{ 
   // Setup serial I/O for communication 
   UBRRH = (unsigned char)(baud>>8); 
   UBRRL = (unsigned char)baud;                            
   UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE); 
   UCSRC = (1 << URSEL) | (3 << UCSZ0); 
} 

SIGNAL (SIG_UART_RECV) 
{ 
   //The UDR register contains the data received. 
   //We can still use rxbyte, but only inside the macro to receive another byte of data 
       
   if (UDR > rxbyte()) //If the first byte is greater than the second byte received 
   { 
      txbyte(1); //Send a 1 back 
   } 
   else 
   { 
      txbyte(0); //Send a 0 back 
   }    
} 

void txbyte(unsigned char data) 
{ 
   while ( !( UCSRA & (1 << UDRE)) ); //Wait for empty slot to send data 
   UDR = data; //Send it 
} 

unsigned char rxbyte (void) 
{ 
   while ( !(UCSRA & (1 << RXC)) ); //Wait until there is a byte to be read from RX buffer 
   return UDR; //Get it 
}