HAL库与Cubemx系列|Systick-系统滴答定时器详解
Systick是什么?
关于Systick,在Context-M3权威指南中如此描述:
SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号: 15)。在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基。例如,为多个任务许以不同数目的时间片,确保没有一个任务能霸占系统;或者把每个定时器周期的某个时间范围赐予特定的任务等,还有操作系统提供的各种定时功能,都与这个滴答定时器有关。因此,需要一个定时器来产生周期性的中断,而且最好还让用户程序不能随意访问它的寄存器,以维持操作系统“心跳”的节律。
SysTick定时器能产生中断, CM3为它专门开出一个异常类型,并且在向量表中有它的一席之地。它使操作系统和其它系统软件在CM3器件间的移植变得简单多了,因为在所有CM3产品间对其处理都是相同的。
SysTick 是一个 24 位的倒计数定时器,当计到 0 时,将从 RELOAD 寄存器中自动重装载定时初值。只要不把它在 SysTick 控制及状态寄存器中的使能位清除, 就永不停息,图 13.1 中小结了 SysTick的相关寄存器。



这是定义在core_cm3.h中的结构体:

SysTick 的最大使命,就是定期地产生异常请求,作为系统的时基。 OS 都需要这种“滴答” 来推动任务和时间的管理。 如欲使能 SysTick 异常, 则把 STCSR.TICKINT 置位。 另外, 如果向量表被重定位到 SRAM 中,还需要为 SysTick 异常建立向量,提供其服务例程的入口地址。
Systick如何使用?
前面说了那么多,Systick到底是什么,小伙伴们是不是已经明白了呢?其实,简单一句话,就是“心跳”,CPU以心跳为依据分配要做的事情,嘀哒...嘀哒...嘀哒...
cubemx配置Systick
来来来,实践是检验真理的唯一标准,没有实践的理论就是耍流氓~~
Systick是系统的“心跳”,为系统提供着时基来源,cubemx中是已经为我们勾选了的,默认的时基是来源于Systick

当然了,条条大路通罗马,Systick可以作为时基,但却不是唯一的,不信你看,实际上有这么多的定时器都可以用来作为时基来源的,移植过操作系统的小伙伴一定不陌生,本次,我们只介绍关于Systick的功能~

- 时钟配置
关于时钟配置的详细讲解,请参看:CubeMX的正确打开方式 一文
- 串口配置
关于串口配置的详细解释,请参看:CubeMX的正确打开方式 一文
- Systick中断
可以看到,Systick的中断是默认已经开启了的,直接使用即可

Systick代码详细解析
结合生成的工程,来看看Systick的时钟配置以及工作流程,systick首先在HAL_Init()函数中被提到,被cue来干嘛呢,接下来跟进去看看

从英文解释中(别说看不懂哈),Systick被配置为系统时基,并且被配置为了1ms,做技术,要有刨根问底的精神,奥利给,继续跟进去看看

这段英文解释很重要,外设中断进程调用HAL_Delay的时候,要特别注意中断的优先级问题,如果systick的中断优先级低于外设中断优先级,会导致一直在外设中断中阻塞,如果外设中调用了HAL_Delay(),一定要保证Systick的中断优先级高于外设中断优先级,但是,小飞哥是极其不建议在中断中调用HAL_Delay()函数的

明明是在说Systick的事情,怎么牵扯到HAL_Delay()函数了呢,那就再来看看,HAL_Delay()是如何实现的呢?打开HAL_Delay(),可以看到,实际上是通过uWTick这个全局变量不断增加,比较来实现的延时,那么uWTick是在哪里增加的呢?

好家伙,转了十万八千里,最终还是在Systick中断中进行增加的,默认配置的是Systick 1ms中断,这下知道了我们调用的HAL_Delay(),为什么是1ms了吧,绕了那么一大圈,是不是有点想打人呢~

默认配置的是1ms中断周期,那我们HAL_Delay()的最小单位是1ms,如果想获得1us的中断周期,该如何调整呢?且往下看,这是我们自定义的systick周期配置函数,一步一步来看

先来看systick的时钟来源,时钟来源为HCLK或者是HCLK的8分频,小飞哥实验选择的是HCLK,72MHZ,确定了systick的时钟源,接下来配置systick的中断周期
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);


再来看这个函数,分析之前,我们先来看看systick的中断周期时间是怎么计算的,T=ReloadValue10001/72000000ms
这是默认的配置1ms,主频是72MHZ,uwTickFreq默认是1KHZ,根据上面的分析计算,算下来T = (72MHZ/1000)1/72MHZ=1000/72MHZ(1/72MHZ)=1/1000s=1ms,你看懂了吗?
HAL_SYSTICK_Config(SystemCoreClock / (1000U / uwTickFreq)


根据上面的分析,我们想要1us、10ms、100ms....的中断周期怎么办,那就根据上面的计算公式算吧,那这么修改后,HAL_Delay不就可以实现us延时了嘛,实现当然是能实现,但中断是不是过于频繁了呢,1us一个中断诶,那怎么实现呢,请查看,关于HAL库us延时的3种实现方式
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000); //1ms

到此,关于systick的工作流程就算是介绍差不多了,还有最后一步,Systick中断回调函数需要添加到中断回调句柄中

可以看到systick中断回调函数依然是_weak修饰符,意思就是我们自己一个一样名字的函数,不会报错

我们自己重新定义回调函数,处理中断事务,好的编程习惯,中断置标志,所有的逻辑处理放在中断外处理,建议这样做


while中不断查询标志

测试结果
间隔100ms,打印systick test,测试OK,over

关于Embeded-party
欢迎加入群聊Embeded-party,这里有一群可爱的人儿,很多有意思的设计,等着你的加入哦


资料获取
公众号后台回复,systick,即可获得源码哦~
HAL库与Cubemx系列|Systick-系统滴答定时器详解的更多相关文章
- STM32 - SYSTICK(系统滴答定时器)
SysTick定时器被捆绑在NVIC中,用于产生SYSTICK异常(异常号:15).在以前,大多操作系统需要一个硬件定时器来产生操作系统需要的滴答中断,作为整个系统的时基.例如,为多个任务许以不同数目 ...
- 系统滴答定时器(SysTick)中断配置
系统滴答定时器(SysTick)中断配置 在STM32标准库中是通过SysTick_Config()函数配置时钟中断的,然后SysTick_Handler()函数自动定时触发其中的函数. if(Sys ...
- STM32 的系统滴答定时器( Systick) 彻底研究解读
作者:王健 前言 SysTick 比起那些 TIM 定时器可以说简单多啦~~~~~哥的心情也好了不少, 嘎嘎!! ARM Cortex-M3 内核的处理器内部包含了一个 SysTick 定时器,它是一 ...
- Cortex-M0系统滴答定时器Systick详解
上图是LPC1114系统滴答定时器(SysTick)的结构图.系统滴答定时器位于Cortex-M0内核中,也就是说,不论是LPC1114,还是其他的Cortex-M0内核单片机,都有这个系统定时器.其 ...
- STM32之系统滴答定时器
一.SysTick(系统滴答定时器)概述 操作系统需要一个滴答定时器周期性产生中断,以产生系统运行的节拍.在中断服务程序里,基于优先级调度的操作系统会根据进程优先级切换任务,基于时间片轮转系统会根据时 ...
- liunx驱动----系统滴答时钟的使用
2019-3-12系统滴答定时器中断使用 定义一个timer 其实就是使用系统的滴答定时器产生一个中断. 初始化timer init_timer函数 实现如下 void fastcall ini ...
- STM32 系统滴答计时器
;//us与系统滴答的被乘数 ;//ms与系统滴答的被乘数 ;//系统运行秒数 /** * @description:系统滴答计时系统初始化 * @param 无 * @retval 无 */ voi ...
- libCURL开源库在VS2010环境下编译安装,配置详解
libCURL开源库在VS2010环境下编译安装,配置详解 转自:http://my.oschina.net/u/1420791/blog/198247 http://blog.csdn.net/su ...
- Java 8系列之Stream的基本语法详解
本文转至:https://blog.csdn.net/io_field/article/details/54971761 Stream系列: Java 8系列之Stream的基本语法详解 Java 8 ...
随机推荐
- JSONP跨域资源共享的安全问题
目录 关于 JSONP 一.JSON 劫持 二.Callback 可定义导致的安全问题 三.其他文件格式( Content-Type )与 JSON 四.防御 摘自:http://blog.known ...
- 影子卫士汉化语言包 res.ini
[translate];authorinfo=Simplified Chinese Translation 简体翻译 by: Clarence [common]0=Shadow Defender 10 ...
- JetBrains系列软件用法
IDEA JSON格式化 IDEA的JSON_Formatter插件,下载地址 安装方式:File->Settings->Plugins,然后选择INstall plugin from d ...
- FileItem的部分方法解释
FileItem的部分方法: boolean isFormField() isFormField() 方法用来判断FileItem对象里面封装的数据是一个普通文本表单字段,还是一个文件表单字段.如果是 ...
- Ubuntu部署项目
一.Ubuntu目录结构 目录 说明 bin 存放二进制可执行文件(ls,cat,mkdir等) .exe== boot 存放用于系统引导时使用的各种文件 开机引导 dev 用于存放设备文件 打印机啥 ...
- SQL Server 查看进程阻塞及处理
修改或删除数据前先备份,先备份,先备份(重要事情说三遍)! 1.首先,查看线程,分析是否存在阻塞进程,blocked>0都是当前被阻塞的进程 SELECT * FROM sysprocesse ...
- 进程间IPC通信-stop waiting for thing to happen,go out and make them happen!!!
进程间通信: System V IPC对象: ipcs -q:查看消息队列 ipcs -m:查看共享内存 ipcs -s:查看信号灯集 ipcrm -q:删除消息队列 ipcrm -m:删除共 ...
- 什么是环境变量,Linux环境变量及作用 echo
什么是环境变量,Linux环境变量及作用 < Linux命令的执行过程是怎样的?(新手必读)Linux PATH环境变量是什么,有什么用?(入门必读) > <Linux就该这么学&g ...
- mpstat命令
mpstat命令 mpstat命令指令主要用于多CPU环境下,它显示各个可用CPU的状态系你想.这些信息存放在/proc/stat文件中.在多CPUs系统里,其不但能查看所有CPU的平均状况信息,而且 ...
- linux patch中的p0和p1的区别
命令patch的主要作用是生成diff文件和应用diff文件.举个例子来讲,当发现某个程序出现bug需要打补丁时,patch便是一个好工具. diff文件头: [root@localhost kern ...