STM32 MCU 定时器详解(1)--基本定时器

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


一、定时器概述

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

1.1 定时原理

首先,时钟信号(CLK)输入到预分频器(PSC),在此降低频率以适应不同的定时需求。降频后的时钟信号送入定时器时钟(TIM CLK),再驱动计数器(CNT)。计数器根据自动重装载寄存器(ARR)设定的值进行计数,一旦计数值达到ARR设定的值,定时器便完成一个周期,产生中断或其他预设的定时事件,如输出比较信号或重置计数器。通过调整PSC和ARR的值,可以精确控制定时周期和定时器的输出
mcu的计时器clk来自哪,单片机,stm32,嵌入式硬件

1.2 定时器分类

定时器分为基本定时器、通用定时器和高级定时器,每个类型的定时器功能上都有区别,具体见下面的表格。
mcu的计时器clk来自哪,单片机,stm32,嵌入式硬件
在STM32F103系列中,每个定时器的特性如下表。
mcu的计时器clk来自哪,单片机,stm32,嵌入式硬件

二、基本定时器工作原理

STM32F103有两个基本定时器TIM6和TIM7,它们的功能完全相同,资源是完全独立的,可以同时使用。其主要特性如下:16位自动重载递增计数器,16位可编程预分频器,预分频系数1~65536,用于对计数器时钟进行分频,还可以触发DAC的同步电路,以及生成中断/DMA请求

2.1 基本定时器框图

mcu的计时器clk来自哪,单片机,stm32,嵌入式硬件

  • 时钟源
    定时器的计数能力依赖于提供给它的时钟源。这个时钟源起始于APB1总线,但并非直接供应,二十通过倍频器调节。当APB1总线的预分频器设置为1时,倍频器系数也是1,因此定时器的时钟频率与APB1总线相同。若APB1预分频器系数大于等于2,倍频器系数成为2,定时器时钟频率便是APB1总线频率的两倍。考虑到在sys_stm32_clock_init函数中APB1总线被设置为36MHz,并且预分频器的分频系数是2,挂在APB1总线上的定时器的时钟频率将是72MHz。
  • 控制器
    控制器除了控制定时器复位、使能、计数等功能之外,还可以用于触发DAC转换。
  • 时基单元
    时基单元包括:计数器寄存器(TIMx_CNT)、预分频寄存器(TIMx_PSC)、自动重载寄存器(TIMx_ARR)。基本定时器的这三个寄存器都是16位雨哦小数字,即可设置的范围是0~65535.
    时间单元中的预分频器PSC,它有一个输入和一个输出。输入CK_PSC来源于控制器部分,实际上就是来自于内部时钟(CK_INT),即2倍的APB1总线时钟频率(72MHz)。输出CK_CNT是分频后的时钟,它是计数器实际的计数时钟,通过设置预分频器寄存器(TIMx_PSC)的值可以得到不同频率CK_INT,计算公式如下:
    f C K C N T = f C K P S C / ( P S C [ 15 : 0 ] + 1 ) f_{CK_CNT} = f_{CK_PSC} / (PSC[15:0] + 1) fCKCNT=fCKPSC/(PSC[15:0]+1)
    PSC[15:0]是写入预分频器寄存器(TIMx_PSC)的值。注意:预分频器寄存器(TIMx_PSC)可以载运行过程中修改它的值,新的预分频数值将在下一个更新事件时起作用。因为更新事件发生时,会把TIMx_PSC寄存器值更新到其影子寄存器(间接更新,确保稳定)中

2.2 更新事件

  • 软件产生
    将TIMx_EGR寄存器的位UG置1,产生更新事件后,硬件会自动将UG位清零。
  • 硬件产生
    基本定时器的核心是一个递增计数器(CNT)。启动定时器的条件是TIMx_CR1寄存器的GEN位被置为1。此后,每个CK_CNT时钟脉冲都会使CNT寄存器的值增加1。当CNT的值增加至自动重载寄存器(ARR)相等时,CNT会自动清零,并触发一个更新事件。这可能导致DMA请求产生中断或触发其他同步操作。每次CNT清零后,它会在接收到下一个脉冲时再次递增,循环继续。计时器的这种计数溢出行为,即CNT等于ARR时自动的清零,被称为定时器溢出或上溢。

2.3 定时器计数模式

定时器计数模式主要有三种:递增计数模式、递减计数模式、中心对齐模式,每种模式的溢出条件如下:
mcu的计时器clk来自哪,单片机,stm32,嵌入式硬件
各计数模式的工作示意图如下:
mcu的计时器clk来自哪,单片机,stm32,嵌入式硬件

  • 递增计数模式
    计数器从0开始,向上递增至ARR(自动重载寄存器)值然后溢出,触发更新事件后重新从0开始计数。
  • 递减计数模式
    计数器从ARR值开始,向下递减至0然后溢出,触发更新事件后重新从ARR值开始计数。
  • 中心对齐模式
    计数器从0开始向上递增至ARR值,然后改为向下计数至0,循环往复。

2.4 溢出事件计算方式

T o u t = ( A R R + 1 ) ∗ ( P S C + 1 ) F t T_{out} = \frac{(ARR + 1) * (PSC + 1)}{F_{t}} Tout=Ft(ARR+1)(PSC+1)

  • Tout是定时器溢出时间
  • Ft是定时器的时钟源频率
  • ARR是自动重装载寄存器的值
  • PSC是预分频器寄存器的值

2.5 定时器配置步骤

  • 配置定时器基础工作参数:HAL_TIM_Base_Init()
  • 定时器基础MSP初始化:HAL_TIM_Base_MspInit(). 配置NVIC、CLOCK
  • 使能更新中断并启动计数器:HAL_TIM_Base_Start_IT()
  • 设置优先级,使能中断:HAL_NVIC_SetPriority()、HAL_NVIC_EnableIRQ()
  • 编写中断服务函数:TIMx_IRQHandler()
  • 编写定时器更新中断回调函数:HAL_TIM_PeriodElapsedCallback()

三、程序示例

头文件定义如下:

#include "./SYSTEM/sys/sys.h"

/******************************************************************************************/
/* 基本定时器 定义 */

/* TIMX 中断定义 
 * 默认是针对TIM6/TIM7
 * 注意: 通过修改这4个宏定义,可以支持TIM1~TIM8任意一个定时器.
 */
 
#define BTIM_TIMX_INT                       TIM6
#define BTIM_TIMX_INT_IRQn                  TIM6_DAC_IRQn
#define BTIM_TIMX_INT_IRQHandler            TIM6_DAC_IRQHandler
#define BTIM_TIMX_INT_CLK_ENABLE()          do{ __HAL_RCC_TIM6_CLK_ENABLE(); }while(0)   /* TIM6 时钟使能 */

/******************************************************************************************/

void btim_timx_int_init(uint16_t arr, uint16_t psc);    /* 基本定时器 定时中断初始化函数 */

定时器源文件代码如下:

#include "./BSP/LED/led.h"
#include "./BSP/TIMER/btim.h"


TIM_HandleTypeDef g_timx_handle;  /* 定时器句柄 */

/**
 * @brief       基本定时器TIMX定时中断初始化函数
 * @note
 *              基本定时器的时钟来自APB1,当PPRE1 ≥ 2分频的时候
 *              基本定时器的时钟为APB1时钟的2倍, 而APB1为36M, 所以定时器时钟 = 72Mhz
 *              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.
 *              Ft=定时器工作频率,单位:Mhz
 *
 * @param       arr: 自动重装值。
 * @param       psc: 时钟预分频数
 * @retval      无
 */
void btim_timx_int_init(uint16_t arr, uint16_t psc)
{
    g_timx_handle.Instance = BTIM_TIMX_INT;                      /* 通用定时器X */
    g_timx_handle.Init.Prescaler = psc;                          /* 设置预分频系数 */
    g_timx_handle.Init.CounterMode = TIM_COUNTERMODE_UP;         /* 递增计数模式 */
    g_timx_handle.Init.Period = arr;                             /* 自动装载值 */
    HAL_TIM_Base_Init(&g_timx_handle);

    HAL_TIM_Base_Start_IT(&g_timx_handle);    /* 使能定时器x及其更新中断 */
}

/**
 * @brief       定时器底层驱动,开启时钟,设置中断优先级
                此函数会被HAL_TIM_Base_Init()函数调用
 * @param       htim:定时器句柄
 * @retval      无
 */
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == BTIM_TIMX_INT)
    {
        BTIM_TIMX_INT_CLK_ENABLE();                     /* 使能TIM时钟 */
        HAL_NVIC_SetPriority(BTIM_TIMX_INT_IRQn, 1, 3); /* 抢占1,子优先级3,组2 */
        HAL_NVIC_EnableIRQ(BTIM_TIMX_INT_IRQn);         /* 开启ITM3中断 */
    }
}

/**
 * @brief       定时器TIMX中断服务函数
 * @param       无
 * @retval      无
 */
void BTIM_TIMX_INT_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&g_timx_handle); /* 定时器中断公共处理函数 */
}

/**
 * @brief       定时器更新中断回调函数
 * @param       htim:定时器句柄
 * @retval      无
 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == BTIM_TIMX_INT)
    {
        LED1_TOGGLE(); /* LED1反转 */
    }
}

主函数代码如下:

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/TIMER/btim.h"


int main(void)
{
    HAL_Init();                             /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);     /* 设置时钟, 72Mhz */
    delay_init(72);                         /* 延时初始化 */
    usart_init(115200);                     /* 串口初始化为115200 */
    led_init();                             /* 初始化LED */
    btim_timx_int_init(5000 - 1, 7200 - 1); /* 10Khz的计数频率,计数5K次为500ms */

    while (1)
    {
        LED0_TOGGLE();
        delay_ms(200);
    }
}

整体代码流程如下,先初始化串口、LED引脚还有基本定时器TIM6(时间为500ms),主函数循环中每200ms切换LED0的状态。每500ms执行定时器中断服务函数,切换LED1状态。文章来源地址https://www.toymoban.com/news/detail-834815.html

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

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

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

相关文章

  • 【STM32】基本定时器

    基于stm32f103 基于《零死角玩转STM32—F103指南者》进行学习 基本定时器,通用定时器,高级定时器 简单来说就是来自APB或者AHB的时钟,经过PSC(1到65535分频),形成时基,每经过一个时基,TIM的cnt计数有一次,根据寄存器的配置,发生更新事件,比较事件等。 时钟源(预分频不

    2024年02月07日
    浏览(45)
  • STM32基本定时器

    1.时基单元 计数寄存器 (TIMx_CNT) 计数器从0累加计数到自动重装载数值(TIMx_ARR寄存器),然后重新从0开始计数并产生一个计数器溢出事件。 预分频寄存器 (TIMx_PSC) 它也有缓存,也是在更新事件产生时刷新缓存。 自动重装载寄存器(TIMx_ARR) 设置此值。计数器达到这个值,

    2024年01月18日
    浏览(46)
  • STM32:基本定时器原理和定时程序

            定时器就是计数器,定时器的作用就是设置一个时间,然后时间到后就会通过中断等方式通知STM32执行某些程序。定时器除了可以实现普通的定时功能,还可以实现捕获脉冲宽度,计算PWM占空比,输出PWM波形,编码器计数等。 STM32共11个定时器,2个高级控制定时器T

    2024年02月01日
    浏览(46)
  • STM32—定时器(TIM)_基本定时

    本文主要通过介绍定时器基本结构去学习如何使用定时器进行定时。 定时器可以对输入的时钟进行计数,并在计数值达到设定值时触发中断,从而达到计时功能。 本文从通用定时器介绍。本文所使用芯片为 STM32F103C8T6,拥有TIM1-TIM4 四个定时器资源。 图.2为基本定时器结构  

    2024年02月02日
    浏览(50)
  • STM32基本定时器中断

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 提示:这里可以添加本文要记录的大概内容: 定时器有什么用?精准延时,PWM,做一个时钟:年月日,时分秒。时钟最基本的就是1s怎么来? 提示:以下是本篇文章正文内容,下面案例可供参考 1.1如何实

    2024年02月06日
    浏览(49)
  • STM32之基本定时器中断

    一、TIM(Timer)定时器 基本定时器中断可以对输入的时钟进行计数,并在计数值达到设定值(自动重装值)时触发中断; 16位计数器、预分频器、自动重装寄存器的时基单元,在72MHz计数时钟下可以实现最大59.65s的定时; 不仅具备基本的定时中断功能,而且还包含内外时钟源

    2024年02月08日
    浏览(44)
  • 聊聊STM32的基本定时器

      STM32 的基本定时器(Basic Timer)是一种简单的定时器模块,用于生成基于时钟频率的定时中断。它可以用于实现各种定时和计时功能,例如延时、频率测量、PWM 生成等。 基本定时器通常由一个 16 位的自由运行计数器和一个预分频器组成。计数器的值可以根据预分频器的设

    2024年02月16日
    浏览(46)
  • STM32定时器基本知识

    STM32定时器 PWM模式 在上面的例子中,我们使用了STM32的定时器3和GPIOB的引脚4来控制电机的运动。 首先,我们需要在GPIO配置函数中使能GPIOB的时钟,并将PB4引脚配置为复用功能,用于TIM3的通道1。 然后,在定时器配置函数中,我们使能了TIM3的时钟,并配置了TIM3的基本参数和通

    2024年02月11日
    浏览(45)
  • STM32CubeMX教程5 TIM 定时器概述及基本定时器

    开发板(STM32F407G-DISC1) STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) ST-LINK/V2驱动 逻辑分析仪nanoDLA 使用STM32CubeMX软件配置STM32F407开发板 使用基本定时器TIM6实现每500ms控制绿灯状态变化一次,基本定时器TIM7实现每1s控制红灯状态变化一次 STM32F407拥有2个基础定时器、

    2024年02月03日
    浏览(92)
  • STM32 基本定时器反转LED

    引脚是什么为什么要初始化引脚?      在嵌入式系统中,引脚是微控制器或微处理器上的物理引脚,用于连接外部设备、传感器或其他芯片。每个引脚都有特定的功能和用途,例如输入、输出、模拟输入、电源供应等。STM32F103C8T6引脚图: 初始化引脚的目的在于: 确定引脚

    2024年01月25日
    浏览(44)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包