文章目录
- 一:基础知识
- 二:SysTick 的时钟频率
- 三:SysTick 的配置
- 四:SysTick 实现精准延时并兼容 FreeRTOS
- 五:参考
一:基础知识
-
SysTick 是什么?
SysTick:系统定时器,是一个 24bit 的向下递减的计数器(计数器每计数一次的时间为 1/SYSCLK,SYSCLK 为系统的是时钟频率(72M、168M等))。属于 CM3 内核中的一个外设,并且内嵌在 NVIC 中。
-
SysTick 的特点
- SysTick 常常用作 延时 或 用于产生时基,维持操作系统的“心跳”。即该硬件定时器用来产生某些使用了时基的系统(FreeRTOS、UCOS 等)需要的“滴答”中断。
- SysTick 是属于 CM3 内核的外设,所有基于 CM3 内核的单片机都具有这个系统定时器。使得操作系统和其它系统软件在 CM3 器件间可以很容易的移植。
- 该定时器的时钟源可以是内部时钟(FCLK, CM3 上的自由运行时钟),或者是外部时钟( CM3 处理器上的 STCLK 信号)。 具体需要检视芯片的器件手册来决定选择什么作为时钟源。
- 节省 MCU 外设资源(不浪费 MCU 内部集成的 TIMER),睡眠模式下也可以工作。
SysTick 定时器可以选择不同的时钟源,可以产生中断,并且 SysTick 定时器是一个倒计数的计数器,每隔一个时钟周期计数值减一,计数至 0 后重新从计数初值处开始倒计数。因此,SysTick 也可用作精准延时。 SysTick 定时器在《STM32F10x- 参考手册》里一个屁都没放,只有在《ARM Cortex-M3 技术参考手册》和《ARM Cortex-M3 权威指南》才找到相关寄存器的介绍。
二:SysTick 的时钟频率
- 在《STM32F10x- 参考手册》中查看有关 SysTick 时钟频率的时钟树。如下图
从图中可以看出 SysTick 有两种模式:一种是 8 分频模式(AHB/8),一种是 FCLK 模式(AHB)。AHB 最大频率可为 SYSCLK (在 f1系列为 72M,f4 系列为 168M )。详细参看《STM32F10x 参考手册》。
三:SysTick 的配置
- 《ARM Cortex-M3 权威指南》中 SysTick 包含四个寄存器,都是 24 位的寄存器,分别是:
- 从上图可以得知,Systick 寄存器 分别为:
- CTRL:控制和状态寄存器。主要用作 配置 SysTick 的时钟源、开启 SysTick 定时器中断以及开启 SysTick 定时器。
- LOAD:重装载数值寄存器。主要作用就是配置 SysTick 的重装载值(一般是配置为 1ms 或者1us 需要递减计数的数值。比如在频率为 72M 下,1us 就需要计数 72 下,1ms 需要递减 72000 下。)并且需要注意的是,SysTick 定时器是一个 24 位递减计数器,所以重装载数值寄存器 LOAD 仅仅用到低 24 位(bit0 ~ bit23),从而使得可以设置的最大值为 16777215。
- VAL:当前数值寄存器。主要作用就是用 延时函数中。(在后面的 us 延时函数中有用到)。
- CALIB:校准数值寄存器。我没怎么用过,就不怎么清楚。
综上所述,SysTick 是一个 24 位的倒计数定时器,当技术到 0 时,会产生 “滴答” 并 将从 RELOAD 寄存器中自动重装载定时初值。只要 SysTick 控制及状态寄存器中的使能位没有清 0,SysTick 定时器就会一直运行。
-
在 core_cm3.h 中声明了可使用的 SysTick 的结构体,声明如下:
typedef struct
{
__IO uint32_t CTRL;
__IO uint32_t LOAD;
__IO uint32_t VAL;
__I uint32_t CALIB;
} SysTick_Type;
-
其次,在 core_cm3.h 中,将 (SysTick_Type *) 进行宏定义为 SysTick。方便后面直接访问结构体内相关成员。
SysTick 初始化编程步骤
-
配置 SysTick 时钟源
固件库函数:SysTick_CLKSourceConfig( );
头文件:misc.h
参数: SysTick_CLKSource_HCLK_Div8 --> AHB 的8分频
SysTick_CLKSource_HCLK --> AHB
-
配置 SysTick 的重装载值
-
开 SysTick 中断 以及 开启 SysTick 定时器
四:SysTick 实现精准延时并兼容 FreeRTOS
SysTick 定时器初始化脑图
SysTick 进行初始化代码
void delay_init(u8 SYSCLK)
{
u32 reload;
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
fac_us=SYSCLK;
reload=SYSCLK;
reload*=1000000/configTICK_RATE_HZ;
fac_ms=1000/configTICK_RATE_HZ;
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk;
SysTick->LOAD=reload;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;
}
- 注释:假设系统频率为 72M HZ,那么 SysTick 定时器每 1s 的计数数值为 72000000。同理,SysTick 定时器节拍数为 72000,那么就是 1ms;为 72,就是 1us。
微妙延时函数的实现
void delay_us(u32 nus)
{
u32 ticks;
u32 told,tnow,tcnt=0;
u32 reload=SysTick->LOAD;
ticks=nus*fac_us;
told=SysTick->VAL;
while(1)
{
tnow=SysTick->VAL;
if(tnow!=told)
{
if(tnow<told)tcnt+=told-tnow;
else tcnt+=reload-tnow+told;
told=tnow;
if(tcnt>=ticks)break;
}
};
}
- 延时函数的实现过程如下:
毫秒延时函数的实现
void delay_ms(u32 nms)
{
if(xTaskGetSchedulerState()!=taskSCHEDULER_NOT_STARTED)
{
if(nms>=fac_ms)
{
vTaskDelay(nms/fac_ms);
}
nms%=fac_ms;
}
delay_us((u32)(nms*1000));
}
void delay_xms(u32 nms)
{
u32 i;
for(i=0;i<nms;i++) delay_us(1000);
}
五:参考
【1】STM32: SysTick系统定时器–滴答定时器
【2】Systick定时器
【3】Stm32-SysTick详解
【4】单片机(四)Systick系统定时器
【5】SysTick定时器
【6】STM32F103 Systick配置
【7】《STM32F10x- 参考手册》
【8】《ARM Cortex-M3 技术参考手册》
【9】《ARM Cortex-M3 权威指南》
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)