You need to log in to create posts and topics.

ATmega328 UDR0 register always zero in MCU monitor

I have been experimenting with the UART in the ATmega328 chip with a very simple circuit where the chip simply writes a string over and over to the UART transmit buffer.

While monitoring via the MCU monitor in debugging mode I noticed that the value of the UDR0 register is never updated. I am not sure if this is by design or not. Perhaps this has to do with the fact that reading values from the UDRn returns contents of the Receive Data Buffer Register RXB whereas writing data to UDRn places contents into the Transmit Data Buffer Register TXB. At any rate I wanted to raise this because it feels like I should be able to see this register reflecting what was just written to it in the MCU monitor.

Attached are the SIM file and the program is below. Hopefully they will prove helpful.

#include <avr/io.h>
#include <util/delay.h>

#define F_CPU 16000000UL   // 16 MHz clock
#define BAUD 9600
#define MYUBRR F_CPU/16/BAUD-1

void uart_init(unsigned int ubrr) {
    UBRR0H = (unsigned char)(ubrr>>8);   // Set baud rate
    UBRR0L = (unsigned char)ubrr;
    UCSR0B = (1<<TXEN0);                 // Enable transmitter
    UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);    // 8 data bits, 1 stop bit
}

void uart_transmit(unsigned char data) {
    while (!(UCSR0A & (1<<UDRE0)));      // Wait for empty transmit buffer
    UDR0 = data;                         // Put data into buffer
}

void uart_print(const char* s) {
    while (*s) {
        uart_transmit(*s++);
    }
}

int main(void) {
    uart_init(MYUBRR);
    while (1) {
        uart_print("Hello, AVR!\r\n");
        _delay_ms(1000); // Wait 1 second
    }
    return 0;
}

Regards, Sam.

Uploaded files:

Yes, you are right, UDR0 is not a register but an I/O address connected to 2 physical registers.
When you read you get the content on the receiver, and the MCU Monitor is just reading registers.

Thank you, this makes sense. Then the answer is that things are functioning as intended. This appears to be an interesting case where the implementation is correct, but has less than desirable debugging features.