Note: I am beginner :) MCU: Atemega328p
In Method 1, I am using a UDRn data register empty interrupt once the transmit buffer is empty and inputting characters from snum
into the UDR0 register within the ISR. I want the serial monitor to print "65534" repeatedly. However it shows this:
Method 1 Code:
#define F_CPU 16000000UL
#define BAUD 9600
#define BRC ((F_CPU/16/BAUD)-1)
char snum[20];
int num = 65534;
int i;
sei();
int main (void)
{
uarttransmitenable();
while (1)
{
utoa(num, snum, 10);
}
}
ISR(USART_UDRE_vect)
{
for (i=0; i< strlen(snum); i++)
{
UDR0 = (char)snum[i];
}
}
void uarttransmitenable(void)
{
UBRR0H = (BRC >> 8);
UBRR0L = BRC;
UCSR0B = (1<<TXEN0)| (1<<RXEN0) | (1<<UDRE0);
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
}
My thinking was that the while loop would covert the 65534 into an array of characters and then every time the interrupt occurred the next char in snum would be sent, and would be sent in order, so 6 first, followed by 5,5,3,4.
In Method 2 I do the int to char conversion and poll the UDREn bit to see if the transmit buffer is ready within the while loop. I don't use ISR at all. This shows "65534" fine on the serial monitor.
Method 2:
#define F_CPU 16000000UL
#define BAUD 9600
#define BRC ((F_CPU/16/BAUD)-1)
char snum[20];
int num = 65534;
int i;
int main (void)
{
uarttransmitenable();
while (1)
{
utoa(num, snum, 10);
for (i=0; i< strlen(snum); i++)
{
while (( UCSR0A & (1<<UDRE0)) == 0){}
UDR0 = (char)snum[i];
}
}
void uarttransmitenable(void){
UBRR0H = (BRC >> 8);
UBRR0L = BRC;
UCSR0B = (1<<TXEN0)| (1<<RXEN0);
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
}
I wanted to use the UDRE interrupt as I thought it would result in better performance, but the figures have come out differently.
I understand that using FIFO buffers would be a good idea for this task in general but I just wanted to understand why method 1 does not work.