STM32之系统滴答定时器

一、SysTick(系统滴答定时器)概述

  操作系统需要一个滴答定时器周期性产生中断,以产生系统运行的节拍。在中断服务程序里,基于优先级调度的操作系统会根据进程优先级切换任务,基于时间片轮转系统会根据时间片切换任务。总之,滴答定时器是一个操作系统的“心跳”。

  Cortex-M3在内核部分封装了一个滴答定时器--SysTick,在之前的ARM内核通常是不会把定时器做进内核,定时器都是SOC厂商自己制作的外设。显然,Cortex-M3封装了这么一个定时器,对于将操作系统移植到不同SOC厂商生产的Cortex-M3系类MCU上,带来了极大的方便。Cortex-M3内核统一了这样的一个系统滴答定时器,移植操作系统的时候可以使用内核的定时器,而忽略掉不同厂商生产定时器带来的分歧。

二、SysTick control and status
register(STK_CTRL)

  SysTick的控制是极其简单的,它的控制和状态都汇聚在同一个寄存器STK_CTRL上。

  STK_CTRL的每一位的含义英文解释都是很清晰的,不必多说。需要额外讨论的是COUNTFLAG标志位,这个标志位代表的含义是:当计数为0时,也即STK_VAL计数至0时,此标志位置1。

  经过笔者一番摸索,对此位有更多的看法。

COUNTFLAG:  

1、此位与SysTick的中断无关,不是中断标志位,可以算作事件标志位(计数至0事件)。

2、此位可以用作软件查询

3、读写此寄存器都会硬件自动更新COUNTFLAG的值,当然此位的值软件也是可以改写的。也就是说,倘若我们轮训查看COUNTFLAG是否置1(也就是计数是否结束)。当SysTick硬件上计数为0,COUNTFLAG因此硬件自动置1。在我们软件读取STK_CTRL的时候,其实SysTick的STK_VAL的值已经不是0(因为自动重装,并且可能计时几个CLK了)。这个时候我们读取到了COUNTFLAG的标志位的1,同时也将COUNTFLAG自动清零。

三、精准延时函数

1、函数实现思路

  函数实现使用“轮询状态位COUNTFLAG”实现精准延时节拍10us。

  在使用的时候,首先调用函数SysTick_Init配置SysTick的定时周期为10us。在延时函数中,当启动定时器后,就调用函数SysTick_GetFlagStatus轮询是否定时10us结束,如果结束就更新一下延时节拍变量nTime。

  由于SysTick定时器自动重装计数器初值,而且SysTick_GetFlagStatus在检测到SET的时候,COUNTFLAG也自动清理。所以软件不必装定时器初值,也不必手动清除标志位COUNTFLAG。

2、函数实现代码


 #include "bsp_sysTick.h"

/**
* @brief 读取SysTick的状态位COUNTFLAG
* @param 无
* @retval The new state of USART_FLAG (SET or RESET).
*/
static FlagStatus SysTick_GetFlagStatus(void)
{
if(SysTick->CTRL&SysTick_CTRL_COUNTFLAG_Msk)
{
return SET;
}
else
{
return RESET;
}
}

/**
* @brief 清除SysTick的状态位COUNTFLAG
* @param 无
* @retval 无
*/
static void SysTick_ClearFlag(void)
{
SysTick->CTRL &= ~ SysTick_CTRL_COUNTFLAG_Msk;
}

/**
* @brief 配置系统滴答定时器 SysTick
* @param 无
* @retval 1 = failed, 0 = successful
*/
uint32_t SysTick_Init(void)
{
/* SystemFrequency / 1000 1ms中断一次
* SystemFrequency / 100000 10us中断一次
* SystemFrequency / 1000000 1us中断一次
*/

/* 设置定时周期为10us */
if (SysTick_Config(SystemCoreClock / 100000))
{
/* Capture error */
return (1);
}

/* 关闭滴答定时器且禁止中断 */
SysTick->CTRL &= ~ (SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk);
return (0);
}

/**
* @brief us延时程序,10us为一个单位
* @param
* @arg nTime: Delay_us( 1 ) 则实现的延时为 1 * 10us = 10us
* @retval 无
*/
void Delay_us(__IO uint32_t nTime)
{
/* 清零计数器并使能滴答定时器 */
SysTick->VAL = 0;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;

for( ; nTime > 0 ; nTime--)
{
/* 等待一个延时单位的结束 */
while(SysTick_GetFlagStatus() != SET);
}

/* 关闭滴答定时器 */
SysTick->CTRL &= ~ SysTick_CTRL_ENABLE_Msk;
}

3、函数的优点和缺陷

优点:

  使用轮询法实现精准延时是可靠的,因为硬件自动重装定时器初值,只要我们在下一次计数结束(为0)之前,将节拍计数变量nTime更新,那么这个延时函数就是可靠的。

  使用轮询法的另一个好处是没有用到全局变量,完全是局部变量搞定了所需功能。倘若使用中断延时,必须利用全局变量给精准延时函数传递参数。

缺陷:

  由于使用的是轮询法,有可能被其他的中断打断,假设其他的中断的服务时间有很长,使得“在下一次计数结束(为0)之前,没有将节拍计数变量nTime更新”,那么延时的时间将要增长。

参考资料:《STM32F10xxx Cortex-M3 programming manual.pdf》

     《STM32库开发实战指南》

STM32之系统滴答定时器,布布扣,bubuko.com

时间: 2024-10-04 23:09:16

STM32之系统滴答定时器的相关文章

STM32 的系统滴答定时器( Systick) 彻底研究解读

作者:王健 前言 SysTick 比起那些 TIM 定时器可以说简单多啦~~~~~哥的心情也好了不少, 嘎嘎!! ARM Cortex-M3 内核的处理器内部包含了一个 SysTick 定时器,它是一个24 位的倒计数定时器,注意,是倒计数! 当计到 0 时它就会从 LOAD 寄存器中自动重装载定时初值.只要不把 CTRL 寄存器中的 ENABLE 为清 0,它就永不停息! 遗憾的是,SysTick 定时器在<STM32 参考手册>里一个屁都没放,只有在<ARM Cortex-M3 技术

《零死角玩转STM32》-18-SysTick系统滴答定时器

参考资料:<STM32F4XX内核参考手册>:4.4.8-SHPRX(System Handler Priority Register)与4.5- System Tick Timer. 1. 简介 SysTick是一个24Bit的系统定时器,属于CM4内核的外设,相关寄存器与部分库函数中core_cm4.h中定义.SysTick一般用于操作系统,用于产生时基,维持OS的心跳. 如下所示:当计数器被使能(STC_CTRL: Bit0-ENABLE)并且计数器到0时,STK_LOAD中的预设值会被

Systick系统滴答定时器

一个24 位的倒计数定时器,计到0 时,将从RELOAD 寄存器中自动重装载定时初值.只要不把它在SysTick 控制及状态寄存器中的使能位清除,就永不停息,即使在睡眠模式下也能工作. 四个寄存器: CTRL            SysTick 控制和状态寄存器 LOAD           SysTick 自动重装载除值寄存器 VAL              SysTick 当前值寄存器 CALIB            SysTick 校准值寄存器 CTRL中的时钟源选择: void H

STM32系统时钟配置,滴答定时器配置相关

以后实在找不到问题出现在哪里,注意还有这么个地方需要留意: 今天在调试滴答定时器,找半天找不到延时为什么不准确,原来以前的代码中,"SYSCLK_FREQ_72MHz"被写成了64MHz了,把这里重新改为72MHz就可以了,走过的路过的,希望这个提醒可以对大家有所帮助,不过大家还是要看实际情况. 原文地址:https://www.cnblogs.com/data-base-of-ssy/p/9513371.html

系统定时器(滴答定时器)

  ARM Cortex-M3内核中有一个Systick定时器,它是一个24位(0~(2^24-1))的倒计数定时器,当计数到0时,它就会从Load寄存器中自动重装定时初值,只要不把CTRL寄存器中的ENABLE清0,它就永不停.   时钟源可以是内部时钟FCLK或外部时钟STCLK        配置系统定时器步骤:      ①选择时钟源       ②设定重载数(reload)       ③开启中断       ④启动滴答定时器 在core_cm3.h中有关于系统定时器的配置:    

内核里获得系统版本,与系统滴答时间

获得系统版本号.内核编程难免使用硬编码,以及使用一些高版本系统才出现的函数.为了使得驱动能在低版本的系统上正常运行,就需要根据不同系统做不同处理了. VOID GetVersion() { ULONG NtBuildNumber; RTL_OSVERSIONINFOW osi; osi.dwOSVersionInfoSize=sizeof(RTL_OSVERSIONINFOW); RtlFillMemory(&osi,sizeof(RTL_OSVERSIONINFOW),0); RtlGetVe

STM32学习笔记9(SysTick滴答时钟)

我不得不说意法半导体确实有点风骚!甚至有点变态.我对ST文档 STM32F10XXX参考手册的编辑水平真是不敢恭维.手册中好多说明都是含糊不清,甚至将好多对初学者来说很重要的地方都一笔带过,让人着实摸不着头脑.比如前面我说过的关于NVIC嵌套向量中断控制器的介绍,这部分我认为是非常重要的,但当你看完他这部分介绍,你根本不会设置中断服务程序,他有哪些寄存器都不知道,更别说去设置了,NVIC的详细介绍是在Cotex-M3中有详细的介绍,不多说.今天我们说的是systick定时器. systick定时

6.SysTick系统时钟滴答实验(stm32中断入门)

系统时钟滴答实验很不难,我就在面简单说下,但其中涉及到了STM32最复杂也是以后用途最广的外设-NVIC,如果说RCC是实时性所必须考虑的部分,那么NVIC就是stm32功能性实现的基础,NVIC的难度并不高,但是理解起来还是比较复杂的,我会在本文中从实际应用出发去说明,当然最好去仔细研读宋岩翻译的<Cortex-M3权威指南>第八章,注意这不是一本教你如何编写STM32代码的工具书,而是阐述Cortex-M3内核原理的参考书,十分值得阅读. SysTick系统时钟的核心有两个,外设初始化和S

DSP/BIOS使用之初窥门径——滴答时钟及烧写Flash

操作平台和环境 DSP型号:TMS320C6713 仿真器:XDS510PLUS Flash型号:AM29LV800BT或AM29LV800BT都试过(一般接口一样,差别不大) RAM型号:MT48LC16M16A2P(注意16位数据线接口) DSP/BIOS库:V5.31.02 CSL库:(假定读者已经会使用了) 边写LED程序,边聊聊操作系统的滴答时钟 在上篇文章DSP-BIOS使用入门的基础上,这里用用DSP/BIOS操作系统的CLK和PRD模块,这两个模块涉及到硬件定时器,我们使用仿真器