I was reading documentation on UART on AVR and it looks simple: when a flag (bit RXC0 of register UCSR0A) is set to 1, it means the micro controller has new data for you, and you read this from register UDR0.

But something boggles my mind: How does the micro controller know that we have read the data? Or, in other words, after it received the first byte on UART, the flag is set to 1, but when is it set back to 0?

  • can someone explain the -1 ? – Thomas Jan 3 '16 at 11:08
  • I'm not sure I understand it either. He indicates that he's been reading the documentation and is puzzled by it. The learning curve here gets steep very fast in places. – dlu Jan 3 '16 at 16:04
  • 1
    What you read is not the documentation, it is a simplified tutorial. Maybe take a look at the datasheet... I would imagine that the UDR0 register is hardwired, so that when it is read (and the "READ" line goes active) then the "latch" on the RXC0 flag is cleared (by the same "READ" line going active). Have a look at some UART design documents, and/or "State Machines". – Greenonline Jan 3 '16 at 16:33

The ATmega328p data-sheet describes the setting of RXCn:

Bit 7 – RXCn: USART Receive Complete

This flag bit is set when there are unread data in the receive buffer and cleared when the receive buffer is empty (i.e., does not contain any unread data). If the Receiver is disabled, the receive buffer will be flushed and consequently the RXCn bit will become zero. The RXCn Flag can be used to generate a Receive Complete interrupt (see description of the RXCIEn bit).

The hardware seems to keep a register the size of the receive buffer. Incremented when received and decremented when read. It is only one level so the size is 0..1, i.e. one bit.

Actually there is two registers; one for possible incoming data and one for the latest data until read.


More details in ATmega328p data-sheet, chap. 19 USART0

  • So the micro controller actually tracks all myvariable = UDR0 or f(UDR0) ?! this doesn't seem uncanny ? – Thomas Jan 3 '16 at 12:36
  • 1
    It is the implementation of reading UDR0 that is "special". There is no special instruction or tracking by the compiler. The hardware does this. Think of it as a hidden bit parallel with the data register. – Mikael Patel Jan 3 '16 at 12:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.