STM32如何利用系统滴答定时器实现精准延时

        系统滴答定时器是捆绑在芯片内核里面的资源,利用系统定时器可以实现跨越不同平台,不同型号,不同库函数的各种MCU来实现统一的精准的计时,只要基于同一内核就可以实现很好的移值,例如STM32F103C8T6是基于Arm的Cortex-M3的内核,在对应的"cm3_core.h"内核寄存器描述的头文中可以找到关于滴答定时器的相关寄存器配置,基于滴答定时器的操作只需要对内核中寄存器进行配置,不需要经过外设寄存器和库函数等途径,因此,无论是基于寄存器开发,库函数开发,还是HAL库开发都可以很好的移植相关程序,那么,我们该如何实现利用内核里面的滴答定时器资源来实现精准延时?

         首先,我们需要了解关于滴答定时器的相关寄存器配置。

#define SysTick             ((SysTick_Type *)       SysTick_BASE)
typedef struct
{
  __IO uint32_t CTRL;             /*!< Offset: 0x00  SysTick Control and Status Register */
  __IO uint32_t LOAD;             /*!< Offset: 0x04  SysTick Reload Value Register       */
  __IO uint32_t VAL;              /*!< Offset: 0x08  SysTick Current Value Register      */
  __I  uint32_t CALIB;            /*!< Offset: 0x0C  SysTick Calibration Register        */
} SysTick_Type;

上述代码中可以看出SysTick是结构体SysTick_Type类型的指针,通过->可以引出结构体内部的成员,进一步对相应寄存器进行配置。

①CTRL:控制与状态寄存器;该寄存器第0位使能定时器,第一位一般给0,不开启结束异常中断,第二位给1,选择内核时钟;通过对第16位的轮询读取可以判断定时器是否计数到0,该位作为定时器的状态控制位;

②LOAD:重装载数值寄存器;配合系统内核时钟来实现给定单位时间的周期性的定时。

#elif defined SYSCLK_FREQ_72MHz
  uint32_t SystemCoreClock         = SYSCLK_FREQ_72MHz;        /*!< System Clock Frequency (Core Clock) */
extern uint32_t SystemCoreClock;          /*!< System Clock Frequency (Core Clock) */

在system_stm32f10x.h系统时钟配置头文件中将SystemCoreClock声明成外部变量,不同型号的系统内核时钟不同,当我们可以通过宏定义的方式来实现跨型号的移植;

③VAL:当前数值寄存器;可读可写,写时可以使它清零,该位便于对滴答定时器进行初始化操作。

              其次,我们要来了解滴答定时器的工作流程;

        最后,我们就可以实现精准延时的模块化代码编写与移植了,下面代码是基于江协科技的延时函数的改编;

#include "stm32f10x.h"

/**
  * @brief  微秒级延时
  * @param  xus 延时时长,范围:0~233015
  * @retval 无
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = SystemCoreClock/1000000 * xus;		    //设置定时器重装值
	SysTick->VAL = 0x00;					                //清空当前计数值
	SysTick->CTRL = 0x00000005;				                //设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	                //等待计数到0
	SysTick->CTRL = 0x00000004;				                //关闭定时器
}

/**
  * @brief  毫秒级延时
  * @param  xms 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒级延时
  * @param  xs 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
} 

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值