I am having a problem with programming the serial for Arduino in C. The application demands speed, so I need to do it in C. I am using Codeblocks for it as it is easy to compile.
As I also want the serial feature not blocking the application and giving debug capability, I am trying to write a circular buffer type of serial library. The application does not need to receive data, only print.
The problem begins with the serial interrupt apparently not firing and the program blocks, the compiler does give a warning:
main.c|11|warning: ‘UART_UDRE_vect’ appears to be a misspelled signal handler|
The test program is as follows:
#include<avr/io.h>
#include<avr/interrupt.h>
#define USART_BAUDRATE 9600
#define BAUD_PRESCALE (((F_CPU/(USART_BAUDRATE*16UL)))-1)
char ok = 0;
ISR(UART_UDRE_vect) {
ok = 1;
UCSR0B &= ~(1<<5);
}
int main(void) {
UBRR0H = (BAUD_PRESCALE >> 8);
UBRR0L = BAUD_PRESCALE;
UCSR0B |= (1<<TXEN0);
UCSR0C |= (1<<UCSZ00) | (1<<UCSZ01);
sei();
while(1){
// write the byte to the serial port
UDR0 = '0';
UCSR0B |= (1<<5);
while(ok != 1){}
ok = 0;
UDR0 = '\n';
UCSR0B |= (1<<5);
while(ok != 1){}
ok = 0;
}
return 0;
}
The configuration and baud rates are correct because the echo example found here does work.
Also other examples does not use UDRE, only RX interruption and that is not what I am looking for.
Am I forgetting something?
Two problems:
According to the documentation you linked, the interrupt vector for your particular part ATmega328p should be named USART_UDRE_vect
.
Variables shared with an interrupt must always be declared as volatile
or the compiler might not understand that they are used and therefore break your program upon optimization. Basically the compiler thinks that the variable ok
can never get another value than 0, since it doesn't see a function call to the ISR anywhere (since it is called by hardware, not by the program). Change the declaration to static volatile char ok;