STM32单片机-SysTick滴答定时器
时间管理是嵌入式系统的关键,而STM32单片机的SysTick定时器就是实现这一功能的核心工具。本文将介绍SysTick定时器的基本原理、配置方法及实际应用案例。SysTick定时器是STM32单片机内核自带的一个系统定时器,主要用于提供系统滴答时钟,为操作系统或任务调度提供时间基准。它是一个24位的倒计数定时器,具有简单易用,高精度,应用广泛特点。在实际应用中,SysTick定时器经常用于操作系
前言
时间管理是嵌入式系统的关键,而STM32单片机的SysTick定时器就是实现这一功能的核心工具。本文将介绍SysTick定时器的基本原理、配置方法及实际应用案例。
SysTick定时器简介
SysTick定时器是STM32单片机内核自带的一个系统定时器,主要用于提供系统滴答时钟,为操作系统或任务调度提供时间基准。它是一个24位的倒计数定时器,具有简单易用,高精度,应用广泛特点。在实际应用中,SysTick定时器经常用于操作系统的时间管理,任务调度,时间测量的场景。
SysTick定时器基本结构
SysTick定时器是一个24位的倒计数定时器,这意味着它从一个设定的值开始倒数,直到数到0。
它的主要组成部分包括:
计数寄存器(SYSTICK_VAL):存储当前的计数值。
重装载寄存器(SYSTICK_RELOAD):存储每次计数的起始值。
控制寄存器(SYSTICK_CTRL):控制定时器的启动、停止、中断等功能。
SysTick定时器配置步骤:
1,设置SysTick定时器的时钟来源
2,设置SysTick定时器的重装初始值
3,清除SysTick定时器当前计数器的值
4,使能SysTick定时器
SysTick定时器代码配置
1,初始化SysTick定时器,选择时钟来源
//全局变量,用于存储微秒和毫秒的倍频系数
u8 time_us;
u16 time_ms;
void SysTick_Init(u8 SYSCLK)
{
// 配置SysTick定时器的时钟源为HCLK的8分频
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
// 计算微秒的倍频系数
time_us = SYSCLK / 8;
// 计算毫秒的倍频系数
time_ms = time_us * 1000;
}
时钟来源为CPU时钟,即HCLK,进行8分频是为了降低SysTick定时器溢出的频率,提高系统的实时性能。将72Mhz的系统时钟进行8分频成9Mhz,此时时钟频率就变成了9Mhz,再根据周期公式:时钟周期 = 1 / 时钟频率,所以9Mhz的时钟周期就约待等于1微秒(us),再根据毫秒与微秒的互换得出1ms = 1000 us;
2,微秒级延时函数
/**
* 微秒级延时函数
* @param us 延时的微秒数
*/
void delay_us(u32 us)
{
u32 temp; // 定义一个临时变量,用于读取SysTick控制寄存器的当前值
// 设置SysTick定时器的重装载值,即定时器计数到0后自动加载的值
SysTick->LOAD = us * time_us;
// 清除当前计数值,让定时器从0开始计数
SysTick->VAL = 0;
// 启动SysTick定时器
// SysTick_CTRL_ENABLE_Msk用于使能SysTick定时器
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
// 等待SysTick定时器计数到0并发生溢出
// 这个循环会一直执行,直到SysTick定时器溢出(COUNTFLAG位被置位)
// 同时确保SysTick定时器是使能状态(ENABLE位为1)
do
{
temp = SysTick->CTRL; // 读取SysTick控制寄存器的当前值
} while ((temp & 0x01) && !(temp & (1 << 16))); // 检查ENABLE位和COUNTFLAG位
// 停止SysTick定时器
// 清除SysTick控制寄存器中的使能位,停止定时器
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
// 清除当前计数值,为下一次使用做准备
SysTick->VAL = 0;
}
首先来讲一下
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
SysTick->CTRL是读取 控制寄存器(SYSTICK_CTRL)的值,然后和SysTick_CTRL_ENABLE_Msk(它的值是0x01)进行按位或运算,将运算的结果写回控制寄存器(SYSTICK_CTRL)中,此时控制寄存器(SYSTICK_CTRL)的值为0x01,这样定时器就被成功启动了。
再来讲一下
do
{
temp = SysTick->CTRL; // 读取SysTick控制寄存器的当前值
} while ((temp & 0x01) && !(temp & (1 << 16)));
temp = SysTick->CTRL;是访问控制寄存器(SYSTICK_CTRL)的值,并将访问的值赋给temp,(temp & 0x01)是将temp的值与0x01进行与运算,运算结果用来检查SysTick定时器是否还在运行。在!(temp & (1 << 16))中,(1 << 16)表示把1向左移16位,然后与temp的第16位进行与运算,最后将该运算结果取反,用来检查SysTick定时器标志位是否为0,标志位为0就继续运行。总结一下,
1. 读取控制寄存器:
temp = SysTick->CTRL; 读取SysTick控制寄存器的当前值,并将其存储在临时变量 temp 中。
2. 检查定时器状态: while ((temp & 0x01) && !(temp & (1 << 16))); :在 while 循环中,检查两个条件:(temp & 0x01) :检查使能位(位0)是否为1,即SysTick定时器是否正在运行。 !(temp & (1 << 16)) :检查SysTick定时器标志位(位16)是否为0,即SysTick定时器是否尚未溢出。
最后来讲一下
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
首先对SysTick_CTRL_ENABLE_Msk(0x01)按位取反,变成0xfe,再与 SysTick->CTRL ,也就是控制寄存器(SYSTICK_CTRL)当前的值进行与运算,并将结果返回控制寄存器(SYSTICK_CTRL),很显然,这时候的控制寄存器(SYSTICK_CTRL)的第0位,也就是使能位为0,即清除使能位,停止定时器。总结一下
3. 清除使能位:由于 ~SysTick_CTRL_ENABLE_Msk 的第0位是0,其他位都是1,按位与运算后, SysTick->CTRL 的第0位(ENABLE位)被清零,其他位保持不变。
4. 停止定时器:使能位被清零后,SysTick定时器停止计数。
3,毫秒级延时函数
/**
* 毫秒级延时函数
* @param ms 延时的毫秒数
*/
void delay_ms(u32 ms)
{
u32 temp; // 定义一个临时变量,用于读取SysTick控制寄存器的当前值
// 设置SysTick定时器的重装载值,即定时器计数到0后自动加载的值
SysTick->LOAD = ms * time_ms;
// 清除当前计数值,让定时器从0开始计数
SysTick->VAL = 0;
// 启动SysTick定时器
// SysTick_CTRL_ENABLE_Msk用于使能SysTick定时器
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
// 等待SysTick定时器计数到0并发生溢出
// 这个循环会一直执行,直到SysTick定时器溢出(COUNTFLAG位被置位)
// 同时确保SysTick定时器是使能状态(ENABLE位为1)
do
{
temp = SysTick->CTRL; // 读取SysTick控制寄存器的当前值
} while ((temp & 0x01) && !(temp & (1 << 16))); // 检查ENABLE位和COUNTFLAG位
// 停止SysTick定时器
// 清除SysTick控制寄存器中的使能位,停止定时器
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
// 清除当前计数值,为下一次使用做准备
SysTick->VAL = 0;
}
总结
SysTick定时器是STM32单片机中不可或缺的一部分,它使得时间控制变得更加容易和可靠。掌握SysTick定时器的使用,将大大提高你在嵌入式系统开发中的效率和项目的可靠性。
更多推荐



所有评论(0)