dashiz 发表于 2018-11-14 14:10:55

新手疑虑: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还是有点糊涂。

wenyangzeng 发表于 2018-11-14 16:46:30

3.6864晶振非整倍数,配置HSE时PLL无法得到合适的系统时钟频率。况且楼主如果没有手动配置,系统自动使用HSI.


dashiz 发表于 2018-11-14 22:27:51

本帖最后由 dashiz 于 2018-11-14 22:40 编辑

wenyangzeng 发表于 2018-11-14 16:46
3.6864晶振非整倍数,配置HSE时PLL无法得到合适的系统时钟频率。况且楼主如果没有手动配置,系统自动使用HS ...
这个程序是前人写的,我作为新手拿过来学习的。所以又很多不懂的地方。
请问,你说的手动配置是怎么配置的?如果系统自动采用内部HSI的话,精确延时还能做到吗?这个程序需要精确截取脉冲的。

wenyangzeng 发表于 2018-11-15 09:43:10

本帖最后由 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);
}

shuihehe 发表于 2018-11-15 10:33:40

wenyangzeng 发表于 2018-11-15 09:43
上图就是手动配置为HSE,但是晶振要使用4M.

你先把参考手册看一遍吧
页: [1]
查看完整版本: 新手疑虑:STM32L151外接3.6864MHz晶振,主频怎么还是32M?