【超详细】定时器的使用

目录

  • 定时器的使用
    • 三种定时器的区别
    • 常用函数
      • HAL_TIM_Base_Init 介绍
    • 定时器配置流程
    • 定时器示例流程图
    • 定时器示例代码

定时器的使用

STM32F407定时器资源包含:2个基本定时器(TIM6、TIM7);10个通用定时器(TIM2~TIM5、 TIM9~TIM14)、2个高级控制定时器(TIM1、TIM8)。

三种定时器的区别

定时器类型 区别
基本定时器 用于实现简单的定时功能,没有外部IO输入,属于内部资源
通用定时器 除了基本的定时功能外,还支持输入捕获、输出比较、PWM生成等多种功能
高级定时器 全面功能:包含基本定时器和通用定时器的所有功能,并具备特殊功能和高精度控制,如死区时间控制、刹车功能、霍尔传感器接口等,特别适用于电机控制等复杂应用场景。
定时器类型 定时器 计数位数 计数模式 预分频系数 产生DMA请求 捕获/比较通道 互补输出 接口最大时钟 定时器最大时钟
基本定时器 TIM6 16 递增 1~65536 可以 0 42MHz 84MHz
基本定时器 TIM7 16 递增 1~65536 可以 0 42MHz 84MHz
通用定时器 TIM2 32 递增、递减、中央对齐 1~65536 可以 4 42MHz 84MHz
通用定时器 TIM5 32 递增、递减、中央对齐 1~65536 可以 4 42MHz 84MHz
通用定时器 TIM3 16 递增、递减、中央对齐 1~65536 可以 4 42MHz 84MHz
通用定时器 TIM4 16 递增、递减、中央对齐 1~65536 可以 4 42MHz 84MHz
通用定时器 TIM9 16 递增、递减、中央对齐 1~65536 不可以 2 84MHz 168MHz
通用定时器 TIM10 16 递增、递减、中央对齐 1~65536 不可以 1 84MHz 168MHz
通用定时器 TIM11 16 递增、递减、中央对齐 1~65536 不可以 1 84MHz 168MHz
通用定时器 TIM12 16 递增、递减、中央对齐 1~65536 不可以 2 42MHz 84MHz
通用定时器 TIM13 16 递增、递减、中央对齐 1~65536 不可以 1 42MHz 84MHz
通用定时器 TIM14 16 递增、递减、中央对齐 1~65536 不可以 1 42MHz 84MHz
高级定时器 TIM1 16 递增、递减、中央对齐 1~65536 可以 4 84MHz 168MHz
高级定时器 TIM8 16 递增、递减、中央对齐 1~65536 可以 4 84MHz 168MHz

常用函数

函数名 作用
HAL_TIM_Base_Init 用于初始化定时器
HAL_TIM_Base_Start_IT 用于更新定时器中断和使能定时器

HAL_TIM_Base_Init 介绍

函数原型:HAL_StatusTypeDef HAL_TIM_Base_Init(TIM_HandleTypeDef *htim);
函数形参:TIM_HandleTypeDef该结构体定义如下:

typedef struct
#endif /* USE_HAL_TIM_REGISTER_CALLBACKS */
{
  TIM_TypeDef                        *Instance;         /*!< Register base address		外设寄存器基地址*/
  TIM_Base_InitTypeDef               Init;              /*!< TIM Time Base required parameters	定时器初始化结构体*/
  HAL_TIM_ActiveChannel              Channel;           /*!< Active channel		定时器通道*/
  DMA_HandleTypeDef                  *hdma[7];          /*!< DMA Handlers array
                                                             This array is accessed by a @ref DMA_Handle_index 
                                                             DMA 管理结构体*/
  HAL_LockTypeDef                    Lock;              /*!< Locking object		锁定资源*/
  __IO HAL_TIM_StateTypeDef          State;             /*!< TIM operation state  定时器状态*/
	  __IO HAL_TIM_ChannelStateTypeDef   ChannelState[4];   /*!< TIM channel operation state		定时器通道状态*/
  __IO HAL_TIM_ChannelStateTypeDef   ChannelNState[4];  /*!< TIM complementary channel operation state  定时器互补通道状态*/
  __IO HAL_TIM_DMABurstStateTypeDef  DMABurstState;     /*!< DMA burst operation state  DMA 溢出状态*/
  } TIM_HandleTypeDef;
  1. Instance:指向定时器寄存器地址;
  2. Init:定时器初始化结构体(TIM_Base_InitTypeDef),用于配置定时器相关函数;
  3. Channel:定时器通道选择,注意基本定时器没有该功能;
  4. hdma[7]:用于配置定时器的DMA请求;
  5. Lock:ADC资源;
  6. State:定时器工作状态;
  7. ChannelState/ChannelNState:定时器通道/互补通道工作状态;
  8. DMABurstState:DMA溢出状态。
    其中定时器初始化结构体的详细内容如下:
typedef struct
{
  uint32_t Prescaler;         /*!< Specifies the prescaler value used to divide the TIM clock.
                                   This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF */

  uint32_t CounterMode;       /*!< Specifies the counter mode.
                                   This parameter can be a value of @ref TIM_Counter_Mode */

  uint32_t Period;            /*!< Specifies the period value to be loaded into the active
                                   Auto-Reload Register at the next update event.
                                   This parameter can be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF.  */

  uint32_t ClockDivision;     /*!< Specifies the clock division.
                                   This parameter can be a value of @ref TIM_ClockDivision */

  uint32_t RepetitionCounter;  /*!< Specifies the repetition counter value. Each time the RCR downcounter
                                    reaches zero, an update event is generated and counting restarts
                                    from the RCR value (N).
                                    This means in PWM mode that (N+1) corresponds to:
                                        - the number of PWM periods in edge-aligned mode
                                        - the number of half PWM period in center-aligned mode
                                     GP timers: this parameter must be a number between Min_Data = 0x00 and Max_Data = 0xFF.
                                     Advanced timers: this parameter must be a number between Min_Data = 0x0000 and Max_Data = 0xFFFF. */

  uint32_t AutoReloadPreload;  /*!< Specifies the auto-reload preload.
                                   This parameter can be a value of @ref TIM_AutoReloadPreload */
} TIM_Base_InitTypeDef;
  1. Prescaler:预分频系数,写入预分频寄存器的值的范围为0~6+5535;
  2. CounterMode:计数器技术模式,注意基本定时器只能向上计数;
  3. Period:自动重载值,写入自动重载寄存器的值范围为:0~65535;
  4. ClockDivision:时钟分频因子,定时器时钟CK_INT与数字滤波器所使用的采样时钟之间的分频比,基本定时器没有此功能;
  5. RepetitionCounter:设置重复计数器的值,用于高级定时器中;
  6. AutoReloadPreload:自动重载预装使能,即控制寄存器1的ARPE位。

定时器配置流程

  1. 开启定时器时钟:__HAL_RCC_TIMx_CLK_ENABLE();
  2. 初始化定时器参数,设置自动重装值、分频系数、计数方式等;
  3. 使能定时器更新中断,开启定时器计数,配置定时器中断优先级;
  4. 编写中断服务函数。

定时器示例流程图

【超详细】定时器的使用_第1张图片

定时器示例代码

头文件

#ifndef __BTIM_H__
#define __BTIM_H__

#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);    /* 基本定时器 定时中断初始化函数 */

#endif

C文件

#include "./BSP/led/led.h"
#include "./BSP/timer/btim.h"


TIM_HandleTypeDef g_timx_handler;         /* 定时器参数句柄 */

/**
 * @brief       基本定时器TIMX定时中断初始化函数
 * @note
 *              基本定时器的时钟来自APB1,当PPRE1 ≥ 2分频的时候
 *              基本定时器的时钟为APB1时钟的2倍, 而APB1为42M, 所以定时器时钟 = 84Mhz
 *              定时器溢出时间计算方法: 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_handler.Instance = BTIM_TIMX_INT;                      /* 定时器x */
    g_timx_handler.Init.Prescaler = psc;                          /* 分频 */
    g_timx_handler.Init.CounterMode = TIM_COUNTERMODE_UP;         /* 递增计数模式 */
    g_timx_handler.Init.Period = arr;                             /* 自动装载值 */
    HAL_TIM_Base_Init(&g_timx_handler);
    
    HAL_TIM_Base_Start_IT(&g_timx_handler);                       /* 使能定时器x和定时器更新中断 */
}

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

/**
 * @brief       基本定时器TIMX中断服务函数
 * @param       无
 * @retval      无
 */
void BTIM_TIMX_INT_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&g_timx_handler);  /* 定时器回调函数 */
}

/**
 * @brief       回调函数,定时器中断服务函数调用
 * @param       无
 * @retval      无
 */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == BTIM_TIMX_INT)
    {
        LED1_TOGGLE(); /* LED1反转 */
    }
}

main函数调用
btim_timx_int_init(5000 - 1, 8400 - 1); /* 84 000 000 / 84 00 = 10 000 10Khz的计数频率,计数5K次为500ms */

你可能感兴趣的:(STM32专题,单片机,嵌入式硬件)