• SysTick定时器详解


    SysTick定时器详解

    关于SysTick定时器,如果想从STM32官方手册去寻找该定时器,会发现并没有该定时器的相关介绍,仅有库函数介绍。由此可以看出SysTick并不是意法半导体公司设定的。从Cortex-M3权威指南可以找到该定时器的详细介绍,由此可以知道SysTick定时器是在ARM芯片当中设定的。
    这里有一个疑问,为什么M3有这么多定时器还要弄一个SysTick定时器呢?
    这要从它的概念入手,系统滴答定时器是一个非常基本的倒计时定时器,用于在每隔一定时间产生一个中断,即使是系统在睡眠模式下也能工作。它使得OS在各CM3器件之间的移植中不必修改系统定时器的代码,移植工作一下子容易多了。SysTick定时器也是作为NVIC的一部分实现的。

    如果有外设就一定会存在一堆用来配置该外设的寄存器,SysTick定时器也不例外。用来控制该定时器的寄存器有四个,下面详细介绍这四个寄存器。

    SysTick控制及状态寄存器(地址:0xE000_E010)

    位段 名称 类型 复位值 描述
    16 COUNTFLAG R 0 如果在上次读取本寄存器后, SysTick 已经数到了 0,则该位为 1。如果读取该位,该位将自动清零
    2 CLKSOURCE R/W 0 0=外部时钟源(STCLK) 1=内核时钟(FCLK)
    1 TICKINT R/W 0 1=SysTick 倒数到 0 时产生 SysTick 异常请求 0=数到 0 时无动作
    0 ENABLE R/W 0 SysTick 定时器的使能位

    四个位都挺简单,对两个稍难的解释一下:

    TICKINT 该位置为1时,SysTick定时器倒数到零会产生中断

    COUNTFLAG 已经有了TICKINT为什么还要该位呢,原因是当TICKINT位置为0时,如果没有该位,就无法得知定时器是否已经倒数到0,因为倒数到0不会有任何动作。

    SysTick重装载数值寄存器(地址:0xE000_E014)

    位段 名称 类型 复位值 描述
    23:0 RELOAD R/W 0 当倒数至零时,将被重装载的值

    该寄存器24位,最大可装载值为FF FFFF

    SysTick当前数值寄存器(地址:0xE000_E018)

    位段 名称 类型 复位值 描述
    23:0 CURRENT R/Wc 0 读取时返回当前倒计数的值,写它则使之清零, 同时还会清除在 SysTick 控制及状态寄存器中的 COUNTFLAG 标志

    该寄存器被读取后,会清零,重装载寄存器就会将它里面的重装载值传递到该寄存器。

    SysTick校准数值寄存器(地址:0xE000_E01C)

    位段 名称 类型 复位值 描述
    31 NOREF R 1=没有外部参考时钟(STCLK 不可用) 0=外部参考时钟可用
    30 SKEW R 1=校准值不是准确的 10ms 0=校准值是准确的 10ms
    23:0 TENMS R/W 0 10ms 的时间内倒计数的格数。芯片设计者应该通 过 Cortex‐M3 的输入信号提供该数值。若该值读 回零,则表示无法使用校准功能

    介绍完了寄存器,那就去STM32官方手册看看相关库函数吧,有一点可以肯定的是,库函数就是用来设置上面四个寄存器中某些位的。

    在core_cm3.h文件中有这么一个函数可以用来配置SysTick定时器:

    /**
     * @brief  Initialize and start the SysTick counter and its interrupt.
     *
     * @param   ticks   number of ticks between two interrupts
     * @return  1 = failed, 0 = successful
     *
     * Initialise the system tick timer and its interrupt and start the
     * system tick timer / counter in free running mode to generate 
     * periodical interrupts.
     * 初始化并启动系统滴答定时器和它的中断/计数器自由运行模式用来产生周期性的中断
     */
    static __INLINE uint32_t SysTick_Config(uint32_t ticks)
    { 
      if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
                                                                   
      SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register * SysTick_LOAD_RELOAD_Msk为0xFFFFFF */
      SysTick->VAL   = 0;                                          /* 把当前计数值设置为0,这* 样会将重装载寄存器中的值自动加载进来 Load the SysTick Counter Value */
      SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk | 
                       SysTick_CTRL_TICKINT_Msk   | 
                       SysTick_CTRL_ENABLE_Msk;                    /* 将SysTick控制及状态寄存器低三位全部置为1。0、SysTick 定时器被使能 2、SysTick 倒数到 0 时产生 SysTick 异常请求 3、选择内核时钟(FCLK)为时钟源,也就是72MHZ*/
      return (0);                                                  /* Function successful */
    }
    
    #endif
    

    用中断的方式实现delay:

    void SysTick_Configuration(void){
        while(SysTick_Config(72)==1);	//1us产生一次SysTick异常
        SysTick->CTRL &= ~(1<<0);	//SysTick暂不开启,等使用时再开启
    }
    
    Void delay_us(unsigned long n){
        SysTick->CTRL |= (1<<0);
        while(n);  //每1us会产生一次中断,n--
        SysTick->CTRL &= ~(1<<0);
    }
    
    void SysTick_Handler(void){
        n--;
    }
    
  • 相关阅读:
    (24)ajax上传json格式的数据
    (23)ajax实现上传文件的功能
    (22)Ajax的基本使用(实现登录功能和局部刷新以及防止跨站请求伪造攻击)
    (21)模型层 -ORM之msql 聚合查询,F和Q(与、或、非查询)、分组查询
    (20)模型层 -ORM之msql 基于双下划线的跨表查询(一对一,一对多,多对多)
    Python init.py
    python 模块积累-----subprocess
    linux修改root密码
    Django urls.py报错: raise TypeError('view must be a callable or a list/tuple in the case of include()
    Python------uuid
  • 原文地址:https://www.cnblogs.com/roscangjie/p/12489574.html
Copyright © 2020-2023  润新知