STM32的定时器详解(嵌入式学习)

这篇具有很好参考价值的文章主要介绍了STM32的定时器详解(嵌入式学习)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

0. 前言

想要了解STM32的时钟系统
点击这里跳转——》STM32的时钟系统(嵌入式学习)

建议先看看时钟树如何配置
点击这里跳转——》STM32的时钟树配置(嵌入式学习)

跳转——》STM32的时钟基础详解(嵌入式学习)
跳跳转——》STM32的时钟源详解(嵌入式学习)

1. Systick定时器

概念

SysTick又称滴答定时器。是一个定时设备,位于Cortex-M0内核中,和NVIC捆绑,产生SysTick异常(IRQ异常号15)可以对输入的时钟进行计数,系统定时器一般用于操作系统,用于产生时基,维持操作系统的心跳。

stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

Systick定时器是一种内置的定时器,通常用于实时操作系统(RTOS)或其他需要精确定时的应用中。它在大多数STM32微控制器中都有提供。

Systick定时器的主要特点如下:

  1. 基于计数器:Systick定时器基于一个32位的自动递减计数器。计数器从一个初始值开始递减,当计数器的值减至零时,会产生一个中断或触发一个事件。

  2. 系统时钟驱动:Systick定时器的时钟源通常是系统时钟(SYSCLK)。这使得它能够提供与系统时钟相关的精确定时功能。

  3. 配置灵活:Systick定时器可以通过寄存器进行灵活的配置。你可以设置计数器的初始值、使能或禁用定时器、选择中断触发或事件触发等。

  4. 中断或事件触发:当计数器减至零时,可以选择触发一个中断或一个事件。中断触发可以用于在特定时间间隔内执行一些任务,而事件触发可以用于与其他外设或模块进行同步。

  5. 时间精度:Systick定时器的时间精度取决于它的时钟源和计数器的位数。通常情况下,它可以提供微秒级别的定时精度。

Systick定时器常用于实现延时函数、系统时钟节拍、定时任务调度等功能。在实时操作系统中,它通常用作系统的节拍定时器,用于调度任务的执行。

要使用Systick定时器,你需要在代码中进行相应的配置和中断处理程序编写。具体的配置和使用方法可以参考相应的微控制器参考手册和编程手册,以及相关的开发工具(如STM32Cube库和HAL库)的文档和示例代码。

工作原理

滴答定时器是一个24位递减定时器,也就是最多能计数2^24(0xFFFFFF)。
SysTick设定初值并使能后,每来一个时钟信号,计数值就减1。
计数到0时,触发中断,SysTick计数器自动重装初值并继续减一,循环不断。
系统默认开启滴答定时器。

Systick定时器是一种基于计数器的定时器,在STM32微控制器中,它的工作原理如下:

  1. 时钟源选择:Systick定时器的时钟源通常是系统时钟(SYSCLK)。系统时钟通常由外部晶体振荡器或内部RC振荡器提供,并通过时钟树的配置确定其频率。

  2. 计数器配置:Systick定时器使用一个32位的自动递减计数器进行计时。在初始化时,需要设置计数器的初始值,这决定了定时器开始计数的起点。

  3. 计数器递减:Systick定时器的计数器从初始值开始递减,每个时钟周期减少一个计数值,直到计数器减至零。

  4. 中断或事件触发:当计数器减至零时,可以选择触发一个中断或一个事件。中断触发会生成一个中断请求,CPU会相应地跳转到Systick中断处理程序执行特定的操作。事件触发则可以与其他外设或模块进行同步操作。

  5. 中断处理程序:Systick定时器的中断处理程序是由开发者编写的一段代码,用于处理定时器中断触发时需要执行的任务。在中断处理程序中,可以执行特定的操作,例如更新系统节拍计数、调度任务、处理延时函数等。

  6. 重载计数器:当计数器减至零后,可以选择自动重载计数器的值。这允许定时器自动重新开始计数,以实现周期性的定时功能。

通过适当配置和使用Systick定时器,可以实现延时函数、系统时钟节拍、定时任务调度等应用。在实时操作系统中,Systick定时器通常用作系统的节拍定时器,用于精确调度任务的执行。

在编程时,你需要配置Systick定时器的相关寄存器,包括计数器的初始值、使能/禁用定时器、中断使能等。同时,需要编写中断处理程序,以响应Systick定时器中断触发时的操作。

请注意,Systick定时器的具体配置和使用方法可能因不同的STM32微控制器型号而有所差异。因此,在进行Systick定时器的配置和使用之前,建议参考所选微控制器的参考手册和编程手册,以获得准确的配置细节和操作说明。

时钟基准

首先看Systick每次触发异常在异常处理程序中做了哪些工作
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

每次systick触发中断后会让uwTick自加1
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

这个uwTick的值就作为系统的时钟基准。
然后再来研究一下,uwTick多久会被加1.
在main.c中main函数首个执行的函数HAL_Init(),会对systick进行初始化。
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件
在HAL_Init中通过调用HAL_InitTick函数,对Tick进行初始化
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件
传递参数为:
TICK_INT_PRIORITY = 0 作为systick的中断优先级
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件
调用HAL_SYSTICK_Config函数用于配置systick时基
SystemCoreClock / (1000U /(uint32_t)uwTickFreq)
uint32_t SystemCoreClock = 16000000UL;
16000000 / 1000 / 1 = 16000
将16000作为参数传递给了HAL_SYSTICK_Config函数
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件
Systic_Config函数对Systick的重装值、初值、优先级和校准值都进行了配置。
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

  if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)  //如果systick初值大于最大值0xFFFFFF
  {
         return (1UL);        //返回1 说明配置失败                                        
  }
  SysTick->LOAD  = (uint32_t)(ticks - 1UL);                         /* 重载的计数值 */     16000 - 1
  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;                      
  return (0UL); 

stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

SysTick->LOAD  = (uint32_t)(ticks - 1UL);  //即16000 - 1

从16000 - 1开始递减到0,总共需要计数16000次
当前时钟频率16Mhz,说明计一个数用时1/16M s
计16000个数需要用时 16000 * 1/16000000 s = 1/1000 s = 1ms
因此Systick每隔1ms会触发一次异常。

Systick练习

利用Systick异常,实现1秒打印“helloworld”
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

每次Systick触发异常时让flag自加1
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

在主函数中判断,当flag加到1000时,说明systick异常触发了1000次,此时刚好用时1s。打印“helloworld”
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

2. HAL_Delay函数分析

__weak void HAL_Delay(uint32_t Delay)
{
 	 uint32_t tickstart = HAL_GetTick();   //获取当前时间
  	 uint32_t wait = Delay;      //获取用户要延时的时间
        /* Add a freq to guarantee minimum wait */
 	 if (wait < HAL_MAX_DELAY)
       {
          wait += (uint32_t)(uwTickFreq);
        }
        while ((HAL_GetTick() - tickstart) < wait)
       {   //如果当前系统时间 - 初始时间 < 延时时间 则继续循环
           //当达到延时条件时,循环结束。
       }
}

stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

GetTick函数返回当前系统uwTick的值
uwTick每个1ms会自加1
因此HAL_Delay的实现依靠Systick,以达到毫秒为单位的延时效果。

3. 定时器

基本概念

定时器本质上是一个计数器,可对输入的时钟进行计数,并在计数值达到设定值时触发中断,当这个计数器的输入是一个准确可靠的基准时钟时,对基准时钟计数的过程就是计时的过程。

定时器分类

定时器的基本结构是通用的,很多模块电路都能用到,所以STM32定时上扩展了非常多的功能,根据复杂度和应用场景分为了高级定时器、通用定时器、基本定时器三种类型。
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件
F103
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

F407
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

定时器组成

计数器

stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件
向上计数模式: 计数器从0开始计数,当达到自动装载寄存器(TIMx_ARR)里的值时,自动清零且产生一个溢出事件,然后再从0开始向上计数。
向下计数模式: 计数器从自动装载寄存器(TIMx_ARR)里的值开始递减计数,当计数值达到0时产生一个定时器溢出事件,并重装初值,继续向下计数。
中央对齐模式: 又称为向上/向下计数,计数器从0开始递增达到ARR的值,产生一个定时器溢出事件,再从ARR的值递减到0,产生一个定时器溢出事件。

自动重装寄存器

stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

预分频器

stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

定时器计数原理

时钟频率配置成了48Mhz,如何让定时器产生1s中断?
分频值写0相当于不分频 48/1 => 48
先对主频进行48分频得到1Mhz的频率,则分频值为48-1
48Mhz / 48 => 1Mhz
1Mhz的时钟频率,相当于计一个数需要1/1000000秒,
所以如果想得到1s中断,则需要从0开始计数到1000000-1,即计1000000个数需要1秒。

定时器练习

利用定时器中断实现1s打印一个“hellowolrd”

stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

在main.c中重写定时器溢出中断回调函数
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

启动定时器以中断模式计数
stm32定时任务,嵌入式底层,stm32,单片机,嵌入式硬件

4. 软件定时器

概念

在STM32微控制器中,通常使用软件定时器来执行特定的定时任务。软件定时器是通过编程实现的,而不是通过硬件计时器。以下是一种实现软件定时器的方法:

  1. 初始化计时器参数:选择一个适当的定时器变量,例如一个32位的计数器变量,以便能够表示较长的时间。另外,设置一个定时器间隔,即希望定时器每隔多久触发一次。

  2. 计时器启动:在合适的时机,例如在系统初始化时或任务启动时,将计时器变量设置为0,并启动计时器。

  3. 定时器中断处理:在每次计时器溢出时,触发一个中断。在中断服务程序(ISR)中,将计时器变量递增,并检查是否已经达到预定的定时器间隔。

  4. 定时任务执行:如果达到了定时器间隔,执行所需的定时任务,然后重置计时器变量为0,以便下一次定时器中断时再次触发任务。

这是一个基本的软件定时器框架,可以根据具体的应用场景进行调整和扩展。需要注意的是,软件定时器是基于系统时钟的,因此在设计定时器间隔时,需要考虑系统时钟频率和定时器的精度。

设计思想

1)设计一个定时器(软件层次,结构体内含有开始的时间和想要延时的时间)
2)设置定时器时间 和 比较定时器是否到达 两个函数

代码

1)设计定时器(记录起始时间,记录用户延时时间)

typedef struct
{
    uint32_t  start; //保存起始时间
    uint32_t  delay; //保存延时时间
}MyTim;	

2)提供一个用于传递定时时间的软件定时器配置函数

//定时器初始化函数
void setTim(MyTim *timer,uint32_t delayms)
{
    timer->start = HAL_GetTick();  
    timer->delay = delayms;
}	

3)提供一个用于比对是否达到定时要求的函数文章来源地址https://www.toymoban.com/news/detail-645955.html

uint32_t compareTim(MyTim *timer)
{
	if(HAL_GetTick() - timer->start >= timer->delay)
	{
	    return 1; //返回1说明达到了定时要求	
	}else
	{
		return 0; 
	}
}	

到了这里,关于STM32的定时器详解(嵌入式学习)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 嵌入式_常见延时方式的差异与选择(for循环延时、定时器延时、汇编延时....)

    这里整理几种常见的延时方式,并做简单测试供大家参考,如果有什么不对的地方,欢迎指正,共同探讨。 测试基于GD32F103CBT6硬件平台,标准的72MHz系统时钟, 使用标准库GD32F10x_Firmware_Library_V1.0.0 提示:(提示:此库坑多、慎用!) 测试方法为: 1:在Debug模式下延时开始于

    2024年02月02日
    浏览(80)
  • 嵌入式培训机构四个月实训课程笔记(完整版)-Linux ARM驱动编程第二天-ARM中断、定时器、看门狗(物联技术666)

    链接:https://pan.baidu.com/s/1E4x2TX_9SYhxM9sWfnehMg?pwd=1688 提取码:1688 上午:中断           吕峰老师 下午:定时器 教学内容: 一、中断 ARM 中断分为二级,分为一级中断和二级中断,二级中断为子中断,对于 ARM 来说有 50 个中断源, 其中有 32+ ( EINT23-4 ) 23-4+1-2=50 子中断源

    2024年02月19日
    浏览(48)
  • STM32定时器-定时器中断功能详解

    STM32的众多定时器中我们使用最多的是高级定时器和通用定时器,而高级定时器一般也是用作通用定时器的功能,下面我们就以通用定时器为例进行讲解,其功能和特点包括: 通用与基本定时器(2~7)位于低速的APB1总线上 高级定时器(1、8)位于高速的APB2总线上 自动装载计

    2024年02月08日
    浏览(37)
  • STM32 MCU 定时器详解(3)--高级定时器

    16位递增、递减、中心对齐计数器(计数值:0~65535) 16位预分频器(分频系数:1~65536) 可用于触发DAC、ADC 在更新事件、触发事件、输入捕获、输出比较时,会产生中断/DMA请求 4个独立通道,可用于:输入捕获、输出比较、输出PWM、单脉冲模式 使用外部信号控制定时器且可实

    2024年04月17日
    浏览(39)
  • STM32 MCU 定时器详解(1)--基本定时器

    定时器是一种电子组件,主要用于定时控制,具备精确计时的能力。它可以在设定的时间间隔内触发特定的操作,如发送数据、采集传感器信息、检测输入信号或产生规律性输出波形。这种灵活性使定时器在多个行业中得到广泛应用,支持各种复杂功能的实现,是现代电子系

    2024年02月22日
    浏览(43)
  • 定时器详解 -- 定时器中断、PWM输出 --stm32

    STM32F103系列芯片拥有多种定时器,包括基本定时器、通用定时器和高级定时器,每种定时器都具有一些特定的功能。 向上计数:计数器从0计数到自动重装载值(ARR),然后重新从0开始计数并且产生一个计数器溢出事件。 向下计数:计数器从自动重装载值(ARR)开始向下计数

    2024年02月11日
    浏览(51)
  • STM32 定时器详解

    吃了一个猛亏,自己理解花了大半天时间,结果一看代码发现巨简单 算了,把自己理解的放上来吧 目录 STM32 定时器详解 前言 一、定时器种类和区分 二、时钟源 三、计数过程 3.1 计数器时钟CK_CNT 3.2 计数器有关的三个寄存器 3.3 其他的寄存器 3.4 定时器计算时间 总结 前面说

    2024年02月06日
    浏览(40)
  • 【嵌入式】STM32计时器编码器接口模式使用

    使用STM32调试电机或传感器时经常会使用到计数器的编码器接口模式,本文主要记录该模式的固件库配置方法,并给出使用该模式获取光栅测距值的实例。 硬件: STM32F103C8T6 光栅测距传感器 编码器接口模式为STM32计时器的一种特殊使用模式,该模式下可对编码器输出的脉冲信

    2024年02月20日
    浏览(39)
  • STM32高级定时器详解

    ✅作者简介:嵌入式入坑者,与大家一起加油,希望文章能够帮助各位!!!! 📃个人主页:@rivencode的个人主页 🔥系列专栏:玩转STM32 💬保持学习、保持热爱、认真分享、一起进步!! 基本定时器TIM6和TIM7各包含 一个16位自动装载计数器 ,由各自的可编程预分频器驱动。

    2024年01月19日
    浏览(42)
  • STM32中TIM定时器定时功能详解(适用基本,通用,高级定时器)

    定时器有高级定时器、通用定时器、基本定时器三种类型。具体功能如下。 上面是每种定时器所具有的功能。 我们可以看到每种定时器都有一个定时功能,(可能是名字的由来吧)。当然,每个定时器都可以来使用定时功能,但是我们往往在基本定时器和通用定时器上面使用

    2024年01月19日
    浏览(54)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包