SysTick系统定时器(滴答定时器)是一个递减定时器,24位向下递减
SysTick 包含 4 个 32 位寄存器:
CTRL (控制和状态寄存器) - 地址:0xE000_E010
- 位 0: ENABLE - 使能定时器
- 位 1: TICKINT - 使能中断
- 位 2: CLKSOURCE - 时钟源选择 (0=AHB/8, 1=AHB)
- 位 16: COUNTFLAG - 计数标志 (计数到 0 时置 1)
LOAD (重装载值寄存器) - 地址:0xE000_E014
- 保存当计数器递减到 0 时自动重装载的值
VAL (当前值寄存器) - 地址:0xE000_E018
- 读取当前计数值
- 写入任意值将清零计数器并清除 COUNTFLAG 标志
CALIB (校准值寄存器) - 地址:0xE000_E01C
- 包含参考时钟和校准值信息 (通常不使用)
/**
* @brief 配置SysTick定时器的时钟源
* @param SysTick_CLKSource: 指定SysTick时钟源
* 该参数可以是以下值之一:
* - SysTick_CLKSource_HCLK_Div8: HCLK时钟除以8作为时钟源
* - SysTick_CLKSource_HCLK: HCLK时钟直接作为时钟源
* @retval 无
*/
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)//配置SysTick定时器的时钟源
typedef struct
{
__IO uint32_t CTRL;//CTRL:控制和状态寄存器,用于配置 SysTick 的工作模式、使能计数以及查询计数状态
__IO uint32_t LOAD;// LOAD:设置定时器从哪个值开始计数。重装载值寄存器,设置当计数器递减到 0 时自动重新加载的值
__IO uint32_t VAL; //VAL:当前值寄存器,读取或设置当前计数器的值
__I uint32_t CALIB;//CALIB:校准寄存器,提供与系统时钟相关的校准值
} SysTick_Type;
软件设计流程:
- 设置定时器的时钟源
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)//配置SysTick定时器的时钟源
- 设置重装初始值
加载延时所需的时钟周期数到 LOAD 寄存器
- 清零定时器当前计数器的值确保从零开始
- 使能定时器
- 等待计数完成(查看第16位的值1为读取完成到和定时器使能「只要定时器在运行且计数未完成,就继续循环」)
- 关闭定时器
- 清空当前值
#include "SysTick.h"
static u8 fac_us=0; //us延时倍乘数
static u16 fac_ms=0; //ms延时倍乘数
//初始化延迟函数
//SYSTICK的时钟固定为AHB时钟的1/9
//SYSCLK:系统时钟频率
void SysTick_Init(u8 SYSCLK)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //时钟源
fac_us=SYSCLK/8;
fac_ms=(u16)fac_us*1000;
}
//延时nus
//nus为要延时的us数.
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;
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void delay_ms(u16 nms)
{
u32 temp;
SysTick->LOAD = (u32)nms*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;
}