文章目录
-
SysTick定时器(系统滴答定时器)是一个在Cortex M内核中定义的倒计时定时器,被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15)
-
SysTick是一个24位的递减定时器,具有自动重载和溢出中断功能
-
Cortex M核设置一个通用SysTick定时器的目的,增加用户在不同核芯片之间移植的便利性,尤其在使用操作系统的时候

寄存器
SysTick控制和状态寄存器(SysTick->CTRL)
| 位 | 名称 | 描述 |
|---|---|---|
| 16 | COUNTFLAG | 当 SysTick 定时器递减计数到 0,该位自动变成 1,如果 TICINT 设置为 1,会产生 SysTick 异常。同时,重装载寄存器 SysTick->LOAD 中的值会载入到当前计数器 SysTick->VAL。读该寄存器或清除计数器则该位清零 |
| 2 | CLKSOURCE | 时钟源选择,0 外部参考时钟(STCLK),1 使用内核时钟 |
| 1 | TICKINT | 允许产生异常配置,1 允许异常 |
| 0 | ENABLE | SytTick 定时器使能,1 使能 |
- 当 CLKSOURCE 设置为0,选择参考时钟时,由 RCC 模块中的寄存器 RCC_CCIPR1完成 SysTick 时钟源的选择

Bits 23:22 SYSTICKSEL[1:0]: SysTick 时钟源选择:
00: HCLK/8 selected
01: LSI selected
10: LSE selected
11: reserved
SysTick重装载值寄存器(SysTick->LOAD)
- 位[23:0]:重装载值
SysTick当前值寄存器(SysTick->VAL)
- 位[23:0]:SysTick当前计数值,写入任何值,清除该寄存器
SysTick校准值寄存器(SysTick->CALIB)
- 提供了SysTick的校准值。目前,很少使用,芯片供应商一般通过其他的可替代方案
使用方法
- 在具备嵌入式实时操作系统(RTOS)的软件中,很多RTOS已经支持了SysTick
- 在未使用RTOS的软件中,可以通过CMSIS-CORE提供的接口函数下面的函数,使用处理器时钟作为时钟源,让SysTick按参数 ticks 产生周期性的中断,中断优先级为最低
c
uint32_t SysTick_Config(uint32_t ticks);
//按当前系统时钟的千分之一(周期是1ms)产生中断
SysTick_Config(SystemCoreClock / 1000);
产生周期性的中断
- CubeMX生成的代码,已经自动完成,并将中断周期设置为1ms
初始化
c
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority);
阻塞延时
c
void HAL_Delay(uint32_t Delay);
非阻塞延时
- 获取当前中断计数值,并以此为计数初值,根据需要,通过查询判断延时
c
uint32_t HAL_GetTick(void);
c
if(HAL_GetTick() >= led1_delay)
{
led1_delay = HAL_GetTick() + 500;
HAL_GPIO_TogglePin(Led1_GPIO_Port, Led1_Pin);
}
注意
- SysTick定时器中的寄存器只能在特权状态下访问
- 若使用嵌入式OS,则SysTick会被OS占用,不能再被应用任务使用
- SysTick会在调试暂停时,停止计数,也会在某些休眠状态中停止计数
- 利用CubeMX生成的初始化代码中,SysTick中断因为优先级最低,所以不能在其他的中断中调用依赖SysTick中断计时的函数,比如 HAL_Delay()
- 周期性中断计数值会有溢出的问题,当程序连续运行可能满足溢出条件时,需要注意