STM32 HAL 库中 TIM 定时器使用方法及案例

**在 STM32 的开发领域,定时器作为极为关键的外设,在众多场景中发挥着不可替代的作用。无论是精确的定时任务调度,如周期性的数据采集与处理;还是复杂的 PWM 输出应用,像电机转速的精准控制;亦或是时间测量相关的工作,比如测量外部信号的脉冲宽度,都离不开定时器的支持。本文将深入探讨 STM32 HAL 库中 TIM 定时器的使用方式,并结合具体案例详细阐述,帮助开发者更好地掌握这一强大工具。 **

TIM 定时器基础

在 STM32 体系中,TIM 定时器家族根据功能特性分为高级定时器、通用定时器和基本定时器。高级定时器功能最为丰富,除具备通用定时器的基本功能外,还拥有一些特殊功能,如带互补输出的 PWM 通道,常用于电机的全桥驱动控制。通用定时器则适用于大多数常规的定时、计数以及 PWM 输出场景。基本定时器相对简单,主要用于基本的定时功能。虽然它们的功能各有侧重,但底层工作原理却有相似之处。

工作原理

TIM 定时器本质上是一个计数器,其工作基于设定的时钟源进行计数操作。时钟源可以是内部的系统时钟,也可以是外部输入的时钟信号。当计数器数值达到预先设定的自动重载值(ARR)时,会触发溢出事件。这一事件可用于激活中断,使得 CPU 能够及时响应并执行特定的任务,比如更新传感器数据、控制通信接口的状态等。或是触发其他特定事件,如触发 DMA 传输,实现数据的自动搬运,提高系统效率。另外,通过对比较寄存器(CCR)的配置,能够实现定时比较功能,这在 PWM 输出等应用中发挥着重要作用。在 PWM 输出时,通过不断比较计数器值与 CCR 值,来确定输出引脚的电平状态,从而产生不同占空比的 PWM 波形。

HAL 库中 TIM 定时器的使用方法

初始化 TIM 定时器
利用 HAL 库初始化 TIM 定时器时,需要对定时器的时钟源、分频系数、计数模式以及自动重载值等关键参数进行配置。以下是一个通用定时器初始化的示例代码:

TIM_HandleTypeDef htim2;
// 定时器初始化函数
void TIM2_Init(void)
{
    // 选择TIM2定时器
    htim2.Instance = TIM2;
    // 分频系数设置,72MHz系统时钟分频后为1MHz,即每1微秒计数一次
    htim2.Init.Prescaler = 72 - 1;
    // 设置为向上计数模式,计数器从0开始,每次计数增加1,直到达到自动重载值
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    // 自动重载值设置,计数到999后溢出,配合1MHz计数频率,实现1ms定时
    htim2.Init.Period = 1000 - 1;
    // 时钟分频设置,这里不分频
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    // 调用HAL库函数进行定时器初始化
    if (HAL_TIM_Base_Init(&htim2)!= HAL_OK)
    {
        // 初始化失败,调用错误处理函数
        Error_Handler();
    }
}

在这段代码中,我们将 TIM2 的计数频率设置为 1MHz,每 1ms 便会产生一次溢出事件。这样的定时精度可以满足许多常见的应用需求,如 LED 的闪烁控制、简单的定时任务调度等。

启动和停止定时器

启动和停止定时器的操作非常简便,借助 HAL 库提供的函数即可完成:

// 启动定时器,使能定时器开始计数
HAL_TIM_Base_Start(&htim2);
// 停止定时器,计数器停止计数
HAL_TIM_Base_Stop(&htim2);

通过这两个函数,开发者可以灵活地控制定时器的运行状态。在需要进行精确时间测量时,先启动定时器,测量完成后及时停止,获取计数值进行后续处理。

定时器中断配置

若要在定时器溢出时执行特定操作,就需要进行中断配置。首先,在完成定时器初始化后,需使能定时器中断:

// 启动定时器中断,当定时器溢出时触发中断
HAL_TIM_Base_Start_IT(&htim2);

接着,在中断处理函数中编写具体执行代码。在 STM32 中,定时器中断处理函数通常位于stm32f4xx_it.c文件内:

void TIM2_IRQHandler(void)
{
    // 检查是否发生更新中断标志
    if (__HAL_TIM_GET_FLAG(&htim2, TIM_FLAG_UPDATE)!= RESET)
    {
        // 检查是否是更新中断源触发
        if (__HAL_TIM_GET_IT_SOURCE(&htim2, TIM_IT_UPDATE)!= RESET)
        {
            // 清除中断标志位,准备下一次中断
            __HAL_TIM_CLEAR_IT(&htim2, TIM_IT_UPDATE);
            // 在此编写定时中断执行代码
            // 例如:实现LED闪烁,假设PC13引脚连接LED
            HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
        }
    }
}

上述代码展示了,当定时器 TIM2 产生溢出中断时,会切换 PC13 引脚的电平状态,从而实现 LED 的闪烁效果。通过这种方式,可以利用定时器中断实现各种周期性的任务,如周期性的状态监测、数据发送等。

案例:使用 TIM 定时器产生 PWM 波控制舵机

使用 CubeMX 配置 TIM 定时器
打开 CubeMX 并创建新项目:选择对应的 STM32 芯片型号后进入配置界面。
配置时钟:确保系统时钟设置正确,这里我们设置为 72MHz。
选择 TIM 定时器:以 TIM3 为例,在Pinout & Configuration选项卡中找到 TIM3,将其Channel1设置为PWM Generation CH1。
配置 TIM3 参数:在Configuration选项卡中设置定时器参数。Prescaler设置为 72 – 1,使得定时器时钟频率为 1MHz;Counter Mode选择Up向上计数模式;Period设置为 19999,配合 1MHz 时钟频率,产生周期为 20ms 的 PWM 信号(舵机控制信号周期通常为 20ms)。
配置 PWM 通道参数:在TIM3 Channel1中,Mode选择PWM mode 1,Pulse初始值可设置为 1500(对应 1.5ms 的脉冲宽度,一般为舵机的中间位置),Polarity设置为High高电平有效。
生成代码:完成上述配置后,点击Project Manager,设置好项目名称、路径等,然后点击Generate Code生成代码。

代码实现

生成代码后,在main.c文件中添加如下代码:

#include "main.h"
#include "stm32f4xx_hal.h"

TIM_HandleTypeDef htim3;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_TIM3_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    MX_GPIO_Init();
    MX_TIM3_Init();

    // 启动PWM通道
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);

    while (1)
    {
        // 例如将舵机旋转到90度位置(假设对应2ms脉冲宽度,即2000的脉冲值)
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 2000);
        HAL_Delay(2000);
        // 将舵机旋转到0度位置(假设对应1ms脉冲宽度,即1000的脉冲值)
        __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, 1000);
        HAL_Delay(2000);
    }
}

void SystemClock_Config(void)
{
    // 时钟配置代码,由CubeMX生成
}

static void MX_GPIO_Init(void)
{
    // GPIO初始化代码,由CubeMX生成
}

static void MX_TIM3_Init(void)
{
    // TIM3初始化代码,由CubeMX生成
}

通过上述 CubeMX 配置和代码,我们实现了使用 TIM 定时器产生 PWM 波来控制舵机的转动。在实际应用中,可以根据具体需求调整 PWM 的脉冲宽度(即通过修改__HAL_TIM_SET_COMPARE函数中的参数),从而精确控制舵机的角度。

调整 PWM 占空比

在控制舵机时,通过修改比较寄存器(CCR)的值,也就是调整__HAL_TIM_SET_COMPARE函数中的参数,能够灵活调整 PWM 的占空比,进而控制舵机的角度。例如,将舵机旋转到某个特定角度对应的脉冲宽度值设置到__HAL_TIM_SET_COMPARE函数中,即可实现舵机的角度控制。

总结

通过上述内容的介绍以及实际案例的展示,我们深入了解了 STM32 HAL 库中 TIM 定时器的基本使用方法,涵盖定时器初始化、中断配置以及 PWM 输出等应用场景。定时器在 STM32 开发中占据着重要地位,熟练掌握其使用方法,对于构建复杂的嵌入式系统至关重要。希望本文能够助力大家在 STM32 开发过程中,更加高效地运用 TIM 定时器,实现更多创新的应用。

作者:B. D

物联沃分享整理
物联沃-IOTWORD物联网 » STM32 HAL 库中 TIM 定时器使用方法及案例

发表回复