STM32 系统定时器(精准延迟)

系统定时器(中断延时(定时中断执行功能))

《STM32中文参考手册》P108

SysTick叫做系统滴答时钟(系统定时器),属于Cortex-M4内核中的一个外设(外围设备),并且是24bit向下递减的计数器。

RCC向Cortex系统定时器(SysTick)馈送8分频的AHB时钟(HCLK)。SysTick可使用此时钟作为时钟源,也可使用HCLK作为时钟源,具体可在SysTick控制和状态寄存器中配置。(168MHZ(HCLK时钟)、21MHZ(8分频的AHB时钟(HCLK)

注意:

  • 定时器的位数越多,定时时间更长。
  • 通过计数值间接计算定时时间,不能像操作系统直接调用函数实现延时或定时功能。计数值,就是要进行多少个计数。

系统定时器(事件延时)

《Cortex M3与M4权威指南.pdf》第351页

1. 官方标准例程代码:

c 复制代码
SysTick->CTRL = 0; 			      // Disable SysTick                             0 0000 0000 0000 0000SysTick->LOAD = 0xFF;			      // Count from 255 to 0 (256 cycles)SysTick->VAL = 0;			      // Clear current value as well as count fl
SysTick->CTRL = 5; 			      // Enable SysTick timer with processor clock   0 0000 0000 0000 0101
while ((SysTick->CTRL & 0x00010000)==0);      // Wait until count flag is set                0000 0000 0000 0001 0000 0000 0000 0000
SysTick->CTRL = 0;                            // Disable SysTicki

2. 相关寄存器说明

a. 控制和状态寄存器 SysTick CTRL 寄存器

地址:0xE000E010

作用:控制 SysTick 的启停、时钟源、中断,以及读取计数完成标志。

名称 说明
0 ENABLE 1 = 启动 SysTick 计数器;0 = 禁止计数
1 TICKINT 1 = 计数到 0 时触发中断;0 = 不触发中断
2 CLKSOURCE 1 = 内部处理器时钟(HCLK);0 = 外部时钟(通常为 HCLK/8)
16 COUNTFLAG 1 = 计数到 0 时自动置位,读后自动清零;0 = 未完成

其余位通常保留,写 0 即可。

代码中的用法

复制代码
SysTick->CTRL = 0;   // 关闭
SysTick->CTRL = 5;   // 5 = 0b101 -> ENABLE=1, TICKINT=0, CLKSOURCE=1
while ((SysTick->CTRL & 0x00010000) == 0);  // 等待 COUNTFLAG = 1

b. 重装载寄存器 SysTick LOAD 寄存器

地址:0xE000E014

作用:设置倒计数的初始值,计数器每次从 LOAD 的值开始倒数到 0。

  • 可设置范围:0~0xFFFFFF(24 位)
  • 当计数到 0 时:
    1. COUNTFLAG = 1
    2. 如果 ENABLE=1,计数器自动重新加载 LOAD 值(形成循环计数)

代码中的用法

复制代码
SysTick->LOAD = 0xFF;  // 计数 256 个周期(255->0)

c. 当前数值寄存器 SysTick VAL 寄存器

地址:0xE000E018

作用:当前倒计数值。写 0 会:

  1. 清零计数器(下次从 LOAD 开始计数)
  2. 清除 COUNTFLAG 标志

代码中的用法

c 复制代码
SysTick->VAL = 0;  // 清零计数器和标志

3. 操作说明

a. 关闭 SysTick

复制代码
SysTick->CTRL = 0;  // Disable SysTick
  • CTRL 是 SysTick 控制寄存器。
  • 写 0 表示 关闭 SysTick 定时器
  • 注释里的二进制:0 0000 0000 0000 0000 表示所有位都清零。

作用:保证开始时定时器是关闭状态,防止计数异常。


b. 设置计数值

复制代码
SysTick->LOAD = 0xFF;  // Count from 255 to 0 (256 cycles)
  • LOAD 寄存器设置计数器的初始值。
  • 0xFF = 255,计数器会从 255 倒数到 0。
  • SysTick 倒计数器 ,所以总共计数 256 个时钟周期(包含 0)。

c. 清零当前计数

复制代码
SysTick->VAL = 0;  // Clear current value as well as count flag
  • VAL 是当前计数值寄存器。
  • 写 0 会:
    1. 清除当前计数器的值(马上从 LOAD 开始计数)。
    2. 清除计数完成标志(COUNTFLAG)。
  • 注释中的 "clear count fl" 就是指这个标志。

d. 启动定时器

复制代码
SysTick->CTRL = 5;  // Enable SysTick timer with processor clock
  • CTRL 控制寄存器:
    • Bit 0 (ENABLE) = 1 → 使能 SysTick。
    • Bit 2 (CLKSOURCE) = 1 → 选择 处理器时钟(HCLK) 作为时钟源。
    • Bit 1 (TICKINT) = 0 → 不产生中断。
  • 二进制:0 0000 0000 0000 0101
    • 从右到左:
      • Bit0=1 (ENABLE)
      • Bit1=0 (TICKINT)
      • Bit2=1 (CLKSOURCE)
      • 其他位=0

e. 等待计数完成

复制代码
while ((SysTick->CTRL & 0x00010000) == 0);
  • Bit16 (COUNTFLAG) = 1 → 表示计数器从 LOAD 倒数到 0。

  • 这里是一个 阻塞等待,直到计数完成。

  • 二进制注释:

    复制代码
    0000 0000 0000 0001 0000 0000 0000 0000

    正是 Bit16 的掩码。


f. 再次关闭 SysTick

复制代码
SysTick->CTRL = 0;  // Disable SysTick
  • 延时完成后关闭定时器,防止误触发。

使用配置

时间配置

c 复制代码
SysTick_Config(SystemCoreClock/1000) ; //系统滴答定时器1ms触发一次

系统滴答定时中断函数

事件触发后,需要去执行的中断函数,函数内容按照需求即可。

c 复制代码
void SysTick_Handler(void);

注意:函数格式(函数名,返回值,参数)必须一致,具体函数名可参考启动文件 startup_stm32f40_41xxx.s

补充说明

ST官方给的例程代码,是没有考虑意外关闭中断的问题的,需要额外补充。

c 复制代码
uint32_t temp = 0;

// 系统滴答时钟配置
SysTick->CTRL = 0;
SysTick->LOAD = sysclk_nus-l;
SysTick->VAL=0;
SysTick->CTRL = sysclk_clh_flag:

while(1)
{
    temp = SysTick->CTRL;
    //检测COUNTFLAG标志位
    if(temp & 0x00010000)
    	break;
    //检查系统定时器是否意外关闭
    if((temp &0x1)==0)
    	return -1: // 意外关闭,直接退出
}
SysTick->CTRL = 0;

注:以上均是学习笔记。

相关推荐
LS_learner17 小时前
树莓派(ARM64 架构)Ubuntu 24.04 (Noble) 系统 `apt update` 报错解决方案
嵌入式硬件
来自晴朗的明天18 小时前
16、电压跟随器(缓冲器)电路
单片机·嵌入式硬件·硬件工程
钰珠AIOT18 小时前
在同一块电路板上同时存在 0805 0603 不同的封装有什么利弊?
嵌入式硬件
代码游侠18 小时前
复习——Linux设备驱动开发笔记
linux·arm开发·驱动开发·笔记·嵌入式硬件·架构
代码游侠1 天前
学习笔记——设备树基础
linux·运维·开发语言·单片机·算法
xuxg20051 天前
4G 模组 AT 命令解析框架课程正式发布
stm32·嵌入式·at命令解析框架
CODECOLLECT1 天前
京元 I62D Windows PDA 技术拆解:Windows 10 IoT 兼容 + 硬解码模块,如何降低工业软件迁移成本?
stm32·单片机·嵌入式硬件
BackCatK Chen1 天前
STM32+FreeRTOS:嵌入式开发的黄金搭档,未来十年就靠它了!
stm32·单片机·嵌入式硬件·freertos·低功耗·rtdbs·工业控制
全栈游侠1 天前
STM32F103XX 02-电源与备份寄存器
stm32·单片机·嵌入式硬件