前言
记录下使用滴答定时器,写Delay延时函数
一、代码
代码如下(示例):
#include "bsp_systick.h" //包含头文件bsp_systick.h
static uint8_t fac_us = 0; //静态变量,微秒基准数
static uint16_t fac_ms = 0; //静态变量,毫秒基准数
void Delay_Init(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); //设置SysTick为CPU时钟源
fac_us = SystemCoreClock / 1000000; //根据CPU时钟计算出1微秒所需的SysTick计数值
//SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //设置SysTick为CPU时钟8分频 72M / 8 = 9M = 9000 000
// fac_us = SystemCoreClock / 8000000; // 72000 000 / 8000 000 = 9次,1S系统计数9M,则系统计数到9,耗时1us
fac_ms = (uint16_t)fac_us * 1000; //根据1微秒所需的计数值计算出1毫秒所需SysTick计数值
}
void Delay_us(uint32_t nus)
{
uint32_t temp;
SysTick->LOAD = nus * fac_us; //设置SysTick的重装值
SysTick->VAL = 0x00; //清空SysTick计数器值
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //开始计时
do
{
temp = SysTick->CTRL; //读取当前SysTick寄存器的状态值
} while((temp & 0x01) && !(temp & (1 << 16))); //指示SysTick计数器计数到0,并且已经完成了计数
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //关闭SysTick定时器
SysTick->VAL = 0x00; //清空SysTick计数器值
}
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864
void Delay_ms(uint16_t nms)
{
uint32_t temp;
SysTick->LOAD = (uint32_t)nms * fac_ms; //设置SysTick的重装值
SysTick->VAL = 0x00; //清空SysTick计数器值
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; //开始计时
do
{
temp = SysTick->CTRL; //读取当前SysTick寄存器的状态值
} while((temp & 0x01) && !(temp & (1 << 16))); //指示SysTick计数器计数到0,并且已经完成了计数
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; //关闭SysTick定时器
SysTick->VAL = 0x00; //清空SysTick计数器值
}
/**
* @brief 秒级延时
* @param xs 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_s(uint32_t xs)
{
while(xs--)
{
Delay_ms(1000);
}
}
总结
这段代码实现了延时功能。通过调用Delay_Init函数,可以初始化系统时钟,并计算出微秒和毫秒基准数。然后通过调用Delay_us和Delay_ms函数,使用SysTick定时器实现所需的微秒和毫秒延时。 SysTick_CLKSourceConfig函数用于选择SysTick计数器的时钟源,可以在本例中表示使用CPU时钟源。间隔一定时长后,可以通过查询SysTick寄存器中的CTRL标志位来判断计时是否结束。