作者:BigBigBigBigPX | 来源:互联网 | 2023-09-12 13:32
3.6节滴答延时实验使用SysTick实现时间戳有时候,我们需要控制程序运行的频率,比如每隔一秒打印一行,这时候需要用到延时函数。本节介绍使用SysTick实现延时。a.实验准备:
3.6节 滴答延时实验使用SysTick实现时间戳
有时候,我们需要控制程序运行的频率,比如每隔一秒打印一行,这时候需要用到延时函数。本节介绍使用SysTick实现延时。
a.实验准备:USB转串口模块,ST-Llink下载器,CHEAPX机器人控制板
b.实验目的:STM32 SysTick实现时间戳
c.相关知识点:
SysTick滴答定时器,内部是一个24 位的倒计数计时器,我们设置计数的频率,就可以根据读取到的计数大小知道时间是多少。
d.编程及运行
(1)初始化SysTick并编写中断。定义三个32位的全局变量_TimeStampH,_TimeStampL分别存储程序运行的多少秒和微秒。
volatile u32 _TimeStampH=0; //单位unit:s
volatile u32 _TimeStampL=0; //单位unit:1/9us
volatile static u32 sysTimeStamp=0; //单位unit:1/9us
void initSysTick(void)
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //8分频,72M/8=9M
SysTick->CTRL|=SysTick_CTRL_TICKINT_Msk; //使能 SYSTICK IR
SysTick->LOAD=9000000; //重装数,最大2^24=16777216
SysTick->VAL =0; //清零
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk; //开启 SYSTICK
}
void SysTick_Handler(void)//SysTick中断函数
{
_TimeStampH++;
}
(2)实现延时函数
void delay_ms(u16 nms)
{
u32 endTime=nms*9000;
if(SysTick->VAL>=endTime)
{
endTime=SysTick->VAL-endTime+4;//4为补偿值,因为执行函数内语句也存在耗时
if(endTime<10)endTime=10;
while(SysTick->VAL>endTime);//每次循环,需要执行一次空语句和一次while判断语句SysTick->VAL>endTime,该过程存在耗时,若endTime太小,可能下一轮判断SysTick->VAL已恢复9000000导致延时出错
}
else
{
endTime=9000000-(endTime-SysTick->VAL);
if(endTime>8999990)endTime=8999990; //保证一定存在 endTime> SysTick->VAL
while(endTime> SysTick->VAL);
if(endTime<10)endTime=10;
while(SysTick->VAL>endTime);//每次循环,需要执行一次空语句和一次while判断语句SysTick->VAL>endTime,该过程存在耗时,若endTime太小,可能下一轮判断SysTick->VAL已恢复9000000导致延时出错
}
}
void delay_us(u16 nus)
{
u32 endTime=nus*9;
if(SysTick->VAL>=endTime)
{
endTime=SysTick->VAL-endTime+4;//4为补偿值,因为执行函数内语句也存在耗时,5,差值为1
if(endTime<10)endTime=10;
while(SysTick->VAL>endTime);//每次循环,需要执行一次空语句和一次while判断语句SysTick->VAL>endTime,该过程存在耗时,若endTime太小,可能下一轮判断SysTick->VAL已恢复9000000导致延时出错
}
else
{
endTime=9000000-(endTime-SysTick->VAL);
if(endTime>8999990)endTime=8999990;//保证一定存在 endTime> SysTick->VAL
while(endTime> SysTick->VAL);
if(endTime<10)endTime=10;
while(SysTick->VAL>endTime);//每次循环,需要执行一次空语句和一次while判断语句SysTick->VAL>endTime,该过程存在耗时,若endTime太小,可能下一轮判断SysTick->VAL已恢复9000000导致延时出错
}
}
(3)主函数
//滴答延时实验
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //PriorityGroupConfig NVIC中断分组设置 组2(2位抢占优先级,2位响应优先级)
initDebugSerial(500000);
initSysTick();
showVersion();//显示版本
while(1)
{
printf("运行时间:%4us\r\n",_TimeStampH);
delay_ms(1000);
}
}
(4)实验结果:
《SLAM机器人基础教程》第三章 单片机与STM32:滴答延时实验使用SysTick实现时间戳