你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32时钟系统经验分享

[复制链接]
攻城狮Melo 发布时间:2023-11-4 19:02
1 STM32的时钟源主要有:
内部时钟
外部时钟
锁相环倍频输出时钟
微信图片_20231104190126.png


1.1 详细介绍

HSI(内部高速时钟)
它是RC振荡器,频率可以达到8MHZ,可作为系统时钟和PLL锁相环的输入

HSE(外部高速时钟)
接入晶振范围是4-16MHZ,可作为系统时钟和PLL锁相环的输入,还可以经过128分频之后输入给RTC。

LSI(内部低速时钟)
它是RC振荡器,频率大概为40KHZ,供给独立看门狗或者RTC,并且独立看门口只能依靠LSI作为时钟源

LSE(外部低速时钟)
通常外接32.768MHZ晶振提供给RTC

PLL(锁相环)
用来倍频输出。因为开发板外部晶振只有8MHZ,而STM32最大工作频率是72MHZ。他可以通过HSI输入,HSE输入或两分频输入,通过PLL倍频(2-16),倍频之后输入给系统时钟。

MCO(时钟输出管脚)
通常对应STM32 PA8,它可以选择一个时钟信号输出,给外部的系统提供时钟源

2 标准库的时钟配置
2.1 STM32启动文件

首先打开startup_stm32f10x_hd.s,该文件为stm32的启动文件,在该文件内会发现有这么一块用汇编写的代码。
  1.       Reset_Handler   PROC
  2.             EXPORT  Reset_Handler    [WEAK]
  3.             IMPORT  __main
  4.             IMPORT  SystemInit
  5.             LDR     R0, =SystemInit
  6.             BLX     R0               
  7.             LDR     R0, =__main
  8.             BX      R0
  9.             ENDP
复制代码

通过这段汇编代码可以看出,程序在执行main函数之前,会先执行SystemInit函数。

2.2 SystemInit函数详解
  1. void SystemInit (void)
  2. {
  3.   /* Reset the RCC clock configuration to the default reset state(for debug purpose) */
  4.   /* Set HSION bit */
  5.   RCC->CR |= (uint32_t)0x00000001;

  6.   /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
  7. #ifndef STM32F10X_CL
  8.   RCC->CFGR &= (uint32_t)0xF8FF0000;
  9. #else
  10.   RCC->CFGR &= (uint32_t)0xF0FF0000;
  11. #endif /* STM32F10X_CL */   

  12.   /* Reset HSEON, CSSON and PLLON bits */
  13.   RCC->CR &= (uint32_t)0xFEF6FFFF;

  14.   /* Reset HSEBYP bit */
  15.   RCC->CR &= (uint32_t)0xFFFBFFFF;

  16.   /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */
  17.   RCC->CFGR &= (uint32_t)0xFF80FFFF;

  18. #ifdef STM32F10X_CL
  19.   /* Reset PLL2ON and PLL3ON bits */
  20.   RCC->CR &= (uint32_t)0xEBFFFFFF;

  21.   /* Disable all interrupts and clear pending bits  */
  22.   RCC->CIR = 0x00FF0000;

  23.   /* Reset CFGR2 register */
  24.   RCC->CFGR2 = 0x00000000;
  25. #elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
  26.   /* Disable all interrupts and clear pending bits  */
  27.   RCC->CIR = 0x009F0000;

  28.   /* Reset CFGR2 register */
  29.   RCC->CFGR2 = 0x00000000;      
  30. #else
  31.   /* Disable all interrupts and clear pending bits  */
  32.   RCC->CIR = 0x009F0000;
  33. #endif /* STM32F10X_CL */

  34. #if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)
  35.   #ifdef DATA_IN_ExtSRAM
  36.     SystemInit_ExtMemCtl();
  37.   #endif /* DATA_IN_ExtSRAM */
  38. #endif

  39.   /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */
  40.   /* Configure the Flash Latency cycles and enable prefetch buffer */
  41.   SetSysClock();

  42. #ifdef VECT_TAB_SRAM
  43.   SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
  44. #else
  45.   SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
  46. #endif
  47. }
复制代码


打开内部8M时钟:
  1. RCC->CR |= (uint32_t)0x00000001
复制代码

通过查看寄存器手册可知,这段代码为打开内部8M时钟。

微信图片_20231104190120.png


设置时钟配置寄存器:
  1. #ifndef STM32F10X_CL
  2.   RCC->CFGR &= (uint32_t)0xF8FF0000;
  3. #else
  4.   RCC->CFGR &= (uint32_t)0xF0FF0000;
  5. #endif /* STM32F10X_CL */   
复制代码

对应寄存器说明可查看《STM32中文参考手册_V10》的6.3.2 时钟配置寄存器(RCC_CFGR)章节。
后续代码,有兴趣可根据《STM32中文参考手册_V10》手册,查看代码具体作用。

2.3 SetSysClock()函数详解
  1. static void SetSysClock(void)
  2. {
  3. #ifdef SYSCLK_FREQ_HSE
  4.   SetSysClockToHSE();
  5. #elif defined SYSCLK_FREQ_24MHz
  6.   SetSysClockTo24();
  7. #elif defined SYSCLK_FREQ_36MHz
  8.   SetSysClockTo36();
  9. #elif defined SYSCLK_FREQ_48MHz
  10.   SetSysClockTo48();
  11. #elif defined SYSCLK_FREQ_56MHz
  12.   SetSysClockTo56();  
  13. #elif defined SYSCLK_FREQ_72MHz
  14.   SetSysClockTo72();
  15. #endif
  16. }
复制代码


system_stm32f10x.c文件中会根据芯片的型号定义对应的宏:
  1. #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
  2. /* #define SYSCLK_FREQ_HSE    HSE_VALUE */
  3. #define SYSCLK_FREQ_24MHz  24000000
  4. #else
  5. /* #define SYSCLK_FREQ_HSE    HSE_VALUE */
  6. /* #define SYSCLK_FREQ_24MHz  24000000 */
  7. /* #define SYSCLK_FREQ_36MHz  36000000 */
  8. /* #define SYSCLK_FREQ_48MHz  48000000 */
  9. /* #define SYSCLK_FREQ_56MHz  56000000 */
  10. #define SYSCLK_FREQ_72MHz  72000000
  11. #endif
复制代码

3 时钟配置函数
3.1 时钟初始化配置函数
  1. void SystemInit(void);
  2. SYSCLK(系统时钟)=72MHZ;
  3. AHB总线时钟(HCLK=SYSCLK)=72MHZ;
  4. APB1总线时钟(PCLK1=SYSCLK/2)=36MHZ;
  5. APB2总线时钟(PCLK1=SYSCLK/1)=72MHZ;
  6. PLL主时钟=72MHZ;
复制代码


3.2 外设时钟使能配置函数
  1. void RCC_AHBPeriphClockCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState);
  2. void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
  3. void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
复制代码

3.3 时钟源使能函数
  1. void RCC_HSICmd(FunctionalState NewState);
  2. void RCC_LSICmd(FunctionalState NewState);
  3. void RCC_PLLCmd(FunctionalState NewState);
  4. void RCC_RTCCLKCmd(FunctionalState NewState);
复制代码


3.4 时钟源和倍频因子配置函数
  1. void RCC_HSEConfig(uint32_t RCC_HSE);
  2. void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource);
  3. void RCC_HCLKConfig(uint32_t RCC_SYSCLK);
  4. void RCC_PCLK1Config(uint32_t RCC_HCLK);
  5. void RCC_PCLK2Config(uint32_t RCC_HCLK);
复制代码

3.5 外设时钟复位函数
  1. void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
  2. void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState);
复制代码

3.6 自定义系统时钟
  1. void RCC_HSE_Config(u32 div,u32 pllm)
  2. {
  3.     RCC_DeInit();
  4.     RCC_HSEConfig(RCC_HSE_ON);
  5.     if(RCC_WaitForHSEStartUp()==SUCCESS)
  6.     {   
  7.         RCC_HCLKConfig(RCC_SYSCLK_Div1);
  8.         RCC_PCLK1Config(RCC_HCLK_Div2);
  9.         RCC_PCLK2Config(RCC_HCLK_Div1);
  10.         RCC_PLLConfig(div,pllm);
  11.         RCC_PLLCmd(ENABLE);     
  12.     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET)
  13.         RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK)
  14.     while(RCC_GetSCLKSource()!=0x08);

  15.     }
  16. }
复制代码
转载自:STM32嵌入式开发

如有侵权请联系删除

收藏 评论0 发布时间:2023-11-4 19:02

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版