2015-04-24 07:52 PM
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/STM32Cube_FW_F4_BugFix/commit/ccdb3219c88559b7652d00859f5a82087af4afeb https://git.oschina.net/dingtu/STM32Cube_FW_F4_BugFix/commit/ccdb3219c88559b7652d00859f5a82087af4afeb