11.1关于 SysTick 定时器
SysTick定时器(又名系统滴答定时器)是存在于Cortex-M3的一个定时器,只要是ARM Cotex-M系列内核的MCU都包含这个定时器。使用内核的SysTick定时器来实现延时,可以不占用系统定时器,节约资源。由于SysTick是在CPU核内部实现的,跟MCU外设无关,因此它的代码可以在不同厂家之间移植。
本 章 将 使用系统滴答定时器实现延时函数, 注 意 SysTick 用于了 HAL 库的毫秒级延时函数“HAL_Delay()”,不建议日常使用SysTick去作为其它用途,这里只作为演示。
SysTick定时器是一个24位递减定时器,即计数器可以从最大值224开始,每个时钟周期减1,当减到0时,会产生Systick异常,同时再自动重载定时初值,开始新一轮计数。通过设置这个定时初值,就可以实现得到指定时间。如下图 11.1.1 所示,y为定时器初值,然后随着时间增加,值逐渐减小,直至为0,再重新加载初值,如此往复,x1、x2、x3这些时间段,就是我们需要的延时时间。
系统滴答定时器加载值寄存器(STK_LOAD)
在理解系统滴答定时器的工作方式,了解系统滴答定时器的寄存器基本信息后,就可以尝试编写程序了。
11.2硬件设计
系统滴答定时器属于Cortex-M3内核资源,不涉及外部硬件电路。实验中会用到LED灯,电路设计参考前面LED点灯实验。
11.3软件设计
11.3.1.1 软件设计思路
实验目的:使用系统滴答定时器实现自定义延时。
- 分析HAL库的系统滴答定时器配置函数;
- 初始化系统滴答定时器(设置计数初值、使能等);
- 封装延时函数,设置系统滴答定时器中断处理函数;
- 主函数调用验证;
本实验配套代码位于“5_程序源码4_基础重点—SysTick定时器”。
11.3.1.2 软件设计讲解
- 分析HAL库的系统滴答定时器配置函数
在HAL库中,使用“HAL_SYSTICK_Config()”函数配置SysTick的初始值。
代码段 11.3.1 SysTick 配置函数(stm32f1xx_hal_cortex.c)
该函数调用“SysTick_Config()”函数,函数内容如下代码段 11.3.2所示。
代码段 11.3.2 SysTick 配置函数(core_cm3.h)
- 24~27行:判断传入的SysTick初始值是否大于最大值2的24次方;
- 29行:设置SysTick初始值;
- 30行:设置SysTick中断的优先级,默认为最低;
- 31行:将SysTick当前计数值清零;
- 32~34行:设置SysTick的控制和状态寄存器,展开对应的宏,值为“(1
通过对“HAL_SYSTICK_Config()”函数分析,可知只需要传入SysTick初始值,其它的都默认已经设置完成了。
- 初始化系统滴答定时器
假设当MCU工作在72MHz,SysTick也工作在72MHz。时钟在1s内完成周期性变化的次数叫做频率(单位:Hz),因此72MHz则表示1秒SysTick计数72000000次,即1毫秒计数72000次。
因此,如果将72000传入“HAL_SYSTICK_Config()”函数,则SysTick从72000减到0,花费时间为1毫秒,创建函数“SysTickInit()”初始化系统滴答定时器,如代码段 11.3.3 所示。
代码段 11.3.3 初始化 SysTick(driver_systick.c)
- 12行:使用HAL库提供的全局变量“SystemCoreClock”获取当前系统时钟,再根据传入的cycle,计算出
SysTick的初始值; - 25~28行:使用“HAL_SYSTICK_Config()”函数设置SysTick的初始值,并检测是否设置成功;
- 31行:设置滴答定时器中断优先级,这里设置为最高。前面分析“HAL_SYSTICK_Config()”函数,知道该函数也会设置中断优先级,这里重新设置为最高优先级,在当前示例里,SysTick中断的优先级不重要;
- 33行:使能SysTick中断;这里是使能NVIC,而“HAL_SYSTICK_Config()”函数使能的是SysTick;
为了方便修改SysTick的初始值,这里定义几个常见的延时周期,如代码段 11.3.4 所示。当需要延时周期为1毫秒时,传入“CYCLE_1MS”给“SysTickInit()”,则SysTick计数到零花费1毫秒
代码段 11.3.4 定义延时周期(driver_systick.h)
- 封装延时函数,设置系统滴答定时器中断处理函数
创建延时函数“SysTickDelay()”,在该函数里设置自定义全局变量systick_t的初始值,SysTick每计数完一次则进入SysTick中断,将全局变量systick_t的值减1,如代码段 11.3.6 所示。一直到systick_t变为零,结束延时,如代码段 11.3.5 所示。
代码段 11.3.5 SysTick 延时函数(driver_systick.c )
代码段 11.3.6 SysTick 中断处理函数(stm32f1xx_it.c)
- 主函数调用验证
代码段 11.3.7 SysTick 延时点灯(main.c)
- 5行:初始化SysTick,这里传入CYCLE_1MS,则延时函数“SysTickDelay()”的单位为1毫秒;
- 7~16行:初始化LED,调用延时函数“SysTickDelay()”,传入1000,则延时为1秒;
11.4实验效果
本实验对应配套资料的“5_程序源码4_基础重点—SysTick定时器”。打开工程后,编译,下载,可以看到红色LED灯间隔1秒,交替闪烁。读者可修改代码段 11.3.7 中的第5行时钟周期,或者13、15行的延时时间,改变LED灯的闪烁间隔时间。
通过LED展示SysTick的延时结果不够严谨,有条件的读者可以使用示波器或逻辑分析仪测试LED灯对应引脚(PB0,在J21_3引出)的翻转时间,如图 11.4.1 所示,分别修改延时时间10us、1ms、1s后逻辑分析仪测量值。

百问 技术论坛:
http://bbs.100ask.net/
百问 嵌入式视频官 :
https://www.100ask.net/index
百问 开发板:
淘宝:https://100ask.taobao.com/
天猫:https://weidongshan.tmall.com/
技术交流群(鸿蒙开发/Linux/嵌入式/驱动/资料下载)
QQ群:869222007(已满)752871361
单片机-嵌入式Linux交流群:
QQ群:536785813
文章知识点与官方知识档案匹配,可进一步学习相关知识CS入门技能树Linux入门初识Linux24804 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!