SysTick滴答定时器简介

本文深入解析了STM32微控制器中的SysTick定时器,介绍了其作为NVIC一部分的作用,以及如何通过配置不同的寄存器实现微秒、毫秒和秒级的精确延时。文章提供了具体的初始化代码和延时函数实现,适用于系统在不同CM3器件间的移植。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述:
系统滴答定时器是一个非常基本的倒计时定时器,用于在每隔一定的时间产生一个中断,即使是系统在睡眠模式下也能工作。它使得 OS 在各 CM3器件之间的移植中不必修改系统定时器的代码,移植工作一下子容易多了。 SysTick定时器也是作为 NVIC 的一部分实现的。

相关寄存器
SysTick控制及状态寄存器(地址:0xE000_E010) —》这个寄存器当中的第 16 位
SysTick重装载器(地址:0xE000_E014)
SysTick当前数值寄存器(地址:0xE000_E018)
SysTick校准数值寄存器(地址:0xE000_E01C)

头文件:
#ifndef __SYSTICK_H
#define __SYSTICK_H

//头文件
#include “stm32f4xx.h” //这个头文件一定要留

void SysTick_Init(void);//时钟源初始化

void Time_us(int nus);//微秒计数

void Time_ms(int nms);//毫秒计数

void Time_s(int ns);//秒计数

#endif

源代码:
#include “sysTick.h”

int my_us = 0;
int my_ms = 0;

void SysTick_Init(void)
{
//初始化滴答定时器的时钟源 8分频 168/8=21MHz = 1/21us
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
my_us = 21;
my_ms = 21*1000;
}

//微秒延时,nus最大值:798915
void Time_us(int nus)
{
//设置重装载数值
SysTick->LOAD = nus*my_us;
//设置当前数值为0
SysTick->VAL = 0x00;
//开始计时
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;

int temp=0;


do {
	
	temp = SysTick->CTRL;
	
}while(!(temp & (1<<16)));

//关闭计时
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL = 0x00;

}

//毫秒延时,nus最大值:798.915
void Time_ms(int nms)
{
//设置重装载数值
SysTick->LOAD = nms*my_ms;
//设置当前数值为0
SysTick->VAL = 0x00;
//开始计时
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;

int temp=0;
do {
	temp = SysTick->CTRL;
}while(!(temp & (1<<16)));

//关闭计时
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
SysTick->VAL = 0x00;

}

void Time_s(int ns)
{
for(;ns>0;ns–)
{
Time_ms(500);
Time_ms(500);
}
}

### STM32 SysTick滴答定时器使用教程 #### 介绍 SysTick 是 ARM Cortex-M 系列处理器中的一个简单易用的倒计数定时器,广泛应用于嵌入式系统中作为时间基准。该定时器包含四个主要寄存器用于配置和监控其行为[^1]。 #### 主要特性 - **24位递减计数器**:当计数值达到零时触发中断并重新加载预设值。 - **灵活的时间间隔设置**:支持从几微秒到几百毫秒不等的各种延迟需求。 - **低开销实现精准延时功能**:相比其他硬件定时器更加高效地利用 CPU 资源[^3]。 #### 初始化过程 为了初始化 SysTick 定时器,在程序启动阶段通常会调用 `delay_init()` 函数来计算不同单位时间内所需的滴答次数,并关闭外部时钟源以便于后续调整[^4]: ```c void delay_init(){ SysTick->CTRL &= ~(1<<2); // 关闭外设时钟 fac_s = SystemCoreClock / 8; // 计算每秒钟对应的 Systick 数量 fac_ms = fac_s / 1000; // 每毫秒对应多少次 Systick 中断 fac_us = fac_ms / 1000; // 每微秒对应多少次 Systick 中断 } ``` 上述代码片段展示了如何基于当前系统的主频 (`SystemCoreClock`) 来确定每一秒、每一毫秒以及每一微秒所经历的具体滴答数目。这里假设每次溢出产生的事件频率大约为主频除以八的结果。 #### 延迟函数设计 通过设定合适的重装载值 (RELOAD),可以精确控制等待多久才会发生下一次中断请求 IRQ 或者单纯依靠轮询方式查询是否已经到达目标时刻。下面给出了一种常见的微秒级延迟算法实现方法: ```c // 微秒级别延时函数定义 void delay_us(u32 nus){ u32 temp; SysTick->LOAD=nus*fac_us; // 设置比较匹配值 SysTick->VAL=0x00; // 清空当前计数值 SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ; // 开启计数 do{ temp=SysTick->CTRL; }while((temp&0x01)&&!(temp&(1<<16))); // 判断是否已过期 SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;// 关闭计数 SysTick->VAL=0X00; // 清空计数器 } ``` 此部分实现了对指定时间段内的阻塞型等待逻辑,其中涉及到几个重要的操作步骤: - 配置 LOAD 寄存器为期望经过的时间长度; - 将 VAL 设定成初始状态(通常是全清零); - 启动控制器开始向下计数直至归零; - 不断循环检测直到满足条件为止; - 最终停止计数并将内部变量复原至默认态。 #### 应用场景举例 除了基本的软件延时之外,SysTick 还经常被用来充当 RTOS 的调度依据或是驱动某些周期性的任务执行,如 LED 流水灯效果展示、传感器数据采集等场合均可见其身影。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值