STM32学习(四) SyxTick 实验
Systick 简介
- SYSTick 系统定时器是 CM4 内核的一个外设(所有 CM4 内核的单片机都有),内嵌在 NVIC 中;
- 24bit 的向下递减计数器,计数器每计数一次的时间是 1/SYSCLK,一般设置 SYSTICK 为168MHz(以STM32F407为例);
- 当重装载数值寄存器的值递减到0的时候,系统定时器就产生一次中断,以此循环往复;
- 一般用于产生时基,维持系统心跳
SysTick 寄存器讲解
寄存器 | 功能 |
---|---|
CTRL | 控制及状态寄存器 |
LOAD | 重装载数值寄存器 |
VAL | 当前数值寄存器 |
CALIB | 校准数值寄存器 |
CTRL 寄存器
bit[2] CLKSOURCE, 时钟源选择,0-AHB/8,1-AHB
bit[1] TICKINIT, 1-SysTick倒计数到0时产生异常请求(即中断)
bit[0] ENABLE,1-使能
RELOAD 重装载值寄存器
- 当计数到0时,重新装载到数值寄存器的值
bit[23~0] 低24位有效
VAL 当前数值寄存器
SysTick 配置库函数
- SysTick 属于内核外设,跟普通外设的中断优先级有些区别,并没有抢占优先级和子优先级的说法;
用库函数编程时,我们只需要使用 SysTick_Config() 进行配置即可,函数如下,在 cm4.h 文件中:
// System Tick Configuration, The function initializes the System Timer and its interrupt, and starts the System Tick Timer.
// param [in] ticks Number of ticks between two interrupts.
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
// 参数检查,重载值最大是24位
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk) { return (1UL); }
/* set reload register */
SysTick->LOAD = (uint32_t)(ticks - 1UL);
NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);
/* Load the SysTick Counter Value */
SysTick->VAL = 0UL;
// 时钟源选择 AHB 168MHz,计数到0时产生中断,使能系统定时器
SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk;
return (0UL);
}
SysTick 初始化函数
如下代码,配置 ticks 为 SystemCoreClock / 1000,即 168K,即计数168K次时,产生一次中断;
而计数一次的时间是:1/CLKAHB,即 1/168M 秒,所以计数168K次用时 1ms,意即 每ms产生一次 SysTick 中断;
在 SysTick 中断处理函数中可以累加经过的 毫秒值,从而达到记录时间的目的;
void SysTick_Init(void)
{
/* SystemFrequency / 1000 1ms中断一次
* SystemFrequency / 100000 10us中断一次
* SystemFrequency / 1000000 1us中断一次
*/
if (SysTick_Config(SystemCoreClock / 1000))
{
/* Capture error */
while (1);
}
}
延时函数 和 SysTick 中断处理函数
static __IO u32 TimingDelay;
void delay_ms(__IO u32 nTime)
{
TimingDelay = nTime;
while (TimingDelay != 0);
}
void TimingDelay_Decrement(void)
{
if (TimingDelay != 0x00)
{
TimingDelay--;
}
}
void SysTick_Handler(void)
{
TimingDelay_Decrement();
}