STM32 SYSTick高精度延时功能代码实现

这篇具有很好参考价值的文章主要介绍了STM32 SYSTick高精度延时功能代码实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

本篇文章将给大家讲解一下SYSTICK滴答定时器,以及讲解使用滴答定时器来实现高精度延时功能的代码。

一、SYSTick定时器介绍

SysTick定时器是嵌入式系统中常见的一个系统定时器,在ARM Cortex-M微控制器中广泛使用。下面是关于SysTick定时器的一些介绍:

用途: SysTick定时器通常被用作操作系统的时钟节拍(Tick)或者作为基本的定时器来执行周期性的任务。它可以提供一个精确的时间基准,用于定时器中断、延时函数的实现以及系统的时间管理。

定时器类型: SysTick定时器是一个24位向下计数器。它可以在一个范围内计数从最大值向0的时钟周期,然后在达到0时重新装载计数值,并触发一个中断(如果已使能)。

配置: 在STM32微控制器中,SysTick定时器可以通过设置相关的寄存器来配置。这些寄存器包括:

STK_CTRL:控制寄存器,用于使能或禁用SysTick定时器,选择时钟源和设置中断使能。
STK_LOAD:装载寄存器,用于设置初始的计数值。
STK_VAL:当前值寄存器,用于读取当前的计数值。
STK_CALIB:校准寄存器,用于存储SysTick定时器的校准值。

时钟源: SysTick定时器的时钟源可以选择为外部时钟或者系统时钟的一个分频。通常情况下,它与系统时钟同步,但也可以使用外部时钟来提供更灵活的配置选项。

中断: SysTick定时器可以在计数器溢出时触发中断。这种中断通常被用来实现操作系统的时钟节拍,或者用于周期性任务的执行。

应用: SysTick定时器广泛应用于嵌入式系统中,特别是在实时操作系统(RTOS)中用作系统时钟。它可以用来实现延时函数、精确的定时器中断、周期性任务的执行以及系统的时间管理。

二、SYSTick定时器和其他定时器的区别

1.SYSTick定时器是CPU内部的定时器,其他定时器是作为STM32的外部定时器。

之所以在处理器内增加一个定时器,是为了提高软件的可移植性。由于所有的 Cortex-M处理器都具有相同的SysTick定时器,为一种Cortex-M3/M4微控制器实现的OS也能适用于其他的Cortex-M3/M4微控制器
STM32 SYSTick高精度延时功能代码实现,STM32框架式编程,stm32,单片机,嵌入式硬件
2.功能和用途:

SYSTick定时器通常用于实现系统的时间管理、时钟节拍以及简单的定时功能,如延时函数的实现等。
其他定时器(如TIM定时器)通常用于更复杂的定时和计时任务,例如PWM输出、捕获/比较模式、定时触发ADC转换等。

3.精度:

SYSTick定时器的精度通常受限于系统时钟频率,因此在一般情况下可能比较低。
其他定时器通常具有更高的精度,并且可以通过外部时钟源进行精确校准,因此适用于需要更精确时间控制的应用。

4.中断处理:

SYSTick定时器通常只能产生一个中断,用于系统的时钟节拍或简单的定时任务。
其他定时器可以配置多个中断触发条件,允许更灵活的中断处理和定时任务的执行。

5.寄存器和配置:

SYSTick定时器只有几个寄存器,配置相对简单。
其他定时器通常具有更多的寄存器和更复杂的配置选项,以支持各种不同的定时和计时功能。

6.外设依赖性:

SYSTick定时器不依赖于外部器件,因为它是CPU内部的一个特殊功能模块。
其他定时器通常依赖于外部时钟源和其他外部器件(例如计数输入、PWM输出引脚等)。

7.优先级:

由于SYSTick定时器是CPU内部的定时器,因此其中断处理通常具有较高的优先级。
其他定时器的中断处理优先级可能需要根据具体应用情况进行配置,并且可能不如SYSTick定时器的中断处理优先级高。

三、SYSTick定时器框图讲解

STM32 SYSTick高精度延时功能代码实现,STM32框架式编程,stm32,单片机,嵌入式硬件
1.首先SYSTick根据处理器时钟或者参考时钟来减小计数

2.配置CTRL寄存器的第0位使能计数器,当前值寄存器在每个处理器时钟周期或参考时钟的上升沿都会减小。若计数减至0,它会从重加载寄存器中加载数值并继续
运行。

3.另外一个寄存器为 SysTick 校准值寄存器。它为软件提供了校准信息。由于 CMSISCore 提供了一个名为 SystemCoreClock 的软件变量(CMSIS 1.2及之后版本可用,CMSIS 1.1或之前版本则使用变量 SystemFrequency),因此它就未使用SysTick 校准值寄存器。系统初始化函数 SystemInit()函数设置了该变量,而且每次系统时钟配置改变时都要对其进行更新这种软件手段比利用SysTick 校准值寄存器的硬件方式更灵活。

四、HAL库中SYSTick配置代码讲解

STM32 SYSTick高精度延时功能代码实现,STM32框架式编程,stm32,单片机,嵌入式硬件
STM32 SYSTick高精度延时功能代码实现,STM32框架式编程,stm32,单片机,嵌入式硬件

STM32 SYSTick高精度延时功能代码实现,STM32框架式编程,stm32,单片机,嵌入式硬件
滴答定时器配置代码:

__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 << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
  SysTick->VAL   = 0UL;                                             /* Load the SysTick Counter Value */
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                   SysTick_CTRL_TICKINT_Msk   |
                   SysTick_CTRL_ENABLE_Msk;                         /* Enable SysTick IRQ and SysTick Timer */
  return (0UL);                                                     /* Function successful */
}

下面是对这段代码的配置流程的讲解:

1.参数检查:

if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
{
  return (1UL);  /* Reload value impossible */
}

这一部分首先检查传入的 ticks 参数是否超过了SysTick定时器的重装载寄存器(LOAD寄存器)的最大值。如果超过了,说明无法设置这么大的重载值,函数返回1表示配置失败。否则,继续执行后续的配置步骤。

2.设置重载寄存器:

SysTick->LOAD  = (uint32_t)(ticks - 1UL);  /* set reload register */

这一行代码设置SysTick定时器的重载寄存器,确定计数器计数到多少时触发一次SysTick中断。ticks - 1 是因为计数器是从零开始计数的。

3.设置中断优先级:

NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL);  /* set Priority for Systick Interrupt */

这里设置了SysTick定时器的中断优先级。NVIC_SetPriority 是一个用于设置中断优先级的CMSIS(Cortex Microcontroller Software Interface Standard)函数。__NVIC_PRIO_BITS 表示中断优先级位的数量,通常由硬件定义。这里将SysTick中断的优先级设置为最低,即最高数值。

4.清零计数器寄存器:

SysTick->VAL   = 0UL;  /* Load the SysTick Counter Value */

这一行代码清零SysTick定时器的计数器寄存器,确保计数器从零开始计数。

5.配置并启用SysTick定时器:

SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
                 SysTick_CTRL_TICKINT_Msk   |
                 SysTick_CTRL_ENABLE_Msk;  /* Enable SysTick IRQ and SysTick Timer */

这一行代码配置并启用SysTick定时器。具体配置包括:

SysTick_CTRL_CLKSOURCE_Msk:选择SysTick定时器的时钟源,通常选择处理器时钟。
SysTick_CTRL_TICKINT_Msk:使能SysTick定时器中断。
SysTick_CTRL_ENABLE_Msk:启用SysTick定时器。

返回配置结果:

   return (0UL);  /* Function successful */

如果上述配置步骤都成功执行,函数返回0,表示配置成功。

五、SYSTick实现高精度延时

创建systick.c和systick.h来管理高精度延时的代码。

systick.c

#include "systick.h"

//us级延时
void udelay(int us)
{
	uint32_t told = SysTick->VAL;
	uint32_t tnow;
	
	uint32_t load = SysTick->LOAD;
	
	/* LOAD+1个时钟对应1ms
	 * n us对应 n*(load+1)/1000个时钟
   */
	uint32_t ticks = us*(load+1)/1000;
	
	uint32_t cnt = 0;
	
	while (1)
	{
		tnow = SysTick->VAL;
		if (told >= tnow)
			cnt += told - tnow;
		else
			cnt += told + load + 1 - tnow;
		
		told = tnow;
		if (cnt >= ticks)
			break;
	}	
}

//ms级延时
void mdelay(int ms)
{
	for (int i = 0; i < ms; i++)
		udelay(1000);	
}

//获取系统上电到现在经过了多少ns
uint64_t system_get_ns(void)
{
	uint64_t ns = HAL_GetTick(); /* ms */
	ns = ns*1000000;

	uint32_t tnow = SysTick->VAL;	
	uint32_t load = SysTick->LOAD;
	
	uint64_t cnt;
	
	cnt = load+1-tnow; /* 没有考虑tnow等于0的情况 */
	
	ns += cnt * 1000000 / (load+1) ;
	return ns;	
}


systick.h

#ifndef __SYSTICK_H__
#define __SYSTICK_H__

#include "main.h"

void udelay(int us);

void mdelay(int ms);

uint64_t system_get_ns(void);

#endif


  1. udelay(int us)
    这个函数实现了微秒级延时。其原理是利用SysTick定时器进行精确计时。首先,获取当前SysTick计数器的值 told,然后计算出需要延时的时钟周期数 ticks,接着在一个循环中不断获取当前计数器的值 tnow,并计算经过的时钟周期数 cnt。当经过的时钟周期数达到了延时所需的时钟周期数 ticks 时,跳出循环,延时结束。

  2. mdelay(int ms)
    这个函数实现了毫秒级延时,它通过多次调用微秒级延时函数来实现。每次调用 udelay(1000) 即相当于延时了1毫秒。

  3. system_get_ns(void)
    这个函数用于获取系统上电到当前时刻经过的纳秒数。首先,获取系统运行时间的毫秒数 ns,然后通过当前SysTick计数器的值 tnow 和 SysTick加载值 load 计算出当前经过的时钟周期数 cnt,进而将其转换为纳秒数并加到系统运行时间上,最终返回总的纳秒数。

总结

本篇文章主要讲解了SYSTick的概念,寄存器配置和使用,并且使用SYSTick实现了高精度延时,大家可以自己写代码实验验证一下正确性。文章来源地址https://www.toymoban.com/news/detail-836407.html

到了这里,关于STM32 SYSTick高精度延时功能代码实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 高精度加法(含代码)

    例如: 1111111111111+9, 列成 竖式 , 先算个位, 1 + 9 = 10 , 满 10 , 向十位进 1 。 接下来, 处理 进位 。 十位: 1+1=2 - 2 百位: 无进位, 直接照抄. 1 - 1 千位: 1 - 1 万位: ... ...: ... 最高位: 1 - 1 最终结果: 所以, 1111111111111+ 9 = 1111111111120 1111111111111+8888888888889, 这个算式变成了 高精度 + 高精度

    2024年02月06日
    浏览(24)
  • 国民技术N32_MCU ADC如何获取高精度采样数据

    国民技 术 微控制器内置最多四个高级 12 位 ADC    (取决于产品系列) ,具有校准功能,用于提高环境条件   变 化时的 ADC   精度。 在涉及模数转 换的应用中,   ADC   精度会影响整体的系统质量和效率。为了提高此精度,必须了解与 ADC 相 关 的误差以及影响它们的参数。

    2024年02月09日
    浏览(24)
  • 基于DSP+FPGA+ADS1282支持32Bit高精度数据采集方案(一)

    3.1 系统需求分析 3.1.1 系统功能设计要求 本硬件处理平台的主要任务有三类,一是数据采集,包括采集惯性测量元件 的输出信号,接收外部系统校正信息,如 GPS 信息等;二是数据处理与计算,包 括惯性测量元件的误差补偿、初始对准、导航参数解算和在线校正滤波等;三是

    2024年02月01日
    浏览(29)
  • 双目相机标定及高精度测量方法,含c++和python代码说明

    视觉测量定位中,双面相机高精度标定是一个重要的步骤。下面是关于如何进行双面相机高精度标定的说明和C++和Python代码实现。 1. 双面相机高精度标定的原理 双面相机高精度标定的目的是确定相机内部参数和外部参数。其中,内部参数包括焦距、主点和畸变系数等,外部

    2023年04月08日
    浏览(19)
  • 基于DSP+FPGA+ADS1282支持32Bit高精度数据采集方案(二)模拟电路设计

    如图 4.1 所示是系统硬件系统的信号框图,数字信号处理板上的主要核心是 两个处理芯片,即 FPGA 和 DSP ,其中 FPGA 主要作用是做 DSP 和外围接口的 桥梁及数据预处理, DSP 做为数据解算核心。 FPGA 通过各种的数据总线接收外部设备传输过来的数据,并进行打包处理 以及其他

    2024年02月02日
    浏览(19)
  • 基于DSP+FPGA+ADS1282支持32Bit高精度数据采集方案(三)系统性能测试

    系统性能分析与测试 本章将首先对系统电路的噪声和温漂进行分析,而后对采集系统的性能进行 测试,并对测试数据进行分析。 5.1 高精度 AD 转换电路噪声和温漂分析 5.1.1 电阻噪声与温漂 1 、电阻的噪声 电阻是一种噪声源,其严重程度取决于电阻值、温度、施加的电压和电

    2024年02月01日
    浏览(61)
  • 冰箱主控 32位MCU,多通道、高精度的AD采样配合温度传感器,实现冰箱各温室的精确控温;低功耗设计

    概览 小华高性价比32位MCU,多通道、高精度的AD采样配合温度传感器,实现冰箱各温室的精确控温;低功耗设计,绿色低碳、节能环保;模块化设计,充分利用丰富的通讯接口,使主控板、显示板和驱动板灵活搭配,设计方便。 方案特点 48MHz32bit ARM Cortex-M0+内核 多种低功耗模

    2024年04月28日
    浏览(18)
  • (基础算法)高精度加法,高精度减法

    什么叫做高精度加法呢?包括接下来的高精度减法,高精度乘法与除法都是同一个道理。正常来讲的话加减乘除,四则运算的数字都是整数,也就是需要在int的范围之内,但当这个操作数变得非常\\\"大\\\"的时候( 其实就是一个字符串,比方说有一个数是20位,如果用整数视角来

    2024年02月01日
    浏览(18)
  • STM32系统滴答定时器SysTick实现精确ms和us延时

    时间记录:2023/12/11 一、时间的计算 STM32F103C8T6单片机为例,系统时钟为72MHz,则一个时钟周期为(1/72M)秒,即1/72us 二、寄存器介绍 (1)CTRL控制及状态寄存器 位段 名称 描述 16 COUNTFLAG 当计数到0时,该位置为1,当读取该位时,自动清零 2 CLKSOURCE 值为0时选择外部时钟源,值为

    2024年01月24日
    浏览(24)
  • 免费开源的高精度OCR文本提取,支持 100 多种语言、自动文本定位和脚本检测,几行代码即可实现离线使用(附源码)

    免费开源的高精度OCR文本提取,支持 100 多种语言、自动文本定位和脚本检测,几行代码即可实现离线使用(附源码)。 要从图像、照片中提取文本吗?是否刚刚拍了讲义的照片并想将其转换为文本?那么您将需要一个可以通过 OCR(光学字符识别)识别文本的应用程序。 图

    2024年02月01日
    浏览(75)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包