MX.4.8.0 FM.F1.V1.0.0 MCU型号STM32F105VCT6 1、昨天调试串口,发现波特率不对,各种查找原因,具体过程就不赘言了。。。。。。 2、最后发现问题出在CubeMX生成的驱动代码有问题,系统时钟配置为72M,但计算波特率的时候却是按36M计算的。 3、问题代码如下: stm32f1xx_hal_rcc_ex.c中 uint32_t HAL_RCC_GetSysClockFreq(void) { const uint8_t aPLLMULFactorTable[12] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 13}; const uint8_t aPredivFactorTable[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16}; uint32_t tmp_reg = 0, prediv1 = 0, pllclk = 0, pllmul = 0; uint32_t sysclockfreq = 0; uint32_t prediv2 = 0, pll2mul = 0; tmp_reg = RCC->CFGR; /* Get SYSCLK source -------------------------------------------------------*/ switch (tmp_reg & RCC_CFGR_SWS) { case RCC_CFGR_SWS_HSE: /* HSE used as system clock */ { sysclockfreq = HSE_VALUE; break; } case RCC_CFGR_SWS_PLL: /* PLL used as system clock */ { pllmul = aPLLMULFactorTable[(uint32_t)(tmp_reg & RCC_CFGR_PLLMULL) >> POSITION_VAL(RCC_CFGR_PLLMULL)]; if ((tmp_reg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2) { prediv1 = aPredivFactorTable[(uint32_t)(RCC->CFGR2 & RCC_CFGR2_PREDIV1) >> POSITION_VAL(RCC_CFGR2_PREDIV1)]; if(HAL_IS_BIT_SET(RCC->CFGR2, RCC_CFGR2_PREDIV1SRC)) { /* PLL2 selected as Prediv1 source */ /* PLLCLK = PLL2CLK / PREDIV1 * PLLMUL with PLL2CLK = HSE/PREDIV2 * PLL2MUL */ prediv2 = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> POSITION_VAL(RCC_CFGR2_PREDIV2)) + 1; pll2mul = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> POSITION_VAL(RCC_CFGR2_PLL2MUL)) + 2; pllclk = (uint32_t)((((HSE_VALUE / prediv2) * pll2mul) / prediv1) * pllmul); } else { /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */ pllclk = (uint32_t)((HSE_VALUE / prediv1) * pllmul); } /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */ /* In this case need to divide pllclk by 2 */ if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> POSITION_VAL(RCC_CFGR_PLLMULL)]) //问题代码 { pllclk = pllclk / 2; } } else { /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */ pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul); } sysclockfreq = pllclk; break; } case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */ default: /* HSI used as system clock */ { sysclockfreq = HSI_VALUE; break; } } return sysclockfreq; } 4、 if (pllmul == aPredivFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> POSITION_VAL(RCC_CFGR_PLLMULL)]) //这是正确代码 5、刚发现 MX.4.9.0 FM.F1.V1.1.0 不知道这个问题解决了没有 |
#define RCC_CFGR_PLLMULL6_5 ((uint32_t)0x00340000) /*!< PLL input clock * 6.5 */错误的
#define RCC_CFGR_PLLMULL6_5 ((uint32_t)0x002C0000) /*!< PLL input clock * 6.5 */正确的
今天也遇到这个问题了,72M时钟按36M计算导致串口波特率设置出错。其实问题在于aPLLMULFactorTable的表定义问题。
原始的表为const uint8_t aPLLMULFactorTable[12] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 13};
但PLLMUL6.5的值为1101,应该对应表的aPLLMULFactorTable[13] 元素,但原始表少了2个元素,导致比较的时候溢出出错。这应该是开发人员的疏忽,spec上的从pllmul9到pllmul6.5之间应该有5个保留位,而不是3个,见下图
PLL multiplication fator
所以表应该定义为
const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 13};