STM32CubeMX-27(补充) | 系统滴答定时器Systick的使用
本篇文章主要介绍STM32中Systick定时器的使用以及HAL_Delay函数的原理。
1. 准备工作
硬件准备
首先需要准备一个开发板,这里我准备的是STM32L4的开发板(小熊派IoT开发套件):
软件准备
需要安装好Keil - MDK及芯片对应的包,以便编译和下载生成的代码;
2.生成MDK工程
如果使用的是STM32F1系列,请先看这篇文章!!!(STM32CubeMX生成F1的工程中造成 下载器无法下载 问题的解决方案)
选择芯片型号
打开STM32CubeMX,打开MCU选择器:
搜索并选中芯片STM32L431RCT6
:
配置时钟源
如果选择使用外部高速时钟(HSE),则需要在System Core中配置RCC; 如果使用默认内部时钟(HSI),这一步可以略过;
这里我都使用外部时钟:
配置GPIO引脚
查看小熊派开发板的原理图,如下:
所以接下来我们选择配置PC13
引脚:
给PC13引脚设置一个user_label:
系统滴答定时器Systick
SysTick 是一个24位的向下计数定时器,当计到0时,将从RELOAD寄存器中自动重装载定时初值并继续计数,且同时触发中断,SysTick 的主要作用是作为系统的时基,产生一个周期性的中断信号。
STM32CubeMX使用的是HAL库,默认已经开启,也可以选择其它的定时器作为系统时基:
中断默认使能,无法关闭:
配置时钟树
STM32L4的最高主频到80M,所以配置PLL,最后使HCLK = 80Mhz
即可:
需要注意,其中To Cortex System timer
这一路是Systick的时钟频率,有/1
和/8
两种选择,这里我们使用8分频:
生成工程设置
代码生成设置
最后设置生成独立的初始化文件:
生成代码
点击GENERATE CODE
即可生成MDK-V5工程:
3. 在MDK中编写、编译、下载用户代码
自动生成的代码
STM32CubeMX会自动生成Systick相关的代码,其中比较重要的有:
① 默认Systick频率值设定:
频率设定有三个值,在stm32l4xx_hal.h
文件中:
② Systick默认中断服务函数
HAL_IncTick函数会把当前系统中定义的计数值变量递加,在stm32l4xx_hal.c
文件中,实现如下:
编写用户代码
HAL库中还定义了一个函数 HAL_GetTick(),使用此API可以获取到当前系统中的计数值,定义如下:
接下来使用此API来编写LED闪烁程序。
在main.c函数中首先定义一个32位的uint型变量,用于存放计数起始值:
/* USER CODE BEGIN 1 */
uint32_t tickstart;
/* USER CODE END 1 */
然后在while(1)循环中调用 HAL_GetTick() 来获取当前的计数值,通过比较当前计数值和起始值即可起到延时的作用:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//获取延时起始值
tickstart = HAL_GetTick();
//死循环比较,直到到达延时值,每次1ms,1000次为1s
while ((HAL_GetTick() - tickstart) < 1000);
//翻转LED
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
}
上面的这种应用方式比较准确,但系统进入了死循环,还有一种比较灵活的使用方式:
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
//翻转LED
if(HAL_GetTick() % 1000 == 0)
{
HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
}
}
这样就不会堵塞CPU了。
实验现象
编译下载之后,即可看到LED按1s的间隔闪烁:
补充 —— HAL_Delay的实现原理
最开始使用HAL库的时候,觉得 HAL_Delay 简直太方便了,其实 HAL_Delay 也是依靠系统的时基信号来实现的,在stm32l4xx_hal.c文件中,实现如下:
可以看到它采用的还是死等的方式,所以相比起来,还是第二种方式应用起来更加灵活,方便,喜欢文章的话,点个赞鼓励一下吧,笔芯~
推荐阅读:
STM32CubeMX原创教程(已有27篇) mculover666,公众号:Mculover666STM32CubeMX系列教程
更多精彩文章及资源,请关注我的微信公众号:『mculover666』。