新手疑虑:STM32L151外接3.6864MHz晶振,主频怎么还是32M?
手头有个前人留下的项目,是用STM32L151,外接3.6864MHz晶振,OSC32IN和OSC32out没接晶振。按我理解,时钟应该是3.6864*8/2=14.7456M,但是我看代码里还是基于8M来设置的。
Main.c里这么注释的:
RCC_GetClocksFreq(&RCC_Clocks); //获取系统时钟频率,外部晶振8.00M,倍频后系统时钟8.000*8/2=32.00M
对应的RCC_GetClocksFreq如下:
void RCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks)
{
uint32_t tmp = 0, pllmul = 0, plldiv = 0, pllsource = 0, presc = 0, msirange = 0;
/* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp)
{
case 0x00:/* MSI used as system clock */
msirange = (RCC->ICSCR & RCC_ICSCR_MSIRANGE ) >> 13;
RCC_Clocks->SYSCLK_Frequency = (((1 << msirange) * 64000) - (MSITable * 24000));
break;
case 0x04:/* HSI used as system clock */
RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
break;
case 0x08:/* HSE used as system clock */
RCC_Clocks->SYSCLK_Frequency = HSE_VALUE;
break;
case 0x0C:/* PLL used as system clock */
/* Get PLL clock source and multiplication factor ----------------------*/
pllmul = RCC->CFGR & RCC_CFGR_PLLMUL;
plldiv = RCC->CFGR & RCC_CFGR_PLLDIV;
pllmul = PLLMulTable[(pllmul >> 18)];
plldiv = (plldiv >> 22) + 1;
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
if (pllsource == 0x00)
{
/* HSI oscillator clock selected as PLL clock entry */
RCC_Clocks->SYSCLK_Frequency = (((HSI_VALUE) * pllmul) / plldiv);
}
else
{
/* HSE selected as PLL clock entry */
RCC_Clocks->SYSCLK_Frequency = (((HSE_VALUE) * pllmul) / plldiv);
}
break;
default:
RCC_Clocks->SYSCLK_Frequency = HSI_VALUE;
break;
}
在system_stm32lxx.c里,看到倍频分频设置值跟外接8M一样,几乎没改动。
/*PLL configuration: PLLCLK = (HSE * 8) / 2 = 32MHz */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMUL |
RCC_CFGR_PLLDIV));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMUL8 | RCC_CFGR_PLLDIV2);
难道是用了默认的内部8M频率?哪位恳请帮理一下。新手对RCC还是有点糊涂。
3.6864晶振非整倍数,配置HSE时PLL无法得到合适的系统时钟频率。况且楼主如果没有手动配置,系统自动使用HSI.
本帖最后由 dashiz 于 2018-11-14 22:40 编辑
wenyangzeng 发表于 2018-11-14 16:46
3.6864晶振非整倍数,配置HSE时PLL无法得到合适的系统时钟频率。况且楼主如果没有手动配置,系统自动使用HS ...
这个程序是前人写的,我作为新手拿过来学习的。所以又很多不懂的地方。
请问,你说的手动配置是怎么配置的?如果系统自动采用内部HSI的话,精确延时还能做到吗?这个程序需要精确截取脉冲的。
本帖最后由 wenyangzeng 于 2018-11-15 09:48 编辑
dashiz 发表于 2018-11-14 22:27
这个程序是前人写的,我作为新手拿过来学习的。所以又很多不懂的地方。
请问,你说的手动配置是怎么配置的 ...
上图就是手动配置为HSE,但是晶振要使用4M.
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
/**Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLL_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
_Error_Handler(__FILE__, __LINE__);
}
/**Configure the Systick interrupt time
*/
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
/**Configure the Systick
*/
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
/* SysTick_IRQn interrupt configuration */
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
wenyangzeng 发表于 2018-11-15 09:43
上图就是手动配置为HSE,但是晶振要使用4M.
你先把参考手册看一遍吧
页:
[1]