源码
delay.h
#ifndef __DELAY_H
#define __DELAY_H
#include "main.h"
void delay_init(uint8_t SYSCLK);
void delay_ms(uint16_t nms);
void delay_us(uint32_t nus);
#endif
delay.c
#include "delay.h"
static uint32_t fac_us=0; //us延时倍乘数
//初始化延迟函数
//SYSTICK的时钟固定为AHB时钟
//SYSCLK:系统时钟频率
void delay_init(uint8_t SYSCLK)
{
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//SysTick频率为HCLK
fac_us=SYSCLK; //不论是否使用OS,fac_us都需要使用
}
//延时nus
//nus为要延时的us数.
//nus:0~190887435(最大值即2^32/fac_us@fac_us=22.5)
void delay_us(uint32_t nus)
{
uint32_t ticks;
uint32_t told,tnow,tcnt=0;
uint32_t reload=SysTick->LOAD; //LOAD的值
ticks=nus*fac_us; //需要的节拍数
told=SysTick->VAL; //刚进入时的计数器值
while(1)
{
tnow=SysTick->VAL; // 读取 SysTick计数器值
if(tnow!=told) // SysTick计数器值发生变化
{
// 累计节拍数,SYSTICK是一个递减的计数器
if(tnow<told)
{
tcnt+=told-tnow;
}
else
{
tcnt+=reload-tnow+told;
}
told=tnow;
if(tcnt>=ticks)
{
break; //时间超过/等于要延迟的时间,则退出.
}
}
}
}
//延时nms
//nms:要延时的ms数
void delay_ms(uint16_t nms)
{
uint32_t i;
for(i=0;i<nms;i++)
{
delay_us(1000);
}
}
main.c
#include "delay.h"
delay_init(72); // 初始化延时函数,参数为主频MHZ
delay_ms(1); // 延时1ms
delay_us(1); // 延时1us
解析
void delay_init(uint8_t SYSCLK);
static uint32_t fac_us=0;
//初始化延迟函数
//SYSTICK的时钟固定为AHB时钟
//SYSCLK:系统时钟频率
void delay_init(uint8_t SYSCLK)
{
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);//SysTick频率为HCLK
fac_us=SYSCLK; //不论是否使用OS,fac_us都需要使用
}
将 滴答定时器(SysTick )时钟源配置为系统时钟(HCLK)。
设置 us延时倍乘数。
void delay_us(uint32_t nus);
//延时nus
//nus为要延时的us数.
//nus:0~190887435(最大值即2^32/fac_us@fac_us=22.5)
void delay_us(uint32_t nus)
{
uint32_t ticks;
uint32_t told,tnow,tcnt=0;
uint32_t reload=SysTick->LOAD; //LOAD的值
ticks=nus*fac_us; //需要的节拍数
told=SysTick->VAL; //刚进入时的计数器值
while(1)
{
tnow=SysTick->VAL; // 读取 SysTick计数器值
if(tnow!=told) // SysTick计数器值发生变化
{
// 累计节拍数,SYSTICK是一个递减的计数器
if(tnow<told)
{
tcnt+=told-tnow;
}
else
{
tcnt+=reload-tnow+told;
}
told=tnow;
if(tcnt>=ticks)
{
break; //时间超过/等于要延迟的时间,则退出.
}
}
}
}
计算需要的节拍数,循环读取 SysTick计数器值,发生变化时进行延时计数累加,达到节拍数后退出循环。
void delay_ms(uint16_t nms);
//延时nms
//nms:要延时的ms数
void delay_ms(uint16_t nms)
{
uint32_t i;
for(i=0;i<nms;i++) delay_us(1000);
}
调用us级延时函数完成ms级延时。