• 《SLAM机器人基础教程》第三章 单片机与STM32:滴答延时实验使用SysTick实现时间戳


    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
    ",_TimeStampH);
          delay_ms(1000);
        }
        
    }

    (4)实验结果:

  • 相关阅读:
    链接<a href="javascript:void(0)" />
    JS 不定函数参数argument的用法
    java编译期常量
    对于代码设计的思考
    java交集retainAll 和 Sets.intersection 性能比较
    java 递归调整为队列
    前端跨域问题springboot
    guava的map中value转换问题和排序问题
    MAC安装 Office2016
    股市中的资金流入流出
  • 原文地址:https://www.cnblogs.com/Baron-Lu/p/13378493.html
Copyright © 2020-2023  润新知