打印
[STM32F4]

Bug: UART BRR calculate error when oversampling by 8. And Poor algorithm

[复制链接]
1010|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
wowow|  楼主 | 2015-4-25 11:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
发在ST论坛上的,转一份过来。这个bug很早就有了,而且算法也写得太复杂了点。
This error lasts a long long time, and maybe still exists other version of stdperiph or Cube.
In STM32Cube_FW_F4_V1.5.0 the error is in this line of stm32f4xx_hal_uart.h:
#define UART_BRR_SAMPLING8(_PCLK_, _BAUD_)             ((UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) << 4)|(UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0x0F))
should be:
#define UART_BRR_SAMPLING8(_PCLK_, _BAUD_)             ((UART_DIVMANT_SAMPLING8((_PCLK_), (_BAUD_)) << 4)|(UART_DIVFRAQ_SAMPLING8((_PCLK_), (_BAUD_)) & 0x07))

Can I complain about the too complex algorithm?
When oversampling by 16, the divide rate is PCLK/(BAUD*16). We have 4 bit fraction in BRR register, then:
BRR = ((PCLK/(BAUD*16))<<4 = PCLK/BAUD. Isn't that simple?
In most case when PCLK/BAUD>100, you can ignore the truncation error.
Or you can use use the rounding to be more accurate: BRR = (PCLK+BAUD/2)/BAUD

Now we can replace UART_BRR_SAMPLING16 macro with:
#define UART_BRR_SAMPLING16(_PCLK_, _BAUD_)     (((_PCLK_)+(_BAUD_)/2)/_BAUD_)

When oversampling by 8, the divide rate is PCLK/(BAUD*8).
In manual: "When OVER8=1, the DIV_Fraction3 bit is not considered and must be kept cleared." means BRR register has 3 bit fraction, and 1 bit blank.
Then BBR=(PCLK/(BAUD*8))<<3 = PCLK/BAUD, same result except that one blank bit is inserted in bit3.
Following inline function can replace the UART_BRR_SAMPLING8 Macro:

__INLINE static uint16_t UART_BRR_SAMPLING8(uint32_t _PCLK_, uint32_t _BAUD_)
{
    uint16_t Div = (_PCLK_ + _BAUD_/2)/_BAUD_;    //result in 3 bit fraction, 15 bit Mantissa
    //When OVER8=1, the DIV_Fraction3 bit is not considered and must be kept cleared.
    uint16_t DIV_Mantissa = (Div & ~0x7)<<1;
    uint16_t DIV_Fraction = Div & 0x07   
    return (DIV_Mantissa | DIV_Fraction);
}

Variable DIV_Mantissa and DIV_Fraction are used for more clear.

my git commit:
https://github.com/skywolf/STM32 ... 0859f5a82087af4afeb
https://git.oschina.net/dingtu/S ... 0859f5a82087af4afeb
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

59

主题

649

帖子

3

粉丝