文章目录[隐藏]
一、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 所需要的时间为,并且当减到 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 所需要的时间为,并且当减到 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
暂无评论