SysTick滴答定时器
一、功能
SysTick定时器是一个简单的定时器,CM3\CM4内核芯片都具备此定时器。SysTick定时器常用来做延时,采用实时系统时则用来做系统时钟。
无论用作延时还是用作系统心跳时钟,不需要太复杂的功能,SysTick即可胜任。
二、实现原理
SysTick定时器是一个24位的倒计数,当倒计数为0时,将从RELOAD寄存器中取值作为定时器的初始值,同时可以选择在这个时候产生中断(异常号:15)。
例如从RELOAD的值为999,那么当倒计数为0时,就会从复位为999继续倒计数。
        只要不把它在SysTick控制及状态寄存器中的使能位清楚,就永不停息,即使在睡眠模式下也能继续工作。
三、SysTick寄存器(在 core_cm3.h 有定义,凡是 M3 内核的单片机都是一样的)
#define SysTick             ((SysTick_Type *)       SysTick_BASE) 
#define SysTick_BASE        (SCS_BASE +  0x0010)
#define SCS_BASE            (0xE000E000) 
typedef struct
{
  __IO uint32_t CTRL;  // 控制及状态寄存器
  __IO uint32_t LOAD;   // 重装载数值寄存器
  __IO uint32_t VAL; // 当前计数数值寄存器
  __I  uint32_t CALIB;  // 校准寄存器
} SysTick_Type;
SysTick->CTRL: (可通过 SysTick_CLKSourceConfig() 函数设置)
COUNTFLAG(16)R: 计数标志位
当SysTick数到0,则该位被硬件置 1,当读取该位时,将被硬件清零
CLKSOURCE(2)R/W: 时钟源设置
1 = 外部时钟源(STCLK) (AHB总线时钟的1/8(HCLK/8))
0 = 内核时钟(FCLK)  (AHB总线时钟的频率(HCLK))
TICKINT(1)R/W: 中断使能位
1 = SysTick 倒数到0时产生 SysTick 异常请求
0 = 数到 0 时无动作
ENABLE(0)R/W: SysTick 定时器使能位
(当中断被使能后,需要关注 void SysTick_Handler(void) 函数)
SysTick_Type->LOAD: (SysTick_Config() 函数会设置该寄存器)
RELOAD(23:0)R/W: 重装载数值寄存器
当SysTick数到0,将被重装载的值
SysTick_Type->VAL: (SysTick_Config() 函数会设置该寄存器)
CURRENT(23:0)R/Wc: 当前计数数值寄存器
读取时返回当前倒计数的值,写它则使之清零,同时还会清除在 SysTick 控制及状态寄存器中的 COUNTFLAG 标志。
四、库函数分析
misc.c
----------------------------------------------------------------------------------
#define SysTick_CLKSource_HCLK_Div8    ((uint32_t)0xFFFFFFFB)
#define SysTick_CLKSource_HCLK         ((uint32_t)0x00000004)
#define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
((SOURCE) == SysTick_CLKSource_HCLK_Div8))
void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
{
  /* Check the parameters */
  assert_param(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
  if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
  {
SysTick->CTRL |= SysTick_CLKSource_HCLK; // 设置 CLKSOURCE 为 1
  }
  else
  {
SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;      // 设置 CLKSOURCE 为 0
  }
}
core_cm3.c
----------------------------------------------------------------------------------
#define SysTick_LOAD_RELOAD_Pos             0                                           
#define SysTick_LOAD_RELOAD_Msk            (0xFFFFFFul << SysTick_LOAD_RELOAD_Pos)
typedef enum IRQn
{
//...
SysTick_IRQn                = -1, 
//...
}IRQn_Type;
#define __NVIC_PRIO_BITS          4
#define SysTick_CTRL_CLKSOURCE_Pos          2                                           
#define SysTick_CTRL_CLKSOURCE_Msk         (1ul << SysTick_CTRL_CLKSOURCE_Pos)          
#define SysTick_CTRL_TICKINT_Pos            1                                           
#define SysTick_CTRL_TICKINT_Msk           (1ul << SysTick_CTRL_TICKINT_Pos)            
#define SysTick_CTRL_ENABLE_Pos             0                                           
#define SysTick_CTRL_ENABLE_Msk            (1ul << SysTick_CTRL_ENABLE_Pos) 
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
  // 设置计数值为 ticks - 1 
  // 原因1:视频说是执行这些代码需要时间,所以减少一个节拍
  // 原因2:我认为是因为 SysTick 的倒计数到 0,例如设置 1000 ,那么范围就应该是 999 ~ 0。
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;     
  // 设置中断优先级
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); 
  SysTick->VAL   = 0;                                
  // 设置时钟源为外部时钟源,同时开启中断、并使能 SysTick 定时器
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
   SysTick_CTRL_TICKINT_Msk   | 
   SysTick_CTRL_ENABLE_Msk;                   
  return (0);                                                 
}
五、延时应用
1、中断方式
static __IO uint32_t TimingDelay;
void Delay(__IO uint32_t nTime)
   TimingDelay = nTime;
   while(TimingDelay != 0);
}
/* 中断服务函数 */
void SysTick_Handler(void)
{
if (TimingDelay != 0x00) 
TimingDelay--;
}
}
int main(void)
{  
// ...
if (SysTick_Config(SystemCoreClock / 1000)) // 注意,这里systick时钟为HCLK,中断时间间隔1ms 
{
while (1);
}
while(1)
{
Delay(200);//2ms
// ...
}
}
SysTick_Config(SystemCoreClock / 1000): (原代码这里假设是采用时钟源为 HCLK)
这里设置的是 72000000Hz / 1000 = 72000 ticks,也就是说 SysTick 从 (72000-1) 开始倒数。
每倒数完 72000 个节拍就触发一次中断。
一个节拍的时间为:72000000 / 72000 = 1000us == 1ms
SysTick_Config((SystemCoreClock / 8000000) * 1000 * 1): 
SysTick_Config() 会设置时钟源为 HCLK/8 所以实际应用中不能按照上述代码的参数。
SystemCoreClock / 8000000: 1us 的节拍数
1us的节拍数 * 1000: 则为 1ms 的节拍数
1ms 的节拍数 * 1: 设置 1ms 一个SysTick中断,即从 ((SystemCoreClock / 8000000) * 1000 * 1) - 1 开始倒数。
2、轮询方式
static u8  fac_us=0; //us延时倍乘数    
static u16 fac_ms=0; //ms延时倍乘数
void delay_init()
{
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8); //选择外部时钟  HCLK/8
fac_us = SystemCoreClock/8000000;         // 为系统时钟的1/8  1us = 72000000 / 8000000 =  9 个节拍
fac_ms = (u16)fac_us*1000; // 1ms 需要 9 * 1000 = 9000 个节拍
}
//延时 nus 微秒         
void delay_us(u32 nus)
{
u32 temp;
SysTick->LOAD=nus*fac_us;  //时间加载     
SysTick->VAL=0x00;          //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;                //开始倒数
do
{
temp=SysTick->CTRL;
}while((temp&0x01)&&!(temp&(1<<16))); //等待时间到达  
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;//关闭计数器
SysTick->VAL =0X00;                     //清空计数器  
}
//延时nms
//注意nms的范围
//SysTick->LOAD为24位寄存器,所以,最大延时为:
//nms<=0xffffff*8*1000/SYSCLK
//SYSCLK单位为Hz,nms单位为ms
//对72M条件下,nms<=1864 
void delay_ms(u16 nms)
{        
u32 temp;    
SysTick->LOAD=(u32)nms*fac_ms;   //时间加载(SysTick->LOAD为24bit)
SysTick->VAL =0x00;                       //清空计数器
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk ;  //开始倒数 
do
{
temp=SysTick->CTRL;
                //等待时间到达,这里使用了一个小技巧,通过(temp&0x01)检查 SysTick 的使能位,避免 Systick 定时器被关闭而导致无限循环 
}while((temp&0x01)&&!(temp&(1<<16)));  
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk; //关闭计数器
SysTick->VAL =0X00;                      //清空计数器        

STM32 SysTick 滴答定时器原理及应用相关推荐

  1. STM32——系统滴答定时器

    STM32--系统滴答定时器 宗旨:技术的学习是有限的,分享的精神是无限的. 一.SysTick[内核中] [风格:先描述一下库对寄存器的封装,再举例实现某些功能] SysTick定时器被捆绑在NVI ...

  2. Systick滴答定时器解析

    Systick滴答定时器 Systick定时器是什么 Systick定时器,是一个简单的定时器,对于CM3,CM4内核芯片,都有Systick定时器. Systick定时器常用来做延时,或者时系统的心 ...

  3. STM32F4无人机Systick滴答定时器

    更多交流欢迎关注作者抖音号:81849645041 目标 了解 ARM Cortex-M 系列芯片的内部时钟及定时器使用,通过配置 STM32F407 芯片的内部定时器,实现流水灯效果. 原理 Sys ...

  4. [学习笔记]STM32F1 SYSTICK 滴答定时器(寄存器、标准库、HAL库)

    目录 0. 博主理解: 1. 实验内容及步骤: 2. 硬件说明 3. 寄存器说明 3.1 SysTick的时钟和使能: 3.2 SysTick重装载数值寄存器: 3.3 SysTick的中断优先级: ...

  5. 滴答定时器的计数模式_Cortex-M4 Systick滴答定时器

    Tickclock可以实现精确延时,在K60的datasheet中没有详细将,现在我把我找到资料分享一下,关于systick在Cortex-M4中有讲到我们大家平常在单片机开发中经常会使用到延时函数, ...

  6. STM32系统滴答定时器(systick)应用

    一:系统滴答定时器(systick) 1.systick介绍 Systick就是一个定时器而已,只是它放在了NVIC中,主要的目的是为了给操作系统提供一个硬件上的中断(号称滴答中断).滴答中断?这里来 ...

  7. stm32系统滴答定时器使用

     STM32菜鸟成长记录---系统滴答定时器(systick)应用 标签: delay任务测试reference编译器工作 2012-08-19 22:55 47395人阅读 评论(4) 收藏 举 ...

  8. Systick滴答定时器寄存器、delay()延时函数、SysTick_Config函数

    SysTick定时器 SysTick定时器,是一个简单的定时器,对于CM3.CM4内核的芯片都有SysTick定时器.SysTick 是一个 24 位的倒计数定时器,当计数到 0 时,将从RELOAD ...

  9. Systick滴答定时器讲解

    Systick定时器基础知识讲解: Systick定时器,是一个简单的定时器,对于CM3,CM4内核芯片,都有- Systick定时器. Systick定时器常用来做延时,或者实时系统的心跳时钟.这样 ...

最新文章

  1. c# Pdf 转换图片
  2. 国有大型企业数据级同城异地灾难备份案例
  3. 多线程开发之---线程等待
  4. CUDA ---- device管理
  5. error: not found: value SparkSession
  6. Python应用实战-Python爬取4000+股票数据,并用plotly绘制了树状热力图(treemap)
  7. windows 快捷键整理
  8. mysql 注入 update_利用insert,update和delete注入获取数据_MySQL
  9. HTML(2)--- 简介
  10. 「BZOJ 2142」礼物
  11. 基础集合论笔记 目录
  12. win10升级补丁_干掉烦人的win10升级助手gwx
  13. 运用Python——劳拉下棋_四连环游戏_重力四子棋游戏(代码与游戏判定)
  14. 洗料系列-编程语言专题-Java 19【线程×,协程√】
  15. php删除二维数组元素_php怎样删除二维数组中的元素
  16. FME对CAD扩展属性的读写
  17. 脑机接口全球Top20实验室信息与概括(有空更新)
  18. java调用 post_java调用post请求到localhost:4040
  19. TikTok不可思议的崛起
  20. 云计算技术基础【2】

热门文章

  1. Android修行手册 - GridLayout复习和计算器示例
  2. Ibatis.Net执行Sql超时commandTimeout的一个坑
  3. C# -XML用法(XmlDocument )
  4. web前端期末大作业【仿12306铁路官网首页】学生网页设计作业源码
  5. Edition-Based Redefinition白皮书笔记
  6. ZXING QR Coder
  7. 计算机在生活中很重要用英语,电脑对生活的影响英语作文
  8. 使用谷歌纵横(Google Latitude)实现监控的设想
  9. FPGA学习(第5节)-看电路图写出Verilog代码(乘法运算+自加一+模块实例化等)
  10. 决策树算法(C4.5算法)