I am using STM32f030C8 controller. As per RM0360 ref. manual, baud rate calculation is as below (Section 23.4.4):
USART baud rate generation:
The baud rate for the receiver and transmitter (Rx and Tx) are both set to the same value as programmed in the USART_BRR register.
Equation 1: Baud rate for standard USART (SPI mode included) (OVER8 = 0 or 1)
In case of oversampling by 16, the equation is:
Tx/Rx baud = Fck / USARTDIV
In case of oversampling by 8, the equation is:
Tx/Rx baud = 2*Fck / USARTDIV
USARTDIV is an unsigned fixed point number that is coded on the USART_BRR register.
When OVER8 = 0, BRR = USARTDIV.
When OVER8 = 1
– BRR[2:0] = USARTDIV[3:0] shifted 1 bit to the right.
– BRR must be kept cleared.
– BRR[15:4] = USARTDIV[15:4]
Note:The baud counters are updated to the new value in the baud registers after a write operation to USART_BRR. Hence the baud rate register value should not be changed during communication.
In case of oversampling by 16 or 8, USARTDIV must be greater than or equal to 0d16.
How to derive USARTDIV from USART_BRR register values
To obtain 9600 baud with fCK = 8 MHz.
In case of oversampling by 16:
USARTDIV = 8 000 000/9600
BRR = USARTDIV = 833d = 0341h
In case of oversampling by 8:
USARTDIV = 2 * 8 000 000/9600
USARTDIV = 1666,66 (1667d = 683h)
BRR[3:0] = 3h << 1 = 1h
BRR = 0x681
But when I am checking the nucleo code, division calculation is as below:
for oversampling by 16:
#define UART_DIV_SAMPLING16(__PCLK__, __BAUD__) (((__PCLK__) + ((__BAUD__)/2U)) / (__BAUD__))
for oversampling by 8:
#define UART_DIV_SAMPLING8(__PCLK__, __BAUD__) ((((__PCLK__)*2U) + ((__BAUD__)/2U)) / (__BAUD__))
Question: Why there is difference in baud rate formula in ref. doc & nucleo code?
In case of oversampling by 8, for BRR [3:0] bits setting, section 23.7.4 tells to right shift by 1 where section 23.4.4, it is left shift by 1. What is correct?