一、SysTick定时器概念

SysTick定时器是一种在嵌入式系统中常用的定时器,它是由ARM Cortex-M处理器核内置的定时器。SysTick定时器具有精简、低功耗和易用的特点,可以用来实现各种定时、延时和时间基准等功能。

二、SysTick定时器的主要特性

  1. 单调递增计数器:SysTick定时器内置一个递增的32位计数器,在每个时钟周期中自动递增。

  2. 可编程计数器值:可以使用32位计数器的值设置定时器的计数周期。

  3. 中断触发:可以配置SysTick中断,当计数器达到设定值时,会触发中断请求。

  4. 低功耗:SysTick定时器可以在低功耗的模式下运行,以节省能源。

  5. 优先级:可以设置SysTick定时器中断的优先级,用于控制中断处理的优先顺序。

三、SysTick定时器时钟源–时钟树

四、4个寄存器控制SysTick定时器

        1. 状态控制寄存器:系统滴答是一个递减计数器–从大减到0,选择SysTick->CTRL,

相关内容如下图:

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

解释图中的内容如下:

(1)位0–系统滴答定时器的使能位—–把这个位写1,就是开始计数

注:先配置好时间,再开始计数,计数时间到,要关闭

(2)位2–时钟源选择       0–外部时钟—稳定—25M产生高速时钟

                                          1–内部时钟—不稳定的,有误差

(3)位16–计数时间到状态位,硬件置1当读取状态后,自动变0

      2. 重装载寄存器:当计数寄存器到0时,不会自动更新计数值,需要从重装载中获得新的计数值24位有效值 2^24次方个数==16,777,215最大个数。选择SysTick->LOAD。

相关内容如图所示:

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

      3. SysTick当前数值寄存器(计数寄存器):递减计数器–会从最大值递减到零,产生中断使控制状态寄存器位16置1,24位有效值 2^24次方个数==16,777,215最大个数,选择SysTick->VAL。

相关内容如图所示:

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

     4. SysTick校准数值寄存器:用于提供一个校准值,以确保 SysTick 计时器满足特定的时间准确性要求,选择SysTick_CALIB。

    相关内容如图所示:

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

   解释图中的内容如下:

          TENMS([23:0]):表示每个计数器时钟周期对应的时间,以毫秒(ms)为单位。这个值可以用来校准 SysTick 的中断间隔时间,从而实现精确的定时。

         SKEW([30]):表示 SysTick 计数器的斜率。如果为 1,则表示计数器的斜率是非线性的,需要校准计数器以提高准确性。

          NOREF([31]):表示处理器是否提供外部时钟源来驱动 SysTick 计时器。如果为 1,表示外部时钟源不可用,需要使用处理器的时钟源来驱动 SysTick 计时器。

五、SysTick定时器作用

          SysTick定时器在嵌入式系统中提供了一个简单、灵活和易用的定时功能,可以满足系统各种时间相关的需求,如节拍、延时、定时中断和时间基准等。同时,SysTick定时器除了能服务于操作系统之外,还能用于其它目的:如作为一个闹铃,用于测量时间等。要注意的是,当处理器在调试期间被喊停(halt)时,则SysTick定时器亦将暂停运作。

六、SysTick定时器的使用步骤通常包括以下几个步骤

        1. 初始化:配置SysTick定时器的计数周期和中断优先级等参数。

        2. 启动定时器:启动SysTick定时器以开始计数。

       3. 中断处理:当计数器达到设定值时,系统会触发SysTick中断,可以在中断处理函数中执行相应的操作。

       4. 停止定时器:根据需要,可以在适当的时候停止SysTick定时器的计数。

七、六个SysTick函数说明

  1. 设置SysTick时钟源函数

 void SysTick_CLKSourceConfig(u32 SysTick_CLKSource);

       其中,SysTick_CLKSource 是一个参数,用于指定 SysTick 定时器的时钟源。该参数可以根据自己的需求,选择以下值的任意一个即可:

     SysTick_CLKSource_HCLK_Div8: 使用 HCLK/8 作为 SysTick 定时器的时钟源。

     SysTick_CLKSource_HCLK: 使用 HCLK(处理器时钟)作为 SysTick 定时器的时钟源。

      下面是关于使用该函数的一个简单例子:

SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);

2. 设置SysTick重装载值函数

void SysTick_SetReload(u32 Reload);

       其中,Reload为重装载值,该参数取值必须在1和0x00FFFFFF之间。

      下面是关于使用该函数的一个简单例子:

SysTick_SetReload(0xFFFF);

3. 使能或者失能SysTick计数器函数

void SysTick_CounterCmd(u32 SysTick_Counter);

      其中,SysTick_Counter为SysTick计数器新状态。

      下面是关于使用该函数的一个简单例子:

SysTick_CounterCmd(SysTick_Counter_Enable);

4. 使能或者失能SysTick中断函数

void SysTick_ITConfig(FunctionalState NewState);

      其中,NewState为SysTick中断的新状态,该参数可以取:ENABLE或者DISABLE。

      下面是关于使用该函数的一个简单例子:

SysTick_ITConfig(ENABLE);

5. 获取SysTick计数器的值函数

u32 SysTick_GetCounter(void);

下面是关于使用该函数的一个简单例子:

u32 SysTickCurrentCounterValue;
SysTickCurrentCounterValue = SysTick_GetCounter();

6. 检查指定的SysTick标志位设置与否函数

FlagStatus SysTick_GetFlagStatus(u8 SysTick_FLAG);

                                                                                                                                             

      其中,SysTick_FLAG为待检查的SysTic标志位,SysTick_FLAG标志列表如下图所示:

     下面是关于使用该函数的一个简单例子:

FlagStatus Status;
Status = SysTick_GetFlagStatus(SysTick_FLAG_COUNT);

if(Status == RESET){

   //加入自己写的代码
}
else{

   //加入自己写的代码
}

八、完整代码

1. systick.c
#include <stdbool.h>
#include "stm32f4xx.h" // 假设使用的是 STM32F4 系列的微控制器

// 初始化 SysTick 定时器
void SysTick_Init(void) {

  SysTick_Config(SystemCoreClock / 1000); // 设置计数周期为 1ms
}

// 启用 SysTick 定时器
void SysTick_Start(void) {

  SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}

// 停止 SysTick 定时器
void SysTick_Stop(void) {

  SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
}

// 获取 SysTick 计数器的当前值
uint32_t SysTick_GetCurrentValue(void) {

  return SysTick->VAL;
}

// 检查 SysTick 计数器是否溢出
bool SysTick_CheckOverflow(void) {

  return (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) != 0;
}

// 延迟指定的毫秒数
void SysTick_Delay(uint32_t ms) {

  uint32_t startTick = SysTick_GetCurrentValue();
  uint32_t targetTick = startTick + ms;

  // 处理 SysTick 计数器溢出的情况
  if (targetTick < startTick) {

    while (SysTick_GetCurrentValue() > startTick) {}

  }
2.systick.h
#ifndef SYSTICK_H
#define SYSTICK_H
#include <stdint.h>
#include <stdbool.h>

void SysTick_Init(void); // 初始化 SysTick 定时器
void SysTick_Start(void); // 启用 SysTick 定时器
void SysTick_Stop(void);  // 停止 SysTick 定时器
uint32_t SysTick_GetCurrentValue(void);  // 获取 SysTick 计数器的当前值
bool SysTick_CheckOverflow(void);  // 检查 SysTick 计数器是否溢出
void SysTick_Delay(uint32_t ms); // 延迟指定的毫秒数

#endif 

物联沃分享整理
物联沃-IOTWORD物联网 » STM32 SysTick定时器详解

发表评论