[STM32F1] STM32 SysTick---系统滴答定时器

[复制链接]
1304|16
 楼主| huangcunxiake 发表于 2018-3-6 17:31 | 显示全部楼层 |阅读模式
一、Systick简介
    Systick也叫系统滴答定时器,滴答定时器就是一个非常基本的倒计时定时器。它存在的意义是为系统提供一个时基,能够给操作系统提供一个硬件上的中断。使用Systick能够精准延时,对于时间要求严格的场所,意义十分重大,我将写一个流水灯改进版----精确延时(可调控)的流水灯。
二、Systick timer
    Systick是一个24位的定时器,一次最多可以计数2^24个时钟脉冲,这个脉冲计数值保存在当前计数值寄存器STK_VAL(Systick current value register)中,只能向下计数,每接收到一个时钟脉冲,STK_VAL的值就会向下减1,当减到0时,硬件会自动把重装载寄存器STK_LOAD(Systick reload value register)中保存的数据加载到STK_VAL,重新开始向下计数。如果STK_VAL的值被减至0时,会触发异常产生中断。

 楼主| huangcunxiake 发表于 2018-3-6 17:32 | 显示全部楼层
三、相关寄存器介绍
除了上面说的STK_VAL,下面带大家了解相关的寄存器和寄存器位。
1.  SysTick_CSR       控制状态寄存器

472716434113603.jpg
472716454145263.jpg
Bit0: ENABLE
          SysTick timer的使能位,1使能Systick timer,0关闭Systick timer
Bit1: TICKINT
          异常触发使能位,TICKINT=1,STK_VAL计数到0触发异常;TICKINT=0,不触发异常
Bit2: CLKSOURCE
          Systick时钟选择位,SysTick = 1,时钟为AHB时钟;0时钟位AHB/8
Bit16:COUNTFLAG
          计数为0标志位, 当STK_VAL计数到0,此标志位会被置1      


2. SysTick_LOAD      重装载寄存器

47271646415130.jpg
0-23 24位的重装值,这也是为什么只能计数到2^24
3.  SysTick_VAL    当前值寄存器

472716464169747.jpg


4.  SysTick_CALRB    校准寄存器
472716464145151.jpg

由于我们要写精确延时的LED流水灯,所以我们需要使用Systick进行精确延时,理论上它的最小计时单位为AHB的时钟周期,1/72000000秒,72分之一微秒。

 楼主| huangcunxiake 发表于 2018-3-6 17:33 | 显示全部楼层
我们在昨天流水灯的基础上,新建两个文件,SysTick.c和SysTick.h
具体代码如下
SysTick.h
  1. #ifndef __SYSTICK_H__
  2. #define __SYSTICK_H__
  3. #include "stm32f10x.h"
  4. void SysTick_Init(void);
  5. void Delay_us(__IO u32 nTime);
  6. #endif

SysTick.c
  1. #include "SysTick.h"
  2. #include "stm32f10x.h"
  3. static __IO u32 TimingDelay;
  4. void SysTick_Init(void)
  5. {
  6. if(SysTick_Config(SystemCoreClock/100000))
  7. {
  8.   while(1);
  9. }
  10. //关闭滴答定时器
  11. SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
  12. }
  13. void TimingDelay_Decrement(void)
  14. {
  15. if(TimingDelay != 0x00)
  16. {
  17.   TimingDelay--;
  18. }
  19. }
  20. void Delay_us(__IO u32 nTime)
  21. {
  22. TimingDelay = nTime;

  23. //使能滴答定时器
  24. SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;

  25. while(TimingDelay != 0);
  26. }
 楼主| huangcunxiake 发表于 2018-3-6 17:34 | 显示全部楼层
中断函数,在stm32f10xit.c
  1. void SysTick_Handler(void)
  2. {
  3. TimingDelay_Decrement();
  4. }

修改main.c如下
  1. #include "stm32f10x.h"
  2. #include "led.h"
  3. #include "SysTick.h"


  4. int main(void)
  5. {
  6. //LED端初始化
  7. LED_GPIO_Config();

  8. //配置SysTick为10us中断一次
  9. SysTick_Init();

  10. while(1)
  11. {
  12.   LED1(0);
  13.   Delay_us(50000);
  14.   LED1(1);
  15.   
  16.   LED2(0);
  17.   Delay_us(50000);
  18.   LED2(1);
  19.   
  20.   LED3(0);
  21.   Delay_us(50000);
  22.   LED3(1);
  23.   
  24.   LED4(0);
  25.   Delay_us(50000);
  26.   LED4(1);
  27. }
  28. }
 楼主| huangcunxiake 发表于 2018-3-6 17:34 | 显示全部楼层
这里面只有两个函数,SysTick_Init()和Delay_us(),一个是配置SysTick定时器,一个是进行精确延时
中断函数也只是运行了一个自定义函数,看看不难理解
SysTick_Config(SystemCoreClock/100000);
SystemCoreClock是系统时钟的宏,SystemCoreClock = 72000000
我们的计时总时间 T = tick * (1/f),tick为SysTick_Config()的输入参数

1/f为SysTick timer使用的时钟源的时钟周期,f为该时钟源的时钟频率。
上面的语句中:tick = SystemCoreClock/100000=720,表示720个时钟周期中断一次,1/f是时钟周期的时间,1/f = 1/72us,所以T = 720*(1/72) = 10us
SysTick_CTRL_ENABLE_Msk,这是一个宏,用来指示寄存器的特定位置或进行位屏蔽用的,那么他是如何定义的呢?
472716474165177.jpg

其中的寄存器位指示宏:SysTick_xxx_Pos, 宏展开后为xxx在相应寄存器中的位置,如控制SysTick时钟源的SysTick_CTRL_CLKSOURCE_Pos,宏展开后为2,正好是SysTick_CSR中的Bit2
寄存器的位屏蔽宏:SysTick_xxx_Msk,宏展开是xxx的位全部置1后,左移SysTick_xxx_Pos位,1ul使之无符号长整型,上图中SysTick_CTRL_CLKSOURCE_Msk,宏展开为1ul<<systick_ctrl_clksource_pos,即1左移2位,得到的只有bit2:clksource位被置1,而其它位为0,这样搭配& |="" 能够很方便的修改寄存器的某些位,这样就程序就不难理解了.就说这么多吧,已经讲得很多了,不懂得自己想想,琢磨一下就通了。[="" size][="" font][="" backcolor][="" color]

xixi2017 发表于 2018-3-7 19:37 来自手机 | 显示全部楼层
这个玩意儿定时范围是多少
aizaixiyuanqian 发表于 2018-3-7 20:59 | 显示全部楼层
还挺详细,不错
quickman 发表于 2018-3-8 17:09 | 显示全部楼层
SysTick定时器被捆绑在NVIC中
jstgotodo 发表于 2018-3-8 17:09 | 显示全部楼层
移植系统产生时间片伦的定时器。
iamaiqiyi 发表于 2018-3-8 17:10 | 显示全部楼层
以前使用这个中断确实不错。
dzfansman 发表于 2018-3-8 17:10 | 显示全部楼层
huangcunxiake 发表于 2018-3-6 17:32
三、相关寄存器介绍
除了上面说的STK_VAL,下面带大家了解相关的寄存器和寄存器位。
1.  SysTick_CSR       ...

如何操作Systick定时器
sanxingnote7 发表于 2018-3-8 17:11 | 显示全部楼层
systic中断间隔时间不好跳转吧
quickman 发表于 2018-3-8 17:13 | 显示全部楼层
用于产生SYSTICK异常
jstgotodo 发表于 2018-3-8 17:13 | 显示全部楼层
这个看着高端了。
iamaiqiyi 发表于 2018-3-8 17:13 | 显示全部楼层
等于变相多出一个定时器。
sanxingnote7 发表于 2018-3-8 17:13 | 显示全部楼层
以前分配之后的中断速度慢了很多,是不是时钟有问题呢
dzfansman 发表于 2018-3-8 17:13 | 显示全部楼层
huangcunxiake 发表于 2018-3-6 17:32
三、相关寄存器介绍
除了上面说的STK_VAL,下面带大家了解相关的寄存器和寄存器位。
1.  SysTick_CSR       ...

周期的配置怎么实现的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

223

主题

3745

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部