找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4656|回复: 2
打印 上一主题 下一主题
收起左侧

关于CortexM3/M4 SysTick定时器的理解(STM32F4例子)

[复制链接]
跳转到指定楼层
楼主

     stm32内核里面有一个很棒的定时器,可以在不占用CPU资源呢的前提下,完成定时的功能。从51单片机过来的时候,使用延时的办法就是CPU一直进行空语句的执行,即for(i=100;i>0;i--)。这样进行延时的办法,在初学阶段是比较好用的,但是深入学习到UCOSII/III这种操作系统之后,这种简单的延时,就只会占用CPU。让该运转的指令得不到及时的执行。(定时器也可以解决这个问题,但是CortexM3/M4内核里面有这个玩意,自然要用上)为了解决这种问题,SysTick定时器应运而生。
    SysTick定时器的内容在《Cortex M3与M4权威指南》里面才被提到,而《STM32F4xx英文参考手册》里面却没有。作者也是看《Cortex M3与M4权威指南》学习的。只需要掌握关于 SysTick里面的3个寄存器,即可随心所欲的使用延时功能啦。
我先将这几个定时器贴出来:


  • SysTick->CTRL  :  SysTick Control and Status Register(systick控制与状态寄存器)
  • SysTick->LOAD SysTick Reload Value Register (systick 重装装载值寄存器)
  • SysTick->VAL SysTick Current Value Register(systick当前值寄存器)
(51过来的同学,systick定时器和51的定时0差不多的理解  (The counter inside the SysTick is a 24-bit decrement counter)SysTick内部的计数器是一个24位递减计数器 。只需要将SysTick从一数到零需要多少时间弄明白即可。
systick定时器初始化
  1. static u8  time_us=0;    //用来存储定时1us需要计数个数     
  2. static u16 time_ms=0;                                                        //用来存储定时1ms需要计数个数     
  3.         
  4. void systick_init(void)
  5. {
  6.          SysTick->CTRL &=~(1<<2);    // 8分频     选择将系统时钟进行8分频  168M/8 = 21M 这个意思就是systick定时器从1->0数一下需要1/21us
  7.         time_us=21;                             //168/8      延时1us需要计数21次               
  8.         time_ms=(u16)time_us*1000;                //        延时1ms需要计数21*1000次                        
  9. }
复制代码
举个例子,如果我们想要延时100us  那么 以systick_init();  进行初始化 我们只需要将计数次数计算出来 count =  time_us * 100us  再将count装载进如systick->load 寄存器里面就可以,然后开启定时器 ,判断是否从count数到0,如果没有,继续检测,反之,则退出,并关闭定时器。即可以完成定时的功能。(不需要systick定时中断)
延时1us代码
  1. //最小延时1us
复制代码






延时1ms代码

  1. /*
  2.         u16 t_ms 最大为65535  
  3.                 65535 * 2100  = 1376235000 >> 16777216超出24位寄存器的值
  4.         在不超出 24位寄存器的前提下 t_ms最大为 16777216/2100 = 798.9150476
  5.         也就是最大延时 798.9150476ms
  6. */
  7. void systick_delay_ms(u16 t_ms)
  8. {
  9.         u8 res = 0;
  10.         SysTick->LOAD = t_ms * time_ms; //SysTick->LOAD 24位的寄存器 最大值是16777216
  11.         SysTick->CTRL |= 1<<0;                        //打开滴答定时器
  12.         SysTick->VAL = 0;
  13.         do { res = (u8)(SysTick->CTRL>>16); }while(!(res&1)); //判断延时是否结束的标志
  14.         SysTick->CTRL &= ~(1<<0);      //关闭滴答定时器
  15. }
复制代码






systick_delay_ms这个函数最大只能延时
798.9150476ms,如果我们想要延时更多的时间,我们怎么办? 最通俗的办法就是systick_delay_ms(500);systick_delay_ms(500);这样即可。请看代码

  1. /*获取更多延时
  2. 思想就是:重复几次 systick_delay_ms这个函数(最大延时 798.9150476ms)
  3.   获取更多延时*/        
  4. void delay_100ms(u8 t_100ms)
  5. {
  6.         u8 res = 0;
  7.         while(t_100ms--)
  8.         {
  9.                 SysTick->LOAD = time_ms * 100; //100ms需要的节拍数
  10.                 SysTick->CTRL |= 1<<0;                        //打开滴答定时器
  11.                 SysTick->VAL = 0;
  12.                 do { res = (u8)(SysTick->CTRL>>16); }while(!(res&1)); //判断延时是否结束的标志
  13.         }
  14. }
复制代码
void delay_100ms(u8 t_100ms)  这个函数还是有问题的,就是我们想要延时更长时间,同时也想要把这个函数延时时间降到100ms以内,这样的话,那么这个函数就做不到啦,于是继续改呗,怎么才能延时更长的时间,而减小间隔呢?
  1. void delay_ms(u16 t_ms)
  2. {
  3.         u8 t_l = t_ms%255;
  4.         u8 t_h = t_ms/255;
  5.         while (t_h--)
  6.         {
  7.                 systick_delay_ms(255);
  8.         }
  9.         if(t_l)  systick_delay_ms(t_l);
  10. }
复制代码
关于systick定时器的学习,就到这里啦。我自己本身还是有很多不足的,其实关于STM32F4的时钟频率是需要配置的,才能为168M。如果没有将这些宏定义改为下面的,时钟频率不为168Mhz,就达不到你想要的延时时间了。
system_stm32f4xx.c  文件     宏定义PLL_M  改为8   即: #define PLL_M      8  uint32_t SystemCoreClock = 168000000;
stm32f4xx.c 文件                                                  即: #define HSE_VALUE    ((uint32_t)8000000)
学无止境,继续努力
代码工程奉上!

全部资料51hei下载地址:
STM32F407 systick 定时器延时.zip (454.94 KB, 下载次数: 32)



评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:256945 发表于 2021-4-3 17:39 | 只看该作者
你这个示波器是什么软件啊
回复

使用道具 举报

板凳
ID:245784 发表于 2021-6-28 09:48 | 只看该作者
夜空之巅 发表于 2021-4-3 17:39
你这个示波器是什么软件啊

这是逻辑分析仪,上位机软件。某一个宝几十块钱的。。不好意思,好久没上这个帐号了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表