文章目录
1. STM32时钟系统概述
1.1 时钟系统的概念及意义
-
概念:时钟系统是由振荡器(信号源)、定时唤醒器、分频器等组成的电路。常用的信号源有晶体振荡器和RC振荡器
-
意义:时钟是嵌入式系统的脉搏,处理器内核在时钟驱动下完成指令执行,状态变换等动作,外设部件在时钟的驱动下完成各种工作,比如串口数据的发送、A/D转换、定时器计数等等。因此时钟对于计算机系统是至关重要的,通常时钟系统出现问题也是致命的,比如振荡器不起振、振荡不稳、停振等。
首先,通过晶体振荡器产生一个时钟信号,然后跟着一个开关,不开这个时钟信号就没有办法传递出去。通常来说晶体振荡器的频率是比较低的,而CPU可以承受的频率是比较大的。比如振荡器只能有几兆或几十兆的时钟信号产生,而CPU需要的时钟信号是上百兆。因此,我们需要倍频器,使输出信号频率等于输入信号频率整数倍的电路,供给CPU使用。然而我们有很多内外设,他们的需要的频率没有CPU那么高,因此我们又需要分频器,将高速频率降下来,适合各个部件的工作频率。
1.2 常见振荡器介绍
-
概念:振荡器是用来产生重复电子讯号的电子元件。其构成的电路叫振荡电路,能将直流电转换为具有一定频率交流信号输出的电子电路或装置。
-
分类:振荡器主要分为RC,LC振荡器和晶体振荡器。RC振荡器是采用RC网络作为选频移相网络的振荡器。LC振荡器是采用LC振荡回路作为移相和选频网络的正反馈振荡器。晶体振荡器的振荡频率受石英晶体控制。
-
RC振荡器:RC振荡器是由电阻电容构成的振荡电路,能将直流电转换为具有一定频率交流信号输出的电子电路或装置
- 优点:实现的成本比较低
- 缺点:由于电阻电容的精度问题所以RC振荡器的震荡频率会有误差,同时受到温度、湿度的影响
-
晶体振荡器:石英晶体振荡器是高精度和高稳定度的振荡器,被广泛应用于彩电、计算机、遥控器等各类振荡电路中,以及通信系统中用于频率发生器、为数据处理设备产生时钟信号和为特定系统提供基准信号
- 优点:是相对来说震荡频率一般都比较稳定,同时精度也较高
- 缺点:价格稍高,用晶体振荡器一般还需要接两个15-33pF起振电容
-
STM32 中主要有四个时钟源: 可以分为高速和低速两种,高速一般几十MHz,低速一般几十kHz;还可以分为内部和外部两种,内部指在STM32内已经集成了,外部指可以在管脚外部接一个晶振。当我们开机刚上电的时候,我们需要给CPU提供时钟信号,但是外部管脚还没有被初始化,这时候我们就需要使用高速内部时钟来给CPU提供时钟信号。如果出现外部时钟出现故障,这个时候也可以调用内部时钟继续工作
- HSI:高速内部时钟,RC振荡器,频率为16MHz;
- HSE:高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~26MHz
- LSI:低速内部时钟,RC 振荡器,频率为 32kHz 左右。供独立看门狗和自动唤醒单元使用。
- LSE:低速外部时钟,接频率为 32.768kHz 的石英晶体。这个主要是 RTC 的时钟源
1.3 时钟树分析
STM32中所有的设备都是需要时钟的,那么怎么时钟源给每一个设备分配适合它的时钟信号都会体现在时钟树中。从上往下看,低速内部时钟主要控制看门狗;低速外部时钟控制RTC;高速内部时钟、高速外部时钟都可以直接选择作为系统时钟,也可以让他们通过倍频器将频率提高到最高168MHz作为系统时钟。当确定好选择哪一个时钟后可以通过AHB PRESC给Cortex系统等高速内核使用,也可以在通过APB PRESC给低速外设使用。
2. STM32时钟配置实例
配置STM32F407的时钟,并对比STM32时钟配置前(16 MHz)后(168 MHz)LED外设闪烁的快慢。需要注意的是闪烁的时候需要用到delay
函数,然而HAL_Delay
不管设置的时钟是多少都是按照毫秒来计算的,因此我们需要自己写一个delay
函数,比较简单代码如下。
void delay(uint32_t time)
{
uint32_t i, j;
for (i = 0; i < time; i++)
{
for (j = 0; j < 5000; j++);
}
}
通过电路原理图,我的板子上的LED用的是PE2、PF8、PF9 和 PF10,因此要设置他们为输出模式。
然后我们看一下时钟配置,默认情况下用的是HSI,也就是高速内部时钟(16 MHz),导出工程后,在main
函数的while
里写如下代码。然后下载到板子里,可以观察到板子上的LED每次闪烁在一秒左右。
while (1)
{
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10, GPIO_PIN_RESET);
delay(1000);
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_2, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOF, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10, GPIO_PIN_SET);
delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
然后,我们按照下图重新设置一下时钟(先设置能使用外部晶振,在配置倍频器),这样能把时钟拉满。算是STM32F407能接受的最快速度。这个时候,我们重新导出工程,下载到板子里,可以观察到闪烁速度快了将近十倍。
3. SysTick定时器讲解
3.1 SysTick 定时器介绍
- 概念:
能够定时、计数的器件称为定时器。SysTick,(系统滴答定时器)是一个定时设备,位于Cortex-M4内核中,可以对输入的时钟进行计数,当然,如果时钟信号是周期性的,计数也就是计时。系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。根据这个中断,系统就可以实现时间片的计算从而切换进程。 - 工作原理:
滴答定时器是一个24位定时器,也就是最多能计数 2 24 2^{24} 224。在使用的时候,我们一般给计数器送一个初始的计数值,计数器向下计数,每来一个时钟信号,计数初值就减一,计数值减到0的时候,就会发出一次中断。然后重新从计数初值再减一计数,循环不断