蓝桥杯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相关寄存器

寄存器名称描述
CTRLSysTick控制及状态寄存器
LOADSysTick重装载数值寄存器
VALSysTick当前数值寄存器
CALIBSysTick校准数值寄存器

设: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则跳出循环、跳出延时函数,执行下一个函数;否则继续循环等待。

好的,我可以为您解答关于STM32系统滴答定时器systick)应用的问题。 系统滴答定时器systick)是STM32中一个非常重要的计时器,它是一个24位的递减计数器,每当计数器减为0时,会触发一个中断。它通常用于操作系统的时间片轮转、延时函数的实现等。 在STM32中,我们可以通过如下代码使能系统滴答定时器: ```c // 使能系统滴答定时器 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; ``` 然后,我们可以通过如下代码设置系统滴答定时器的时钟源和计数器值: ```c // 设置系统滴答定时器的时钟源和计数器值 SysTick->CTRL &= ~SysTick_CTRL_CLKSOURCE_Msk; // 使用处理器时钟作为时钟源 SysTick->LOAD = SystemCoreClock / 1000 - 1; // 设置计数器值为1ms ``` 在这段代码中,我们将系统滴答定时器的时钟源设置为处理器时钟,每次计数器减1代表1个处理器时钟周期的时间。然后我们将计数器的初值设置为`SystemCoreClock / 1000 - 1`,这里的`1000`代表我们希望系统滴答定时器每1ms中断一次。 最后,我们需要在中断服务函数中处理系统滴答定时器中断: ```c void SysTick_Handler(void) { // 处理系统滴答定时器中断 } ``` 在中断服务函数中,我们可以编写自己的代码来处理系统滴答定时器中断。例如,可以实现一个简单的延时函数: ```c void delay_ms(uint32_t ms) { uint32_t i; for (i = 0; i < ms; i++) { while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); // 等待计数器减为0 } } ``` 这个函数可以让程序在执行到它的时候暂停一段时间,等待系统滴答定时器中断触发一定次数后再继续执行。 希望这些代码可以帮助您更好地理解STM32系统滴答定时器的应用。如果您还有其他问题,请随时提出。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不爱学习的刘.Sir

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值