目录
STM32中SysTick系统滴答定时器用于延时功能的实现及说明
delay.h文件
delay.c文件
STM32中SysTick系统滴答定时器用于延时功能的实现及说明
在进行stm32开发的过程中,我们可能会使用到系统滴答定时器SysTick进行延时。系统滴答定时器是一个24位的向下倒计时的定时器。它主要有四个寄存器:重装载值寄存器LOAD、当前值寄存器VAL、控制寄存器CTRL和校准寄存器CALIB(校准寄存器一般不使用)。以下是系统滴答定时器用于延时操作的相关代码实现及说明。(这里只是在没有操作系统OS的驱动代码中使用,在有操作系统OS的代码中,SysTick系统滴答定时器可能作为操作系统的时基时钟使用。并且操作系统OS往往已经提供了相关的延时函数,直接调用操作系统提供的函数即可)
delay.h文件
#ifndef __DELAY_H #define __DELAY_H void delay_init(void); void delay_ms(u16 ms); void delay_us(u32 us); #endif
=================================分割线================================
delay.c文件
#include "delay.h" static u8 fac_us = 0; //微秒级延时系数 static u16 fac_ms = 0; //毫秒级延时系数//初始化延迟函数 void delay_init() {SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //使用外部时钟 fac_us = SystemCoreClock / 8000000; //微秒对应的tick数 fac_ms = (u16)fac_us * 1000; //毫秒对应的tick数 } 说明:对于F103系列芯片来说系统时钟为72MHz,而滴答定时器的时钟为HCLK的8分频,即是9MHz。那么可以知道滴答定时器的计数器每减9次,时间为1微秒。每减9000次时间为1毫秒。(1MHz的时钟频率计数器每加1或者减1的时间为1us)因此微秒系数fac_us = 9,fac_ms = 9000。 //微秒级延时函数 void delay_us(u32 us) { u32 temp; SysTick->LOAD = us * 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; //清除COUNTFLAG计时完成标志位 } 说明:对于系统滴答定时器的使用一般为以下步骤:1、将重装载值赋给LOAD寄存器,对于微秒延时重装载值就是延时系数乘以延时时间2、将当前值寄存器VAL清零3、启动定时器进行计时4、等待计时时间到关闭定时器5、清除计时完成的标志位COUNTFLAG关于清除COUNTFLAG标志位,可以等计时完成后直接读取控制寄存器CTRL的第16位进行清除;也可以通过写当前值寄存器VAL来进行清除。do{temp = SysTick->CTRL;}while((temp & 0x01) && !(temp & (1<<16))); 这个语句中(temp & 0x01)首先确保定时器是处于打开状态。(temp & (1<<16)用来判断标志位COUNTFLAG是否为1,当计时时间到后标志位COUNTFLAG会自动置1。由于这里是do--while循环,因此当计时时间未到时,标志位COUNTFLAG一直为0,也即是(temp & (1<<16)为0,取反后为1表示真,以上条件都成立,则继续执行do语句里的内容(继续查询COUNTFLAG标志位的状态)。//毫秒级延时函数 void delay_ms(u16 ms) { u32 temp; SysTick->LOAD = (u32)ms * fac_ms; //时间加载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; //清除COUNTFLAG计时完成标志位 } 注意:由于滴答定时器的重装载值寄存器LOAD和当前值寄存器都是24位的,因此延时的时间是有上限的。最大延时时间为2^24 - 1 = 16777215,对于微秒级延时每减9次为1us,因此最大延时时长为:16777215 / 9 ---1864135us = 1864.135ms = 1.864s。在使用滴答定时器进行延时时不能超过以上的最大延时时间。