您当前的位置: 首页 > 

韦东山

暂无认证

  • 2浏览

    0关注

    506博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

SysTick 定时器

韦东山 发布时间:2021-04-27 13:17:16 ,浏览量:2

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这些时间段,就是我们需要的延时时间。 在这里插入图片描述

假设STM32F103工作在72MHz,即72000000Hz,意味着1s时间内,会计数72000000次。那么1ms则计数72000000/1000=72000次。这个72000就可以作为系统滴答定时器的初始值,将这个值写入系统滴答定时器,定时器在每个时钟周期减1,减到0时,就刚好是1ms,同时产生中断通知,再次加载72000如此反复。HAL库提供“HAL_SYSTICK_Config()”函数去设置这个初始值。

系统滴答定时器控制寄存器比较少,整体比较简单,借助本次机会详细分析一下寄存器和HAL之间是调用关系。系统滴答定时器只有四个控制寄存器:STK_CTRL,STK_LOAD,STK_VAL和STK_CALIB。因 为系统滴答定时器属于Cotex-M3内核的外设,相关寄存器介绍不在《参考手册》,而在《3_STM32F10xx Cortex-M3编程手册》,后简称《编程手册》。

系统滴答定时器控制和状态寄存器(STK_CTRL) 在这里插入图片描述 重点关注Bit[0],用于使能系统滴答定时器,Bit[1]使能系统滴答定时器中断,Bit[2]系统滴答时钟的时钟来源。

系统滴答定时器加载值寄存器(STK_LOAD) 在这里插入图片描述 Bit[23:0],一共24位,用来设置系统滴答定时器的初始值,因此范围为1~ 16777216。

系统滴答定时器当前值寄存器(STK_VAL) 在这里插入图片描述 在这里插入图片描述 Bit[23:0],一共24位,用来获取当前系统滴答定时器的计数值。

系统滴答定时器校准值寄存器(STK_CALIB) 在这里插入图片描述 这个寄存器没用到,可以不用管。此外,当处理器在调试期间被暂停(halt)时,系统滴答定时器也将暂停运作。

在理解系统滴答定时器的工作方式,了解系统滴答定时器的寄存器基本信息后,就可以尝试编写程序了。

11.2硬件设计

系统滴答定时器属于Cortex-M3内核资源,不涉及外部硬件电路。实验中会用到LED灯,电路设计参考前面LED点灯实验。

11.3软件设计 11.3.1.1 软件设计思路

实验目的:使用系统滴答定时器实现自定义延时。

  1. 分析HAL库的系统滴答定时器配置函数;
  2. 初始化系统滴答定时器(设置计数初值、使能等);
  3. 封装延时函数,设置系统滴答定时器中断处理函数;
  4. 主函数调用验证; 本实验配套代码位于“5_程序源码\4_基础重点—SysTick定时器”。
11.3.1.2 软件设计讲解
  1. 分析HAL库的系统滴答定时器配置函数 在HAL库中,使用“HAL_SYSTICK_Config()”函数配置SysTick的初始值。 代码段 11.3.1 SysTick 配置函数(stm32f1xx_hal_cortex.c)
/**
* @brief Initializes the System Timer and its interrupt, and starts the System Tick Timer.
* Counter is in free running mode to generate periodic interrupts.
* @param TicksNumb: Specifies the ticks Number of ticks between two interrupts.
* @retval status: - 0 Function succeeded.
* - 1 Function failed.
*/
uint32_t HAL_SYSTICK_Config(uint32_t TicksNumb)
{
return SysTick_Config(TicksNumb); }

该函数调用“SysTick_Config()”函数,函数内容如下代码段 11.3.2所示。 代码段 11.3.2 SysTick 配置函数(core_cm3.h)

/* ################################## SysTick function ############################################ */
/**
\ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_SysTickFunctions SysTick Functions
\brief Functions that configure the System.
@{
*/
#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U)
/**
\brief System Tick Configuration
\details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
Counter is in free running mode to generate periodic interrupts.
\param [in] ticks Number of ticks between two interrupts.
\return 0 Function succeeded.
\return 1 Function failed.
\note When the variable __Vendor_SysTickConfig is set to 1, then the
function SysTick_Config is not included. In this case, the file device.h
must contain a vendor-specific implementation of this function.
*/
__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
{
if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
return (1UL); /* Reload value impossible */
}
SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
NVIC_SetPriority (SysTick_IRQn, (1UL CTRL = SysTick_CTRL_CLKSOURCE_Msk |
SysTick_CTRL_TICKINT_Msk |
SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
return (0UL); /* Function successful */
}
#endif
  • 24~27行:判断传入的SysTick初始值是否大于最大值2的24次方;
  • 29行:设置SysTick初始值;
  • 30行:设置SysTick中断的优先级,默认为最低;
  • 31行:将SysTick当前计数值清零;
  • 32~34行:设置SysTick的控制和状态寄存器,展开对应的宏,值为“(1
关注
打赏
1658827356
查看更多评论
立即登录/注册

微信扫码登录

0.0383s