STM32F407VET6 基于滴答定时器实现精确延时功能
在这个实验中,我们基于滴答定时器实现精确延时功能,当然想要实现精确的延时功能也不一定非得使用滴答定时器,使用其它定时器一样可以实现,其实现的原理是一样的。这里我们虽然借用了滴答定时器,但是不占用滴答定时器的中断,只是不断的去读取滴答定时器的寄存器,从而实现延时功能。如果想要在项目中移植实时操作系统,下面的延时功能代码也无需做什么改变,同时也不会对系统内核产生影响(注:这里的不会影响是基于大部分系统的时钟节拍为1ms)。
代码如下:
#include "stm32f4xx.h"
#include "delay.h"
#include "delay.h"
/********************************************************
* 函数功能:初始化滴答定时器
* 形 参:无
* 返 回 值:无
********************************************************/
void systick_init(void)
{
// Reload为24位寄存器,最大值:16777216,在168M下,约合0.0998s左右
SysTick->LOAD = SystemCoreClock / 1000UL; // 配置中断时间为1ms
SysTick->CTRL |= SysTick_CLKSource_HCLK; // 内部时钟配置为168MHz
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 开启SYSTICK
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; // 开启SYSTICK中断
}
* 函数功能:初始化滴答定时器
* 形 参:无
* 返 回 值:无
********************************************************/
void systick_init(void)
{
// Reload为24位寄存器,最大值:16777216,在168M下,约合0.0998s左右
SysTick->LOAD = SystemCoreClock / 1000UL; // 配置中断时间为1ms
SysTick->CTRL |= SysTick_CLKSource_HCLK; // 内部时钟配置为168MHz
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; // 开启SYSTICK
SysTick->CTRL |= SysTick_CTRL_TICKINT_Msk; // 开启SYSTICK中断
}
/********************************************************
* 函数功能:使用滴答定时器做的微秒级延时函数(强阻塞)
* 形 参:nus:延时时间,单位:微秒
* 返 回 值:无
********************************************************/
void delay_us(unsigned short nus)
{
unsigned int wait_time = 0UL;
unsigned int check_time = 0UL;
unsigned int start_time = SysTick->VAL; // 计数器值
unsigned int total_time = (SystemCoreClock / 1000000UL) * nus;
// 注:SysTick是一个递减的计数器
while(wait_time < total_time)
{
start_time = check_time;
check_time = SysTick->VAL;
if(check_time < start_time)
{
wait_time += start_time - check_time;
}
else if(check_time > start_time)
{
wait_time += SysTick->LOAD - check_time + start_time;
}
}
}
while(wait_time < total_time)
{
start_time = check_time;
check_time = SysTick->VAL;
if(check_time < start_time)
{
wait_time += start_time - check_time;
}
else if(check_time > start_time)
{
wait_time += SysTick->LOAD - check_time + start_time;
}
}
}
/********************************************************
* 函数功能:使用滴答定时器做的毫秒级延时函数(强阻塞)
* 形 参:nms:延时时间,单位:毫秒
* 返 回 值:无
********************************************************/
void delay_ms(unsigned short nms)
{
delay_us((unsigned int)(nms * 1000UL));
}
不但要知其然,还要知其所以然