RCC—使用HSE配置系统时钟
芯片提供时钟就要有时钟树
时钟树在参考手册RCC章节开头就有(这里的时钟树看到感觉眼睛打了马赛克,小弟截图技术有限)
什么是晶振?
晶振:晶体振荡器,用于各种电路中产生振荡频率,每个单片机里都会有晶振,给单片机提供时钟频率,振荡得越快,时钟频率就越高,单片机运行的速度就越快
解析时钟树的方法:(系统时钟)
时钟是由晶振提供的,首先要找到时钟的入口点。图中OSC_IN 和 OSC_OUT,这两个是外部晶振的引脚,所以时钟是从这里进入的。接有源晶振时,时钟从OSC_IN进入,OSC_OUT悬空。接无源晶振时,时钟从OSC_IN 和 OSC_OUT一起进入
时钟进入以后会经过PLL锁相环,进入前会经过一个M分频,进入PLL锁相环之后就会进入N倍频,输出时经过一个P分频,输出的时钟为PLLCLK
可以选择PLLCLK、HSE、HIS作为系统时钟
然后经过AHB总线的分频因子,成为HCLK作为AHB总线的时钟,或者再经过APB的分频因子作为APB1、APB2总线的时钟(根据参考手册AHB总线频率最大为180MHZ 、高速APB2总线频率最大为90MHZ 低速APB1总线频率最大为45MHZ)
上述分析的是时钟树的系统时钟,还有其他时钟RTC实时时钟、看门狗时钟、I2S时钟、以太网时钟、MCO输出时钟,这些等需要用到的时钟看吧
下面用固件库编写使用HSE配置系统时钟函数
(HSI也是同样的思路)
启动HSE,在头文件寻找HSE启动的函数void RCC_HSEConfig(uint8_t RCC_HSE)
等待HSE稳定ErrorStatus RCC_WaitForHSEStartUp(void)
这个函数是如何实现的:在这个函数中还调用了函数
FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)
那先讲解这个函数是如何实现的:这个函数的功能是检查是否设置了指定的RCC标志。RCC的标志(RCC_FLAG)都会有自己的值,首先检查参数,然后得到RCC寄存器的位号(根据RCC的标志确定在RCC的哪个寄存器里),最后获得RCC寄存器的位置判断是否设置了指定的参数,然后返回值,如果设置了返回1,否返回0
判断HSE是否准备好,如果是返回1,否返回0
设置HCLK、APB1、APB2预分频因子
void RCC_HCLKConfig(uint32_t RCC_SYSCLK)
void RCC_PCLK1Config(uint32_t RCC_HCLK)
void RCC_PCLK2Config(uint32_t RCC_HCLK)
设置进入PLL锁相环的M分频因子 PLL锁相环的N倍频因子 出PLL锁相环的P分频因子 void RCC_PLLConfig(uint32_t RCC_PLLSource, uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ)控制系统时钟的频率就在于这几个分频因子
启动PLL void RCC_PLLCmd(FunctionalState NewState)
等待PLL稳定 使用了FlagStatus RCC_GetFlagStatus(uint8_t RCC_FLAG)把RCC_FLAG设为RCC_FLAG_PLLRDY,若准备好返回1
设置PLLCLK为系统时钟void RCC_SYSCLKConfig(uint32_t RCC_SYSCLKSource)
读取状态位确保PLLCLK被选中为系统时钟
uint8_t RCC_GetSYSCLKSource(void)//该函数功能:返回时钟源用作系统时钟
若返回数值为PLLCLK数值,则PLLCLK被选为系统时钟
代码如下
函数的形参根据函数中需要传入的数据所设定
void HSE_SetSysclk ( uint32_t PLLM, uint32_t PLLN, uint32_t PLLP, uint32_t PLLQ)
{
RCC_HSEConfig(RCC_HSE_ON);
if(RCC_WaitForHSEStartUp()==SUCCESS)
{
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div4);
RCC_PCLK2Config(RCC_HCLK_Div2);
RCC_PLLConfig(RCC_PLLSource_HSE,PLLM, PLLN, PLLP, PLLQ);
RCC_PLLCmd(ENABLE);
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while(RCC_GetSYSCLKSource()!=0x08);
}
else
{
while(1)
{
}
}
}
上一篇:GPIO输出——固件库点LED GPIO输入——按键检测
下一篇:STM32 高级定时器 输出PWM (用DHT11测得的温度去调节RGB灯的亮度)
推荐阅读最新更新时间:2024-10-23 02:01
设计资源 培训 开发板 精华推荐
- L6726ATR单相PWM控制器典型应用
- LTC3210-2/LTC3210-3 的典型应用 - 采用 3mm -3mm QFN 封装的具有 32 级亮度控制的主/凸轮 LED 控制器
- LTC3603IMSE 1.8V、2.5A 降压稳压器(1MHz、突发模式操作)的典型应用电路
- DC2066A,具有数字 PSM 的 LTM4677EY 模块稳压器演示板,4.5V = VIN = 16V,Vout0 = Vout1 = 0.5V 至 1.8V @ 18A
- 用于个人数字助理的 3V DC 至 DC 单路输出电源
- 具有轻松驱动输入电流消除功能的 LTC2484、24 位 ADC 的典型应用
- AD8657ARMZ-R7 4 mA至20 mA电流环路变送器的典型应用电路
- OM13489: 面向Fm+开发板的通用16位通用IO子板
- 多路输出稳压电源
- ch9102x_usb_to_ttl