在正点原子的《STM32F1开发指南-库函数版本_V3.3》第五章 SYSTEM文件夹介绍的5.1中对于系统定时器的讲解中出现了如下内容。
这一行:
fac_us=SystemCoreClock/8000000
讲解的很笼统,对于初学者来说不易理解,经过我查阅众多资料详解如下:
STM32F103的时钟频率是72MHz,PLL锁相环(72MHz)或者HSI(72MHz)后得到的SYSCLK再经过八分频后得来的Cortex系统时钟(72MHz/8=9MHz),如下图所示:
我们以delay_nus函数为例分析,代码如下(正点原子的任何一个例程都包括这个代码,在SYSTEM文件夹下的delay.c中)
//延时初始化函数
void delay_init()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟 HCLK/8
fac_us=SystemCoreClock/8000000; //为系统时钟的1/8
fac_ms=(u16)fac_us*1000; //非OS下,代表每个ms需要的systick时钟数
}
//延时nus
//nus为要延时的us数.
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us; //时间加载
SysTick->VAL=0x00; //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00; //清空计数器
}
其中的
fac_us=SystemCoreClock/8000000
就是我们这次的重点。SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);函数就是选择时钟来源函数,在这里SysTick 的时钟源自 HCLK 的 8 分频,假设我们外部晶振为 8MHz然后倍频到 72MHz ,那么 SysTick 的时钟即为 :
SysTick时钟频率 = SystemCoreClock / 8=72Mhz / 8=9MHz=9 000 000Hz
我们都知道周期T和频率F是倒数关系,所以SysTick的一个周期为
[1/(SystemCoreClock/8)]=1 / 9 000 000S=1 / 9us
因为1s=1000 000us,那么反过来
所以1us内SysTick需要计数的次数就是
也就是1us计数9次