浅析STM32 Systick查询定时的处理过程

电子说

1.3w人已加入

描述

STM32处理器有一个24位的系统滴答定时器SysTick,它从重新加载值开始倒数到0,然后在下一个时钟边缘重新加载(包装到)STK_LOAD寄存器中的值,然后在随后的时钟上倒数。

led灯

计数标志位COUNTFLAG在系统控制和状态寄存器STK_CTRL的16位,当计时器减计数到0时,返回1。

时钟源选择位CLKSOURCE在系统控制和状态寄存器STK_CTRL的2位,赋值为0时为8分频,赋值为1时为1分频。想要计数速度更快可以选择1分频的时钟源。

SysTick异常请求允许位TICKINT在系统控制和状态寄存器STK_CTRL的1位,赋值为0时禁止异常请求,赋值为1时允许异常请求。软件可以使用COUNTFLAG来判断SysTick是否曾经被计数为零。

计数使能位在系统控制和状态寄存器STK_CTRL的0位,赋值0时禁止计数,赋值1时使能计数。

led灯

重装载值RELOAD在SysTick重载值寄存器STK_LOAD的0~23位,加载寄存器指定在启用计数器时和计数器达到0时加载到当前值寄存器STK_VAL的起始值。

led灯

当前的计数器值CURRENT在当前值寄存器STK_VAL的1~23位。前值寄存器STK_VALSysTick计数器的当前值。读取返回SysTick计数器的当前值。任何值的写入都会将字段清除为0,并将STK_CTRL寄存器中的COUNTFLAG位清除为0。

查询us、ms延时函数

void Systick_Delayus(u32 us)
{
  SysTick- >CTRL &=~ (1< < 2);                   //选择时钟源,8分频 
  SysTick- >LOAD  =  21*us - 1;                //赋值装载值
  SysTick- >VAL   =    0;                      //清除当前值
  SysTick- >CTRL  |=  1< < 0;                    //使能计数器
  while((SysTick- >CTRL  &  (1< < 16)) == 0);    //判断计数是否结束
  SysTick- >CTRL  &=~  (1< < 0);                 //禁止计数器
}
void Systick_Delayms(u16 ms)
{
  Systick_Delayus(ms * 1000);
}

led灯

从时钟树可以知道,系统时钟168Mhz,8分频后得到滴答定时器时钟为21Mhz,装载值(需要延时时间)可根据时钟频率计算求得,每秒可计数21000000次,每微秒可计数21次。装载值和当前值都是24位,最大为16777215,最大微秒定时798915us,最大毫秒定时798ms。

结合LED灯和Systick定时让LED灯500ms闪烁一次,主函数为

#include "stm32f4xx.h"
#include "led.h"
#include "delay.h"


int main()
{
  LED_Init();              //初始化LED灯

  while(1)                //点亮或熄灭LED灯
  {
    GPIOH- >ODR      &=~    (0x01< < 10);      //输出为0,led灯亮
    GPIOH- >ODR      &=~    (0x01< < 11);      //输出为0,led灯亮
    Systick_Delayus(500000);
    GPIOH- >ODR      |=    (0x01< < 10);      //输出为1,led灯灭
    GPIOH- >ODR      |=    (0x01< < 11);      //输出为1,led灯灭
    Systick_Delayms(500);
  }
}

编译成功后将程序烧入,LED每500ms闪烁一次,Systick查询定时成功。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分