MCU微课堂
第一期 2022.12.10
作为MCU运行的基础,时钟是单片机各个模块工作时序的最小时间单位,推动单片机的各指令执行,是MCU选型的一个重要指标。CKS32F4xx系列产品具有众多的外设,但并非所有的外设均需要系统时钟的高频率,并且高时钟频率将导致功耗增加、抗电磁干扰能力变弱,因此,CKS32F4xx系列产品内部具备多个时钟源。本文将对CKS32F4xx系列产品时钟组成进行分析,并讲解该系统单片机的时钟的配置方法,以能够让用户更加简单的对系统时钟进行配置。
CKS32F4xx系列产品时钟树
在CKS32F4xx系列产品中,有HSI、HSE、LSI、LSE、PLL五个重要的时钟源,其中PLL分为主PLL和专用PLL两部分。从时钟频率来分可以分为高速时钟源(HIS、HIS、PLL)和低速时钟源(LSI、LSE);从来源可分为外部时钟源(HSE、LSE)和内部时钟源(HIS、LSI、PLL)。
①:LSI是低速内部RC振荡器,频率为32kHz。供独立看门狗和RTC单元使用。
②:LSE是低速外部时钟,接频率为32.768kHz晶振。主要供RTC单元使用。
③:HSE是高速外部时钟晶振输入,频率范围为4MHz~26MHz。。
④:HSI是高速内部RC振荡器,频率为16MHz。可以直接作为系统时钟或者用作PLL输入。
⑤:PLL为锁相环倍频输出,有两个PLL:
1)主 PLL(PLL)由 HSE 或者 HSI 提供时钟信号,并具有两个不同的输出时钟。
其一PLLP用于生成高速的系统时钟(最高 168MHz)
其二PLLQ用于生成 USB_OTG_FS(48MHz)、随机数发生器SDIO时钟。
2)专用 PLL(PLLI2S)用于生成精确时钟,用于实现I2S高品质音频性能。
CKS32F4xx系列系统时钟配置
在CKS32F4xx系列固件库system_cks32f4xx.c文件中定义了函数SystemInit(void),并在其中调用了SetSysClock()函数来配置系统关键时钟寄存器,其处理流程如下:
先使能外部时钟HSE,等待HSE稳定之后,配置AHB、APB1、APB2时钟相关的分频因子;等待这些都配置完成之后,打开主PLL时钟并设置主PLL作为系统SYSCLK时钟源。如果HSE不能达到就绪状态则依然以HSI作为系统时钟源头。
在设置主PLL时钟时,需要设置一系列的分频系数和倍频参数,代码如下:
RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | (RCC_PLLCFGR_PLLSRC_HSE) | (PLL_Q << 24);
PLL_M、PLL_N、PLL_P宏定义均在在System_cks32f4xx.c文件中定义,当采用8MHz外部晶振时,主PLL时钟计算方法如下:
PLL = 8MHz * PLL_N / (PLL_M * PLL_P) = 8MHz * 336 /(8 * 2) = 168MHz
用户可根据实际需求,根据SetSysClock函数内的注释进行实际修改,可用的时钟源配置宏定义位于cks32f4xx.h中,如RCC_CR_HSION、RCC_CR_HSEON等。
CKS32F4xx系列外设时钟配置
在系统初始化之后,在使用部分外设时,我们还需要根据外设需求修改某些时钟源配置。在CKS32F4xx系列固件库中,时钟源的选择以及时钟使能等函数均在RCC相关固件库文件 cks32f4xx_rcc.h 和 cks32f
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); void RCC_AHB2PeriphClockCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); void RCC_AHB3PeriphClockCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); void RCC_APB1PeriphClockCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); void RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
以上5个系统时钟使能函数分别控制AHB1、AHB2、AHB3、APB1、APB2总线。要使能某个外设,调用对应的总线外设时钟使能函数即可。
例如,如果我们要使能GPIOA,那么我们可以在头文件 cks32f4xx_rcc.h 里面查看到宏定义标识符RCC_AHB1Periph_GPIOA挂载在AHB1总线之下,因此我们调用方式入如下:
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
同理,如果我们要使能USART1的时钟,那么我们调用的函数为:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
还有一类时钟使能函数是时钟源使能函数,前面我们已经讲解过CKS32F4xx系列有5类时钟源。这里我们列出来几种重要的时钟源使能函数:
void RCC_HSICmd(FunctionalState NewState); void RCC_LSICmd(FunctionalState NewState); void RCC_PLLCmd(FunctionalState NewState); void RCC_PLLI2SCmd(FunctionalState NewState); void RCC_PLLSAICmd(FunctionalStateNewState); void RCC_RTCCLKCmd(FunctionalState NewState);
具体调用方法如下:
RCC_PLLCmd(ENABLE);
第二类时钟功能函数:时钟源选择和分频因子配置函数用来选择相应的时钟源以及配置相应的时钟分频系数,比如配置HSI、HSE、PLL三个中的一个时钟源为系统时钟。以下为几种时钟源配置函数:
void RCC_LSEConfig(uint8_t RCC_LSE); void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource); void RCC_HCLKConfig(uint32_t RCC_SYSCLK); void RCC_PCLK1Config(uint32_t RCC_HCLK); void RCC_PCLK2Config(uint32_t RCC_HCLK); void RCC_RTCCLKConfig(uint32_t RCC_RTCCLKSource); void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM,uint32_t PLLN, int32_t PLLP, uint32_t PLLQ);
比如我们要设置系统时钟源为 HSI,则可以调用系统时钟源配置函数:
RCC_HCLKConfig(RCC_SYSCLKSource_HSI);
第三类外设复位函数如下:
void RCC_AHB1PeriphResetCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState); void RCC_AHB2PeriphResetCmd(uint32_t RCC_AHB2Periph, FunctionalState NewState); void RCC_AHB3PeriphResetCmd(uint32_t RCC_AHB3Periph, FunctionalState NewState); void RCC_APB1PeriphResetCmd(uint32_t RCC_APB1Periph, FunctionalState NewState); void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);
这类函数和前面讲解的外设时钟函数使用方法基本一致,不同的是一个是用来使能外设时钟,一个是用来复位对应的外设。对于这些时钟操作函数,我们就不一一列举出来,大家可以打开 RCC 对应的文件仔细了解。
审核编辑:汤梓红
评论
查看更多