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;

注:以上均是学习笔记。

相关推荐
瑞江无限3 小时前
南麟NP3401MR-M-G技术规格与应用全解析
单片机·嵌入式硬件
kuan_li_lyg4 小时前
笛卡尔坐标机器人控制的虚拟前向动力学模型
人工智能·stm32·机器人·机械臂·动力学·运动学·导纳控制
典则4 小时前
STM32FreeRtos入门(五)——同步互斥与通信
java·jvm·stm32
qq_401700414 小时前
自恢复保险丝
单片机·嵌入式硬件
三佛科技-134163842125 小时前
暖手宝方案开发,暖手宝MCU控制方案开发设计
单片机·嵌入式硬件·智能家居·pcb工艺
物随心转7 小时前
ARM的中断模式与快速中断模式
嵌入式硬件
朱嘉鼎8 小时前
寄存器编写LED程序
stm32·单片机·架构·keilmdk
点灯小铭9 小时前
基于单片机的智能厨房环境控制系统设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
LS_learner14 小时前
运放的虚短和虚断
嵌入式硬件