I was able to use USART without interrupt driven and it worked perfectly! However, when I tried adding interrupt on USART_RX_vect
, the program does not work as expected anymore.
Below is my small program. The expected behavior of this program is everytime I press a button the LED should toggle its state, but also by default the LED will toggle its state every 500ms. Right now, the LED toggles every 500ms but the moment I press a button on my machine keyboard to send data to the ATmega328p, the program stops (the led freezes on its last state).
I am not using an external clock, but I wonder if that could be the problem or I am missing something in my code that I can't figure out.
I appreciate any help. Thank you.
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#define FOSC F_CPU
#define BAUD 4800
#define MYUBRR FOSC/16/BAUD-1
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
void USART_Init(unsigned int ubrr) {
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
UCSR0B = (1<<RXEN0) | (1<<RXCIE0);
UCSR0C |= (1<<UCSZ00 | (1 << UCSZ01));
}
IRS(USART_RX_vect) {
PORTC ^= (1 << PC5);
}
int main(void) {
USART_Init(MYUBRR);
DDRC |= (1 << PC5);
sei();
while(1) {
PORTC ^= (1 << PC5);
_delay_ms(500);
}
return 0;
}
Edit#1: I modified IRS handler:
Code:
IRS(USART_RX_vect) {
while(!(UCSR0A&(1<<RXC0))){};
unsigned char received = UDR0;
PORTC ^= (1 << PC5);
}
Status: Program does not work.
Edit#2: Fixed typo ISR instead of IRS (pffff)
Solution: I was missing the code for consuming the RX buffer and I had a typo: IRS should be ISR. Thanks for @Edgar Bonet and @Majenko for the help!