ARM Cortex-M架构中有一个位于核内的标准系统节拍时钟(Systick)。系统节拍时钟的寄存器地址由ARM标准规定,在所有芯片中都是相同的。开发者可通过ARM CMISIS库标准函数进行配置。相对于芯片自身提供的计时器,使用系统节拍时钟的优势在于其初始化和中断函数程序可以运行在任何ARM Cortex-M核的芯片上。而芯片计时器的初始化和中断函数只适用于特定芯片,在进行程序移植时需要重新研读芯片数据手册编写程序。
系统节拍时钟配置
系统节拍时钟是一个倒数计时器。系统节拍时钟的SYST_RVR
寄存器用来设置倒数计时器的初始值。硬件首先会将SYST_RVR
中的初始值装载进SYST_CVR
寄存器中。在每个时钟上升或者下降沿,SYST_CVR
寄存器值会减1。倒数到0后芯片自动将SYST_RVR
寄存器值重新装载到SYST_CVR
寄存器中重新开始倒计时。在倒数到0时,系统节拍时钟还、会将SYST_CSR
寄存器中的COUNTFLAG
位置1。如果在SYST_CSR
寄存器中设置了TICKINT
位,同时还会触发SysTick
中断。SysTick
中断位于ARM Cortex-M定义的16个中断位中,在所有芯片上具有相同的中断号。
以下是core_cm4.h
中SysTick
的定义。
/**
\brief Structure type to access the System Timer (SysTick).
*/
typedef struct
{
__IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
__IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
__IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
__IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
} SysTick_Type;
...
#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
以下是利用ARM CMSIS标准库提供的系统节拍时钟初始化函数,开发者程序#include "core_cm4.h"
后可直接调用。需要注意的是
SYST_RVR
寄存器有效值只有24bit。所以在设置倒数计时器初始值时要确保其不大于0xFFFFFF
。- 函数参数
ticks
值取决于倒是计时器周期和驱动系统节拍时钟的时钟频率。如果驱动时钟频率为24MHz
,开发者希望系统节拍时钟中断频率为1KHz(1ms周期)。那么tick
的值为24*1000000/1000 = 24000
。 - 示例程序使用了系统节拍时钟中断并且设置了中断优先级。如果开发者希望用轮询方式获得倒计时时间可以移除
SysTick_CTRL_TICKINT_Msk
。
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Fun