Search code examples
cbit-manipulationuart

UART communication on Atmega32A with PC


I'm a begginer in programming AVR microcontroler and I get a lot of headacke sometimes from reading the datasheets. I'm trying to make a communication between my AVR and PC just to send some caracters and receive it on my computer. There are two lines I don't understand from the whole program and that is:

 void USART_init(void)
{
    UBRRH = (uint8_t)(BAUD_PRESCALLER>>8); <---- this one!
    UBRRL = (uint8_t)(BAUD_PRESCALLER); <--- and this one
    UCSRB = (1<<RXEN)|(1<<TXEN);
    UCSRC = (1<<UCSZ0)|(1<<UCSZ1)|(1<<URSEL);
}

Datasheet

Why do I have to shift BAUD_PRESCALLER with 8? If BAUD_PRESCALLER is a number and shifting that number with 8 doesn't mean the result will be zero?(Because we are shifting it too many times)

From the datasheet I understand that UBRRH contains the four most significant bits and the UBRRL contains the eight least signicant bits of the USART baut rate.(Note:UBBR is a 12-bit register)

So how actually we put all the required numbers in the UBBR register?


Solution

  • You have to shift it right 8 bits because the result of BAUD_PRESCALLER is larger than 8 bits. Shifting it right 8 bits gives you the most significant byte of a 16-bit value.

    For example, if the value of BAUD_PRESCALAR is 0x123 - then 0x1 would be assigned to UBRRH and 0x23 would be assigned to UBRRL.

    If the library was smart it could also perform sanity checking on the BAUD_PRESCALAR to make sure it fits in 16bits. If it can't, that means you cannot achieve the baud rate you want given the clock you are using. If you're UBRRx is truly 12bits, the sanity check would look something like this:

    #if BAUD_PRESCALAR > 0xFFF
    #error Invalid prescalar
    #endif