Calculate_UBRR

Purpose: UBRR is the generic term for all 2-byte USART Baud Rate Registers. In a 328P, there is only COM1 (UBRR0), while in a 328PB, there are both COM1 (UBRR0) and COM2 (UBRR1), and in a 2560, even COM3 (UBRR2) and COM4 (UBRR3.)
The UBRR value is a prescalar, or divisor, which sets the communication data rate for a serial (or USB) port. This subroutine simply calculates the UBRR value to use for a specific communication data rate, expressed in BPS (Bits Per Second.) It verifies that the BPS rate passed is valid (i.e., neither 0x0000 nor 0xFFFF) and if invalid, sets it to 960.
The bootup sequence reads the value of System Variable EEwCOM1_xBPS, which is the WORD located at EEPROM address 0x30. Multiply the value in EEwCOM1_xBPS by 10 to arrive at the actual BPS rate that will be set upon reboot. Setting EEwCOM1_xBPS to 960 will select a 9,600 BPS comm rate, for example. This subroutine neither reads nor changes that System Variable.
Assumes: The USART transmission speed doubling bit (U2X0 in UCSR0A) is SET (i.e., bit B00000010 in SRAM address 0xC0 is logic 1.) This can be verified using the command "DS 192 2", for example, and examining the value of the first byte after "00C0: ", remembering that all values are displayed in hexadecimal format.
Passed: R25:R24 WORD     the desired BPS value, divided by 10
Returns: R25:R24 WORD     value to write to UBRR0 (UBRR0L in R24, UBRR0H in R25)
Alters: R18 through R23, but not Registers UBRR0L or UBRR0H
Example: 
Set38400BPS:
   LDI     R25, (38400 / 10) >> 8  ; Select the desired comm rate of 38,400 BPS
   LDI     R24, (38400 / 10) & 0xFF
   CALL    ACalculate_UBRR         ; This subroutine recalculates the Baud Rate
   STS     UBRR0H, R25             ;  Register 0 (for COM1) values based on the
   STS     UBRR0L, R24             ;  on the value passed and sets it in the WORD
   CALL    ADumpRegs_Begin         ;  returned in R25:R24, displays the value
   RET                             ;  and exits
Notes: It is a good idea to test how a specific UBRR0 value corresponds to a give computer's serial data rate before changing the EEwCOM1_xBPS value. The Operating System initializes UBRR0 using the system variable on startup. Remember that the value in EEwCOM1_xBPS is 1/10th the desired value in order to allow the BPS to be stored in 2 bytes instead of using 4 bytes for a BPS greater than 65,535.
To test how a specific UBRR0 value corresponds to a computer data rate, the UBRR0 value might be set manually by writing to the WORD at SRAM address 0xC4. This could be done using "ESW 0xC4 = 16", for example, to set (approximately) 57,600 BPS. If it doesn't work as expected, just reboot the microcontroller to restore the default.
The AVR documentation for the 328PB, for example, uses BOTH UBRR and UBBR as the Register name , which is an easy mistake to make. Since the acronym means "USART Baud Rate Register", the correct one, UBRR, is used throughout this documentation.
Also see:  -