因为 STM32 十分复杂,外设非常多,而外设需要的系统时钟频率都不同,且 同一个电路,时钟越快功耗越大,同时抗电磁干扰能力也会越弱,所以采用多时钟源来解决这些问题
五个时钟源
HSI HSE LSI LSE PLL
分类——时钟频率
HSI HSE PLL 为高速时钟
LSI LSE 为低速时钟
分类——来源
HSE LSE 为外部时钟
(外部时钟源为从外部通过接晶振的方式获取时钟源)
LSI HSI PLL 为内部时钟
HSI 是高速内部时钟,RC 振荡器,频率为 8MHz。
HSE 是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为 4MHz~16MHz。
LSI 是低速内部时钟,RC 振荡器,频率为 40kHz。独立看门狗的时钟源只能是 LSI,同时 LSI 还可以作为 RTC 的时钟源
LSE 是低速外部时钟,接频率为 32.768kHz 的石英晶体。这个主要是 RTC 的时钟源
PLL 为锁相环倍频输出,其时钟输入源可选择为 HSI/2、HSE 或者 HSE/2。倍频可选择为2~16 倍,但是其输出频率最大不得超过 72MHz
MCO——时钟输出IO
可以选择一个时钟信号输出
PLL的二分频,HSI,HSE,系统时钟
用来给外部其他系统提供时钟源
USBCLKL——USB时钟
来自 PLL 的时钟源
当使用 USB 模块时必须使能 PLL
SYSCLK——系统时钟
提供绝大部分部件工作的时钟源
来源于三个时钟源
- HSI 振荡器时钟
- HSE 振荡器时钟
- PLL 时钟
AHB——预分频器
分频因子有九种
1,2,4,8,16,64,128,256,512
后接 APB1 和 APB2
APB1——接低速外设
电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3 等
APB2——接高速外设
UART1、SPI1、Timer1、ADC1、ADC2、所有普通 IO 口(PA~PE)、第二功能 IO 口等
APB2 上接的外设时钟要高于 APB1的
当使用某模块时,必须先使能对应的时钟
在system_stm32f10x.c 文件中的SystemInit()函数用来初始化时钟系统
其他则是来设置时钟的函数
系统时钟的 SetSysClock()函数
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz
SetSysClockTo72();
#endif
}
用来判断系统宏定义的时钟是多少,然后设置相应值
该系统默认宏定义是 72MHz
#define SYSCLK_FREQ_72MHz 72000000
要修改为 36MHz 时改为
#define SYSCLK_FREQ_36MHz 36000000
当设置好时系统钟时,可以通过变量 SystemCoreClock
获取系统时钟值
SystemInit()函数中设置的系统时钟大小
SYSCLK(系统时钟) =72MHz
AHB 总线时钟(使用 SYSCLK) =72MHz
APB1 总线时钟(PCLK1) =36MHz
APB2 总线时钟(PCLK2) =72MHz
PLL 时钟 =72MHz
Systick——滴答定时器
常用来做延时,或实时系统的心跳时钟
24位的倒计数定时器,计到 0 时,将从 RELOAD 寄存器中自动重装载定时初值
只要不清除在 SysTick 控制及状态寄存器中的使能位,该过程就不会停止,睡眠模式下也能工作
Systick 相关的定时器
CTRL——控制和状态寄存器
配置函数
SysTick_CLKSourceConfig();
LOAD——重装载数值定时器
VAL——当前值寄存器
利用中断实现延时