SysTick 简单总结
一、SysTick 核心基础
- 本质与特性:属于 Cortex-M 内核外设,24 位向下递减计数器,所有 Cortex-M 系列(M3/M4/M7)通用,方便软件移植,常用于 OS 时基。
- 时钟源与计数:计数周期为
1/SYSCLK
,RT1052 中 SYSCLK 等于 AHB 时钟(528MHz);计数器减至 0 时,会置位标志或触发中断(需使能)。 - 关键寄存器:共 4 个,定时功能仅需配置前 3 个。
- CTRL:控制及状态寄存器,配置时钟源(AHB/8 或 AHB)、中断使能、定时器使能。
- LOAD:重装载数值寄存器,设定计数器初始值(最大值 2²⁴)。
- VAL:当前数值寄存器,读取获当前值,写入可清零并清除 COUNTFLAG。
- CALIB:校准寄存器,定时实验中无需使用。
二、SysTick 编程实现(以 500ms 定时 / LED 闪烁为例)
1. 编程核心要点
无论哪种方式,都需遵循 3 个基础步骤:
- 设置 LOAD 寄存器的重装载值。
- 清零 VAL 寄存器的当前值。
- 配置 CTRL 寄存器(时钟源、中断 / 使能)。
2. 两种编程方式对比
对比维度 | 中断法(推荐用于 OS 或多任务) | 查询法(推荐用于简单延时) |
---|---|---|
核心逻辑 | 定时器减至 0 触发中断,在中断中更新计时变量 | 轮询 CTRL 寄存器的 COUNTFLAG 位,判断是否计数到 0 |
关键代码 | 调用SysTick_Config() 配置中断,编写SysTick_Handler() 中断服务函数 | 调用SysTick_Config() 后,循环查询(SysTick->CTRL)&(1<<16) |
资源占用 | 需全局变量(如TimingDelay )记录次数 | 无需全局变量,代码更简洁 |
适用场景 | 操作系统时基、后台定时任务 | 简单的毫秒 / 微秒级延时(如 LED 闪烁) |
3. 关键代码解析
中断法核心代码:
- 初始化函数:
SysTick_Init(void)
调用SysTick_Config(SystemCoreClock/1000)
,配置 1ms 中断一次(528MHz/1000=528000)。 - 中断服务函数:
SysTick_Handler()
中对TimingDelay
减 1,实现计时。 - 延时函数:
Delay_ms(nTime)
通过等待TimingDelay
减至 0,实现指定毫秒延时。
- 初始化函数:
查询法核心代码:
- 微秒延时:
SysTick_Delay_Us(us)
配置时钟为 1MHz(528MHz/1000000),循环查询 COUNTFLAG,每次查询对应 1 微秒。 - 毫秒延时:
SysTick_Delay_Ms(ms)
配置时钟为 1kHz(528MHz/1000),循环查询 COUNTFLAG,每次查询对应 1 毫秒,延时结束后关闭定时器。
- 微秒延时:
三、中断优先级配置
- 内核外设与片上外设优先级关系:
- 内核外设(如 SysTick)优先级由 SCB 的 SHPRx 寄存器配置,仅 1 个优先级值(0-15,数值越小优先级越高)。
- 片上外设优先级需先分组,再设抢占 / 子优先级,两者优先级比较需遵循 NVIC 分组规则(如分组 2 时,SysTick 优先级 15 对应抢占 3、子优先级 3)。
- 默认优先级:
SysTick_Config()
中默认配置优先级为 15(最低),可通过NVIC_SetPriority(SysTick_IRQn, 优先级值)
修改。