蓝桥杯STM32G431学习之SysTick系统滴答定时器

一、SysTick系统滴答定时器寄存器

SysTick系统滴答定时器位于Cortex M4内核中。

在编程LED时,使用到了 HAL_Delay(500) 函数,此函数利用的就是SysTick系统滴答定时器

LED_Show(0x00);
HAL_Delay(500);
LED_Show(0xFF);
HAL_Delay(500);

SysTick用于提供时间基准,常用于对时间要求严格的情况,其意义十分重要。

Systick是一个24位的定时器,一次最多可以计数 2^24 个时钟脉冲,这个脉冲计数值保存在当前计数值寄存器 STK_VAL(Systick current value register)中,只能向下计数,每接收到一个时钟脉冲,STK_VAL 的值就会向下减1,当减到0时,硬件会自动把重装载寄存器 STK_LOAD(Systick reload value register)中保存的数据加载到 STK_VAL,重新开始向下计数如果 STK_VAL 的值被减至0时,会触发异常产生中断。

Systick相关寄存器

寄存器名称 描述
CTRL SysTick控制及状态寄存器
LOAD SysTick重装载数值寄存器
VAL SysTick当前数值寄存器
CALIB SysTick校准数值寄存器

设:VAL中的数值为 80,脉冲频率为 80MHz,则VAL由 80 减到 0 所需要的时间为80/80MHz=1us,并且当减到 0 时会触发中断(相当于 1us 定时器),同时 LOAD 的值也会重新载入到VAL中。

问:Systick的脉冲频率从何而来呢?

在 STM32CubeMX 中配置好时钟树后,时钟频率会输入到 Cortex System timer内核时钟 。而 SysTick 又属于内核,故给到 SysTick 的脉冲频率来自于此。

二、代码部分

1. 中断函数

HAL_Init() 中使用到了 SysTick,跳转到函数所在位置,我们可以看到这么一句话:

/* Use SysTick as time base source and configure 1ms tick (default clock after Reset is HSI) */

说明使用SysTick作为时基源,并配置1ms定时(重置后的默认时钟为 HSI)。但是 HSI 为内部时钟,而我们使用的是外部时钟,此1ms定时是不精准的。

精准的1ms定时在中,从此函数逐渐深入到 core_cm4.h 中就有详细的SysTick配置。

LOAD寄存器 和 VAL寄存器 的值都在此函数中配置好了。

在while(1)循环中,除了在执行我们编程的函数外,内核还会不断的产生1ms中断(只是我们看不见),中断函数中。

中断函数

中断函数中 uwTick 会每1ms加1。

  • uwTick 是一个非常重要的变量
  • uwTickFreq 的值为1(可跳转深入查看)。

2. uwTick的作用

HAL_Delay() 中的 HAL_GetTick() 的值来自 uwTick,Delay 的值用户自定义(这里以500为例)。

while ((HAL_GetTick() - tickstart) < wait)
{
}
  • HAL_GetTick() 为uwTick,随时都在变化,每1ms就加1。
  • tickstart 为 HAL_GetTick() 最初的值(即进入中断时uwTick的值),固定不变。
  • HAL_GetTick() 与 tickstart 的差值若小于用户定义的500,则继续循环等待;若超过500,则跳出循环(即跳出HAL_Delay() ),执行下一个函数。

SysTick滴答定时器总结:

延时函数HAL_Delay()使用了SysTick滴答定时器。

1. 利用SysTick产生中断,使uwTick每1ms加1。

2. 将uwTick的值赋值到HAL_Delay()中,判断是否达到500ms(已等待时间产生中断的那个时刻差值)。

3. 若以达到500ms则跳出循环、跳出延时函数,执行下一个函数;否则继续循环等待。

版权声明:本文为CSDN博主「不爱学习的刘.Sir」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46409367/article/details/120936778

一、SysTick系统滴答定时器寄存器

SysTick系统滴答定时器位于Cortex M4内核中。

在编程LED时,使用到了 HAL_Delay(500) 函数,此函数利用的就是SysTick系统滴答定时器

LED_Show(0x00);
HAL_Delay(500);
LED_Show(0xFF);
HAL_Delay(500);

SysTick用于提供时间基准,常用于对时间要求严格的情况,其意义十分重要。

Systick是一个24位的定时器,一次最多可以计数 2^24 个时钟脉冲,这个脉冲计数值保存在当前计数值寄存器 STK_VAL(Systick current value register)中,只能向下计数,每接收到一个时钟脉冲,STK_VAL 的值就会向下减1,当减到0时,硬件会自动把重装载寄存器 STK_LOAD(Systick reload value register)中保存的数据加载到 STK_VAL,重新开始向下计数如果 STK_VAL 的值被减至0时,会触发异常产生中断。

Systick相关寄存器

寄存器名称 描述
CTRL SysTick控制及状态寄存器
LOAD SysTick重装载数值寄存器
VAL SysTick当前数值寄存器
CALIB SysTick校准数值寄存器

设:VAL中的数值为 80,脉冲频率为 80MHz,则VAL由 80 减到 0 所需要的时间为80/80MHz=1us,并且当减到 0 时会触发中断(相当于 1us 定时器),同时 LOAD 的值也会重新载入到VAL中。

问:Systick的脉冲频率从何而来呢?

在 STM32CubeMX 中配置好时钟树后,时钟频率会输入到 Cortex System timer内核时钟 。而 SysTick 又属于内核,故给到 SysTick 的脉冲频率来自于此。

二、代码部分

1. 中断函数

HAL_Init() 中使用到了 SysTick,跳转到函数所在位置,我们可以看到这么一句话:

/* Use SysTick as time base source and configure 1ms tick (default clock after Reset is HSI) */

说明使用SysTick作为时基源,并配置1ms定时(重置后的默认时钟为 HSI)。但是 HSI 为内部时钟,而我们使用的是外部时钟,此1ms定时是不精准的。

精准的1ms定时在中,从此函数逐渐深入到 core_cm4.h 中就有详细的SysTick配置。

LOAD寄存器 和 VAL寄存器 的值都在此函数中配置好了。

在while(1)循环中,除了在执行我们编程的函数外,内核还会不断的产生1ms中断(只是我们看不见),中断函数中。

中断函数

中断函数中 uwTick 会每1ms加1。

  • uwTick 是一个非常重要的变量
  • uwTickFreq 的值为1(可跳转深入查看)。

2. uwTick的作用

HAL_Delay() 中的 HAL_GetTick() 的值来自 uwTick,Delay 的值用户自定义(这里以500为例)。

while ((HAL_GetTick() - tickstart) < wait)
{
}
  • HAL_GetTick() 为uwTick,随时都在变化,每1ms就加1。
  • tickstart 为 HAL_GetTick() 最初的值(即进入中断时uwTick的值),固定不变。
  • HAL_GetTick() 与 tickstart 的差值若小于用户定义的500,则继续循环等待;若超过500,则跳出循环(即跳出HAL_Delay() ),执行下一个函数。

SysTick滴答定时器总结:

延时函数HAL_Delay()使用了SysTick滴答定时器。

1. 利用SysTick产生中断,使uwTick每1ms加1。

2. 将uwTick的值赋值到HAL_Delay()中,判断是否达到500ms(已等待时间产生中断的那个时刻差值)。

3. 若以达到500ms则跳出循环、跳出延时函数,执行下一个函数;否则继续循环等待。

版权声明:本文为CSDN博主「不爱学习的刘.Sir」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_46409367/article/details/120936778

生成海报
点赞 0

不爱学习的刘.Sir

我还没有学会写个人说明!

暂无评论

相关推荐

基于STM32设计的实时心率检测仪

一、开发环境介绍 主控芯片:  STM32F103ZET6 代码编程软件: keil5 心率检测模块: PulseSensor WIFI模块: ESP8266 --可选的。直接使用串口有线传输给上位机也可以。 上位机:  C&#xff