2018-01-15 04:39 AM
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[3] 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 valuesExample 1To obtain 9600 baud with fCK = 8 MHz. In case of oversampling by 16:USARTDIV = 8 000 000/9600BRR = USARTDIV = 833d = 0341h In case of oversampling by 8:USARTDIV = 2 * 8 000 000/9600USARTDIV = 1666,66 (1667d = 683h)BRR[3:0] = 3h << 1 = 1h
BRR = 0x681But 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?
2018-01-15 06:05 AM
The OVER8 mode description does seem inconsistant
3 << 1 != 1
The + (BAUD/2) highlighted is to address rounding.
For the OVER16, which is what I use most often
BRR = APBCLK / BAUD;
This generates a 12.4 fixed point representation, with the implicit DIV16
2018-05-04 07:08 AM
Hello
rwaghode
,There is No diffrence in the
formula
between thereference manual and the Cube.In fact, the Cube implementation was applied rounding, because the computation is made on integers and rounding of integers is always towards down, therefore was there added 0.5 for correct rounding.
Now the implementation in the new Cube is like this:
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 = *** / USARTDIV
+ 0.5
(0.5 is due to integer rounding)
In case of oversampling by 8, the equation is Tx/Rx baud = 2 *** × / USARTDIV
+ 0.5
(0.5 is due to integer rounding)
So, the Cube implementation is more precise, rounding around 0.5.
For more clarification, In the code, there is this implementation:
[ PCKL + (BAUD/2) ] / BAUD
Is the same as:
PCKL / BAUD + (BAUD/2) / BAUD = PCKL / BAUD + 1/2 which is after integer rounding as in the reference manual.
So, the reference manual is correct and aligned with the Cube, because formula calculates the value precisely.
In real implementation is up to programmer to choose correct rounding of calculated value (formula produces real number and then is necessary to choose correct conversion from real number to integer to load it into register).
Hope this clarify your question.
Best Regards,
Imen