1.systick介绍

Systick就是一个定时器而已,只是它放在了NVIC中,主要的目的是为了给操作系统提供一个硬件上的中断(号称滴答中断)。滴答中断?这里来简单地解释一下。操作系统进行运转的时候,也会有“心跳”。它会根据“心跳”的节拍来工作,把整个时间段分成很多小小的时间片,每个任务每次只能运行一个“时间片”的时间长度就得退出给别的任务运行,这样可以确保任何一个任务都不会霸占整个系统不放。或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。 只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息。

知道systick在系统中的地位后,我们来了解systick的实现。这里只是举例说明systick的使用。它有四个寄存器,笔者把它列出来:

SysTick->CTRL,        --控制和状态寄存器

SysTick->LOAD,        --重装载寄存器

SysTick->VAL,          --当前值寄存器

SysTick->CALIB,        --校准值寄存器

下图有他们的分别描述:     下图引用地址:http://blog.csdn.net/marike1314/article/details/5673684

2.systick编程

现在我们想通过Systick定时器做一个精确的延迟函数,比如让LED精确延迟1秒钟闪亮一次。

思路:利用systick定时器为递减计数器,设定初值并使能它后,它会每个1系统时钟周期计数器减,计数到 0时,SysTick计数器自动重装初值并继续计数,同时触发中断。

那么每次计数器减到0,时间经过了:系统时钟周期 *计数器初值。我们使用72M作为系统时钟,那么每次计数器减1所用的时间是1/72M,计数器的初值如果是72000,那么每次计数器减到0,时间经过(1/72M)*72000= 0.001,即1ms。(简单理解:用72M的时钟频率,即1s计数72M=72000000次,那1ms计数72000次,所以计数值为72000) 

首先,我们需要有一个72M的systick系统时钟,那么,使用下面这个时钟OK就 !

SystemInit();

这个函数可以让主频运行到72M。可以把它作为systick的时钟源。

接着开始配置systick,实际上配置systick的严格过程如下:

1、调用SysTick_CounterCmd()       --失能SysTick计数器

2、调用SysTick_ITConfig()          --失能SysTick中断

3、调用SysTick_CLKSourceConfig()  --设置SysTick时钟源。

4、调用SysTick_SetReload()         --设置SysTick重装载值。

5、调用SysTick_ITConfig()          --使能SysTick中断

6、调用SysTick_CounterCmd()       --开启SysTick计数器

这里大家一定要注意,必须使得当前寄存器的值VAL等于0!

SysTick->VAL  = (0x00);只有当VAL值为0时,计数器自动重载RELOAD。

接下来就可以直接调用Delay();函数进行延迟了。延迟函数的实现中,要注意的是,全局变量TimingDelay必须使用volatile,否则可能会被编译器优化。

下面我们来做一下程序分析:

(1)系统时钟进配置

首先我们对系统时钟进行了配置并且SetSysClock(void)函数使用72M作为系统时钟;

为了方面看清代码我选择截图:

(2)先来看看主函数

[plain]  view plain copy
  1. int main(void)
  2. {            unsigned char i=0;
  3. unsigned char a[] = "abncdee";
  4. SystemInit1();//系统初始化
  5. if (SysTick_Config(72000))  //1ms响应一次中断
  6. {
  7. /* Capture error */
  8. while (1);
  9. }
  10. /*解析:因为要求是每500ms往中位机发数据一件事,所以放在while语句中,
  11. *送据+延时可以完成相当于中断的效果;
  12. *若是多任务中,其中一个任务需要中断,这把这个任务放在中断函数中调用;
  13. */
  14. while (1)
  15. {
  16. //测试代码:测试定时器功能,通过延时来测试
  17. GPIO_SetBits(GPIOC, GPIO_Pin_6);      //V6
  18. Delay(50);
  19. GPIO_ResetBits(GPIOC, GPIO_Pin_6);         //V6
  20. Delay(50);
  21. //功能1代码:每500ms发送数据
  22. /*
  23. UART2_TX485_Puts("123450");
  24. Delay(500);
  25. */
  26. //功能2代码:上位发特定指令,中位机执行相应操作
  27. //     RS485_Test();
  28. }
  29. }

(3)系统滴答定时器的配置--主角登场:

主函数中: SysTick_Config(72000) ;滴答定时器的参数是72000即计数72000

(因为我们使用72M的时钟频率,即1s计数72M=72000000次,那1ms计数72000次,所以计数值为72000) 

在文件Core_cm3.h中

SysTick_Config函数的具体实现如下:

[html]  view plain copy
  1. static __INLINE uint32_t SysTick_Config(uint32_t ticks)
  2. {
  3. if (ticks>SYSTICK_MAXCOUNT)
  4. return (1);      /* Reload value impossible */
  5. SysTick->LOAD = (ticks & SYSTICK_MAXCOUNT) - 1;//systick重装载值寄存器   /* set reload register */
  6. NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Cortex-M0 System Interrupts */
  7. SysTick->VAL = (0x00);  //systick当前值寄存器
  8. /* Load the SysTick Counter Value */
  9. SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<<SYSTICK_ENABLE) | (1<<SYSTICK_TICKINT);//使能IRQ(普通中断)和系器         return(0);      /* Function successful */
  10. }

我们来看一下这句代码:SysTick->CTRL = (1 << SYSTICK_CLKSOURCE) | (1<<SYSTICK_ENABLE) | (1<<SYSTICK_TICKINT); 这是使能IRQ(普通中断)和系统定时器,为什么要使能中断和系统定时器呢?

下面我们来看一下stm32f10x_it.h文件中:

找到滴答定时器中断函数:SysTickHandler()

void SysTickHandler(void)

{

TimingDelay_Decrement();

}

从上文我们通过装载的计数值72000知道每1ms发生一次中断,在中断函数中调用一个函数TimingDelay_Decrement();-----即每1ms发生中断时就调用到此函数;

下面我们来看看TimingDelay_Decrement();在干些什么?

[html]  view plain copy
  1. /*****************************************************************
  2. *函数名称:TimingDelay_Decrement
  3. *功能描述:中断里调用此函数,即没发生一次中断,此函数被调用,此函数里
  4. *          的变量TimingDelay 相当于减法计数器
  5. *
  6. *输入参数:无
  7. *返回值:无
  8. *其他说明:无
  9. *当前版本:v1.0
  10. *作    者: 梁尹宣
  11. *完成日期:2012年8月3日
  12. *修改日期      版本号      修改人      修改内容
  13. *-----------------------------------------------------------------
  14. *
  15. ******************************************************************/
  16. void TimingDelay_Decrement(void)
  17. {
  18. if (TimingDelay != 0x00)
  19. {
  20. TimingDelay--;
  21. }
  22. }
  23. 我们看了TimingDelay的定义,又看了还有哪些函数调用到这个变量,如下:
  24. /*****************************************************************
  25. *                                        全局变量
  26. ******************************************************************/
  27. static __IO uint32_t TimingDelay=0;
  28. /*****************************************************************
  29. *函数名称:    Delay
  30. *功能描述:    利用系统时钟计数器递减达到延时功能
  31. *
  32. *输入参数:nTime :需要延的时毫秒数
  33. *返回值:无
  34. *其他说明:无
  35. *当前版本:v1.0
  36. *作    者: 梁尹宣
  37. *完成日期:2012年8月3日
  38. *修改日期      版本号      修改人      修改内容
  39. *-----------------------------------------------------------------
  40. *
  41. ******************************************************************/
  42. void Delay(__IO uint32_t nTime)//delay被调用时,nTime=500
  43. {
  44. TimingDelay = nTime;
  45. while(TimingDelay != 0);
  46. }

通过上面几个函数我们知道了,在调用Delay(500)即nTime=500;在后在Delay()函数中TimingDelay =nTime;(即TimingDelay=500是它的初始值),再TimingDelay_Decrement(void)函数的作用就是把TimingDelay- -;每毫秒进行递减直到减到0为止;这样就起到一个延时的作用;

现在我们做出来的Delay(1),就是1毫秒延迟。Delay(1000)就是1秒。

我们来画个图,方便这几个函数间关系的理解:

我们在返回到主函数main()中看这几条语句:红色标注de

[html]  view plain copy
  1. while (1)
  2. {
  3. //测试代码:测试定时器功能,通过延时来测试
  4. GPIO_SetBits(GPIOC, GPIO_Pin_6);      //V6
  5. Delay(500);
  6. GPIO_ResetBits(GPIOC, GPIO_Pin_6);         //V6
  7. Delay(500);
  8. //功能1代码:每500ms发送数据
  9. /*
  10. UART2_TX485_Puts("123450");
  11. Delay(500);
  12. */
  13. //功能2代码:上位发特定指令,中位机执行相应操作
  14. //     RS485_Test();
  15. }

经过上面系统定时器的分析我们知道Delay(500);是延时500ms ;那么LED就是每隔500ms闪烁一次;

上面有关系统滴答定时器的应用讲解基本完毕!

有关SysTick编译后的源代码包,(其实客官细心的话一经发现上面代码含有485通讯代码,

只不过被暂时屏蔽掉了,下一节将讲到)我放在我的资源里:http://download.csdn.net/detail/yx_l128125/4511622

下面我们来看看一下参考资料的问题,一边对上面我写的博客有更深入的理解:

《Cortex-M3权威指南》

《Cortex-M3 Technical Reference Manual》

Q:什么是SYSTick定时器?

SysTick 是一个24位的倒计数定时器,当计到0时,将从RELOAD寄存器中自动重装载定时初值。只要不把它在SysTick控制及状态寄存器中的使能位清除,就永不停息。

Q:为什么要设置SysTick定时器?

(1)产生操作系统的时钟节拍

SysTick定时器被捆绑在NVIC用于产生SYSTICK异常(异常号:15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。

(2)便于不同处理器之间程序移植。

Cortex‐M3处理器内部包含了一个简单的定时器。因为所有的CM3芯片都带有这个定时器,软件在不同 CM3器件间的移植工作得以化简。该定时器的时钟源可以是内部时钟(FCLK,CM3上的自由运行时钟),或者是外部时钟( CM3处理器上的STCLK信号)。

不过,STCLK的具体来源则由芯片设计者决定,因此不同产品之间的时钟频率可能会大不相同,你需要检视芯片的器件手册来决定选择什么作为时钟源。SysTick定时器能产生中断,CM3为它专门开出一个异常类型,并且在向量表中有它的一席之地。它使操作系统和其它系统软件在CM3器件间的移植变得简单多了,因为在所有CM3产品间对其处理都是相同的

(3)作为一个闹铃测量时间。

SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等。要注意的是,当处理器在调试期间被喊停(halt)时,则SysTick定时器亦将暂停运作。

Q:Systick如何运行?

首先设置计数器时钟源,CTRL->CLKSOURCE(控制寄存器)。设置重载值(RELOAD寄存器),清空计数寄存器VAL(就是下图的CURRENT)。置CTRL->ENABLE位开始计时。

如果是中断则允许Systick中断,在中断例程中处理。如采用查询模式则不断读取控制寄存器的COUNTFLAG标志位,判断是否计时至零。或者采取下列一种方法

当SysTick定时器从1计到0时,它将把COUNTFLAG位置位;而下述方法可以清零之:

1. 读取SysTick控制及状态寄存器(STCSR)

2. 往SysTick当前值寄存器(STCVR)中写任何数据

只有当VAL值为0时,计数器自动重载RELOAD。

Q:如何使用SysTicks作为系统时钟?

SysTick 的最大使命,就是定期地产生异常请求,作为系统的时基。OS都需要这种“滴答”来推动任务和时间的管理。如欲使能SysTick异常,则把STCSR.TICKINT置位。另外,如果向量表被重定位到SRAM中,还需要为SysTick异常建立向量,提供其服务例程的入口地址

转载于http://blog.csdn.net/yx_l128125/article/details/7884423

系统滴答定时器(systick)应用相关推荐

  1. linux调度周期systick怎么看,Cortex-M0系统滴答定时器Systick详解

    上图是LPC1114系统滴答定时器(SysTick)的结构图.系统滴答定时器位于Cortex-M0内核中,也就是说,不论是LPC1114,还是其他的Cortex-M0内核单片机,都有这个系统定时器.其 ...

  2. 【STM32】HAL库-系统滴答定时器SysTick

    SysTick定时器被捆绑在NVIC中,是一个简单的定时器,对于CM3.CM4内核芯片,都有Systick定时器.Systick定时器常用来做延时,或者实时系统的心跳时钟.这样可以节省MCU资源,不用 ...

  3. stm32滴答计时器_STM32 的系统滴答定时器( Systick) 彻底研究解读

    作者:王健 前言 SysTick 比起那些 TIM 定时器可以说简单多啦~~~~~哥的心情也好了不少, 嘎嘎!! ARM Cortex-M3 内核的处理器内部包含了一个 SysTick 定时器,它是一 ...

  4. stm32滴答计时器_STM32的系统滴答定时器(Systick)

    1.systick时钟来源 2.SysTick库函数 3.源码 /** *@} */ /** @defgroup SysTick_clock_source *@{ */ #define SysTick ...

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

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

  6. stm32滴答计时器_STM32之系统滴答定时器

    一.SysTick(系统滴答定时器)概述 操作系统需要一个滴答定时器周期性产生中断,以产生系统运行的节拍.在中断服务程序里,基于优先级调度的操作系统会根据进程优先级切换任务,基于时间片轮转系统会根据时 ...

  7. cube 设置滴答定时器_STM32CubeMX | 27-系统滴答定时器Systick的使用

    本篇文章主要介绍如何使用STM32中的系统滴答定时器Systick. 1. 准备工作 硬件准备开发板 首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi): 软件准备需要安装好 ...

  8. SysTick系统滴答定时器

    工作原理 SysTick系统滴答定时器是一个24位递减计数器计数器,向下计数,最大计数值为() SysTick系统滴答定时器,每个时钟周期-1,减到0后申请中断,并且会自动重装初值. 注意: 定时器的 ...

  9. SysTick系统滴答定时器(STM32F4xx系列)

    定时器概念 1.1 定时器的含义 1.2片上外设的定时器 1.3定时/延时原理 系统滴答定时器 2.1 为什么需要系统滴答定时器 2.2 系统滴答定时器概述 2.3 系统滴答定时器框架 2.4 系统滴 ...

最新文章

  1. centos 网卡聚合及Cisco交换机链路聚合
  2. Spring AOP Capability and Goal
  3. 转载一遍Java规范
  4. 如何在Python中使用“ with open”打开多个文件?
  5. DELL 通过iDrac安装ESXI
  6. 7-8 InputMismatchException异常 (20 分)
  7. learning to rank评价指标
  8. MDX Step by Step 读书笔记(四) - Working with Sets (使用集合)
  9. Gerrit 服务搭建和升级详解(包括 H2 数据库迁移 MySQL 步骤)
  10. 记录一下----关于设计模式和面向对象设计原则
  11. linux命令详解——sar
  12. bigemap 软件功能对比
  13. uint32 t java_数据类型 -- uint32_t 类型
  14. 微信电脑端突然发送不了文件了
  15. Win10 固定IP地址方法
  16. pdf 电子签章 java_利用itextpdf实现简单的电子签章/水印等
  17. Codeforces Round #533(Div. 2) A.Salem and Sticks
  18. 手把手教你在Github上建立自己的个人博客网站
  19. Mongdb重启后dirty很高,cache打满
  20. 中控考勤机使用 zkemkeeper SDK订阅考勤数据事件失效解决方式

热门文章

  1. Robots.txt泄露敏感信息
  2. java ee学生信息管理_【全】JAVAEE_学生信息管理系统
  3. 童话 谢幕了。梦也该醒了:伤感日志
  4. “票卡分析专用工具”功能介绍
  5. Windows 环境下搭建VTS
  6. mysql 用户权限
  7. 阿里的Hadoop之路:Hadoop的过去、现在和未来
  8. iPhone 13 发布日期、规格、预期价格等信息超全汇总
  9. u88财富快车流氓软件RK驱动分析
  10. <整理不易|全网独家|欢迎收藏>《信息资源管理》第4章真题整理,信息系统资源内容管理