STM32
直播中

向日葵的花季

8年用户 1186经验值
擅长:电源/新能源
私信 关注
[问答]

关于stm32系统滴答定时器的基本知识都总结在这里

什么是系统滴答定时器呢?

系统滴答定时器的内部结构是如何构成的?


回帖(1)

吴银红

2021-11-24 09:52:05
  1、系统滴答定时器的概述
  滴答定时器又称 SysTick,有两个时钟源,一个为内部时钟,一个为外部时钟。滴答定时器是一个 24 位倒计
  数的定时器,从预装载值一直到 0,重装载寄存器的值会自动装载到计数寄存器中。 只要不把它使能位清除,那
  么它就永远不停,即使在芯片在睡眠模式下也能工作。
  2、滴答定时器的内部框图
  
  系统滴答定时器的是一个倒计数计数器,作用是:通过计数来定时。常用于:①操作系统的心跳时钟。②裸机代码中的简单定时。
  STM32F407ZGT6的系统滴答定时器的计数频率为21MHZ或者为168MHZ。系统滴答定时器控制器有一个“自动重装载寄存器”,该寄存器是24位有效。
  举例:假如系统滴答定时器的计数频率设置为21MHZ,定时1ms,需要计数21000,则将该值写入“自动重装载寄存器”。然后系统滴答定时器还有一个“当前值寄存器”,“当前值寄存器”加载“自动重装载寄存器”中的值,在每个时钟节拍下,“当前值寄存器”的置递减,递减到0,则定时时间到。
  3、相关寄存器
  详细资料在《Cortex M3 与 M4 权威指南》第 315 页
  3.1、控制及状态寄存器(SysTick_CTRL)
  
  
  举例:将滴答定时器的计数频率设置为21MHZ,禁止产生滴答中断,使能滴答定时器,如何配置?
  SysTick-》CTRL &=~(1《《2);
  SysTick-》CTRL &=~(1《《1);
  SysTick-》CTRL |= (1《《0);
  3.2、自动重装载数据寄存器(SysTick_LOAD)
  
  只有低 24 位有效,数值有效范围为 0-(2^24-1)。 当 SysTick 定时器倒计数到 0 时,该寄存器的值就会把计
  数初始值重新加载到计数器中工作。
  举例1:将滴答定时器的计数频率设置为21MHZ,禁止产生滴答中断,使能滴答定时器,定时时间为1us,如何配置?
  答1:
  SysTick-》CTRL &=~(1《《2);
  SysTick-》CTRL &=~(1《《1);
  SysTick-》LOAD = 0; //清零
  SysTick-》LOAD = 21; //计21次为1us
  SysTick-》CTRL |= (1《《0);
  举例2:将滴答定时器的计数频率设置为21MHZ,禁止产生滴答中断,使能滴答定时器,最大定时时间是多少?
  重装载数值寄存器的最大值是16777215,则最大定时时间是:(1/21000000)*16777215 = 0.798915秒。
  3.3、当前值寄存器(SysTick_VAL)
  
  这个寄存器同样只有低 24 位有效, SysTick 定时器倒计数寄存器。读取时返回当前倒计数的值,对这个寄存
  器进行写操作,则使之清零,并对到零标志位清零。
  3.4. 设置延迟时间
  由上面寄存器可知,定时器计数的周期为 SysTick-LOAD 寄存器的值和选择的时钟源有关。例如:选择时钟频
  率为 24MHz 的时钟,即周期为 1/24000000s,所以假如要实现定时 1s,则需要设置装载值为 24000000(1s=
  (1/24000000) *24000000)。同理可得 1ms 需要设置装载值为 21000, 1us 需要设置装载值为 21。
  4、软件设计
  寄存器
  #include “stm32f4xx.h”
  void delay_ms(int ms)
  {
  SysTick-》CTRL &=~(1《《2);//选择时钟源为21MHZ
  SysTick-》CTRL &=~(1《《1);//禁止滴答中断
  SysTick-》LOAD = 21000*ms; //设置重装载寄存器的值
  SysTick-》CTRL |= (1《《0);//使能滴答定时器
  while(!(SysTick-》CTRL&(1《《16)));//阻塞判断定时时间是否到达,判断SysTick-》CTRL的位
  }
  int main(void)
  {
  LED_Init();
  while(1)
  {
  GPIOF-》ODR |= (1《《6);//GPIOF_ODR的位6置1则输出高电平
  Delay_ms(500);//延时500ms
  GPIOF-》ODR &= ~(1《《6);//GPIOF_ODR的位6清零则输出低电平
  Delay_ms(500);//延时500ms
  }
  }
  void delay_s(int s)
  {
  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK); //选择时钟
  SysTick-》VAL =0;
  SysTick-》LOAD =s*24000000; //设置预装载值
  SysTick-》CTRL =1; //使能滴答定时器
  while(!(SysTick-》CTRL &(1《《16))); //等待计数完成
  SysTick-》CTRL =0; //失能滴答定时器
  }
  void delay_ms(int ms)
  {
  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
  SysTick-》VAL =0;
  SysTick-》LOAD =ms*24000;
  SysTick-》CTRL =1;
  while(!(SysTick-》CTRL &(1《《16)));
  SysTick-》CTRL =0;
  }
  void delay_us(int us)
  {
  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
  SysTick-》VAL =0;
  SysTick-》LOAD =us*24;
  SysTick-》CTRL =1;
  while(!(SysTick-》CTRL &(1《《16)));
  SysTick-》CTRL =0;
  }
  int main(void)
  {
  LED_Init();
  while(1)
  {
  GPIO_SetBits(GPIOF,GPIO_Pin_9);
  delay_s(2);
  GPIO_ResetBits(GPIOF,GPIO_Pin_9);
  delay_s(2);
  }
  }
举报

更多回帖

发帖
×
20
完善资料,
赚取积分