2015-04-22 06:18 PM
Test data: HSE_VALUE = 24000000, pllm=196, plln=14, pllp=2,
result: sysclockfreq=167,999,930,but the correct one is 168,000,000 reason: in expression pllvco = ((HSE_VALUE / pllm
) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN))); (HSE_VALUE / pllm) =1,714,285.71 round to 1,714,285 fix: pllvco = ((uint64_t)HSE_VALUE * plln / pllm) full code: uint32_t HAL_RCC_GetSysClockFreq(void) { uint32_t pllm = 0, plln=0, pllvco = 0, pllp = 0; uint32_t sysclockfreq = 0; /* Get SYSCLK source -------------------------------------------------------*/ switch (RCC->CFGR & RCC_CFGR_SWS) { case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */ { sysclockfreq = HSI_VALUE; break; } case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */ { sysclockfreq = HSE_VALUE; break; } case RCC_CFGR_SWS_PLL: /* PLL used as system clock source */ { /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN SYSCLK = PLL_VCO / PLLP */ pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; plln = (RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN); pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> POSITION_VAL(RCC_PLLCFGR_PLLP)) + 1 ) *2; if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI) { /* HSE used as PLL clock source */ pllvco = ((uint64_t)HSE_VALUE * plln / pllm); } else { /* HSI used as PLL clock source */ pllvco = ((uint64_t)HSI_VALUE * plln / pllm); } sysclockfreq = pllvco/pllp; break; } default: { sysclockfreq = HSI_VALUE; break; } } return sysclockfreq; }2015-04-22 09:50 PM