In our previous articles on serial data transmission using AVR microcontroller we have demonstrated serial communication using the polling method. In Polling, the microcontroller waits for the RXC flag (in the case of serial receiver) to go high and then moves to the next instruction. This is not a good programming technique to keep the microcontroller busy to monitor the RXC flag. Alternatively, serial interrupts can be used to transmit and receive data. This increases the efficiency of the code and keeps the processor free for other tasks. The article explains serial data reception using interrupts concepts.It is recommended that the readers should study the article on AVR Interrupts before proceeding.
The UCSRB register has RXCIE (Reception Complete Interrupt Enable) bit, which is used to enable the serial reception interrupt. The I-bit of SREG register is must be set to enable global interrupt of ATmega16. The circuit diagram is same as used in previous article of USART.
Step1: In order to use serial interrupts, the first step will be to initialize USART. In this case we need to add one more step to the initialization done in the polling method. The RXCIE (Receiver Complete Interrupt Enable) bit in UCSRB register is also set high to enable the serial receive interrupt. Every time one byte of the data is received serially, a serial receive interrupt is generated and the control transfers to the corresponding ISR. The RXC flag will go high to indicate the serial receive interrupt.
UCSRB |= (1<<RXCIE) | (1 << RXEN) | (1 << TXEN); // Turn on the transmission reception ..
// circuitry and receiver interrupt
UCSRC |= (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1); // Use 8-bit character sizes
UBRRL = BAUD_PRESCALE; // Load lower 8-bits of the baud rate value..
// into the low byte of the UBRR register
UBRRH = (BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value..
// into the high byte of the UBRR register
Step2: Now define its ISR
When the serial receive interrupt comes, the serial data is present in UDR (no need monitor RXC flag) and needs to be read in a variable. (In this program the data which is received is sent back serially. The controller is connected to PC and the data which is sent is received on the HyperTerminal).
unsigned char value;
value = UDR; // Fetch the received byte value into the variable “value”
UDR = value; //Put the value to UDR
For more detail: Serial communication with AVR microcontroller using interrupts