STM外设介绍2(Timer)

1. 定时器概述

在 STM32 系列微控制器中,定时器(Timer)是一个非常重要的外设,它能够提供精确的时间延时、定时控制、PWM 输出、事件计数、脉冲宽度调制(PWM)等多种功能。定时器通常用于定时中断、时间计数、精确延迟等场景。而中断在定时器的应用中起到了非常重要的作用,在完成定时器任务前我们应该先去了解它:
中断介绍https://blog.csdn.net/weixin_43756295/article/details/144549733

1.1 定时器的分类

STM32F103 中有多个定时器,这些定时器可以分为以下几类:

  • 基本定时器(Basic Timer)

    • 例如 TIM6, TIM7,这些定时器通常用于生成定时中断。
  • 通用定时器(General-purpose Timer)

    • 例如 TIM2, TIM3, TIM4, TIM5,这些定时器支持多种模式,如 PWM 输出、输入捕获、输出比较等。
  • 高级定时器(Advanced-control Timer)

    • 例如 TIM1TIM8,具有高级功能,支持更复杂的 PWM 控制,适用于电机控制等高精度应用。

1.2 定时器的工作原理

定时器基于一个内置的时钟源(通常是系统时钟),并通过分频器将系统时钟降低为定时器时钟。定时器会不断递增计数器的值,直到计数器的值达到预设的 自动重载寄存器(ARR),然后产生一个定时器溢出事件或中断。

1.3 定时器的常见功能

  • 定时器中断:定时器溢出时触发中断,可以用来定时执行任务。
  • PWM 输出:通过定时器控制占空比生成 PWM 波形,适用于电机控制、LED 灯光调光等。
  • 输入捕获(IC):测量外部信号的频率和脉宽。
  • 输出比较(OC):定时器比较当前计数值与预设值,生成精确的定时事件。

2. 定时器的配置

定时器配置通常包括以下几个步骤:

  1. 启用定时器时钟 :通过 RCC 模块启用定时器的时钟。
  2. 配置定时器参数:设置计数器的计数方向、预分频器、自动重载值等。
  3. 启动定时器:启动定时器工作。
  4. 配置定时器中断(可选):如果需要中断,启用定时器溢出中断,并在中断服务程序中处理。

3. 定时器在 STM32F103 上的应用:基础定时器

这里将展示如何在 STM32F103 上使用定时器生成定时中断,定时中断每秒触发一次,执行一个简单的操作(例如,切换一个 LED 的状态)。

3.1 代码实现:使用 TIM3 生成定时中断

硬件连接
  • 将 LED 的正极连接到 PA0 引脚,负极通过一个 330Ω 电阻连接到 GND。
代码实现

以下示例代码演示了如何使用 STM32F103 的 TIM3 定时器生成定时中断,并在中断服务函数中切换 LED 状态。

cpp 复制代码
#include "main.h"

// LED 状态变量
volatile uint8_t LED_State = 0;

// 初始化 TIM3 定时器
void TIM3_Init(void) {
    // 1. 启用 TIM3 时钟
    __HAL_RCC_TIM3_CLK_ENABLE();

    // 2. 配置 PA0 为推挽输出,用于控制 LED
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // 3. 配置定时器 TIM3
    TIM_HandleTypeDef htim3;
    htim3.Instance = TIM3;
    htim3.Init.Prescaler = 8000 - 1; // 分频值 8000 (APB1 频率 72MHz / 8000 = 9kHz)
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数
    htim3.Init.Period = 9000 - 1; // 定时器计数周期 (9kHz / 9000 = 1Hz)
    htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

    // 4. 初始化 TIM3
    if (HAL_TIM_Base_Init(&htim3) != HAL_OK) {
        // Initialization Error
        Error_Handler();
    }

    // 5. 启动 TIM3 中断
    HAL_TIM_Base_Start_IT(&htim3);
    
    // 6. 配置 NVIC,启用 TIM3 中断
    HAL_NVIC_SetPriority(TIM3_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(TIM3_IRQn);
}

// TIM3 中断处理函数
void TIM3_IRQHandler(void) {
    // 检查定时器更新中断标志位
    if (__HAL_TIM_GET_FLAG(&htim3, TIM_FLAG_UPDATE) != RESET) {
        if (__HAL_TIM_GET_IT_SOURCE(&htim3, TIM_IT_UPDATE) != RESET) {
            __HAL_TIM_CLEAR_IT(&htim3, TIM_IT_UPDATE);

            // 翻转 LED 状态
            LED_State = !LED_State;
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, LED_State ? GPIO_PIN_SET : GPIO_PIN_RESET);
        }
    }
}

int main(void) {
    // HAL 库初始化
    HAL_Init();

    // 初始化 TIM3 定时器
    TIM3_Init();

    while (1) {
        // 主循环,空闲,等待中断
    }
}

3.2 代码解释

  1. 定时器初始化

    • 使用 __HAL_RCC_TIM3_CLK_ENABLE() 启用 TIM3 的时钟。
    • 使用 HAL_TIM_Base_Init() 配置定时器的预分频器和自动重载值(ARR)。在此示例中,预分频器设置为 8000,将时钟频率降低至 9kHz。自动重载值设置为 9000,使得定时器每秒溢出一次,生成一个 1Hz 的定时中断。
  2. 定时器启动

    • 使用 HAL_TIM_Base_Start_IT() 启动定时器并使能中断。
  3. 定时器中断服务函数

    • TIM3_IRQHandler() 是定时器溢出的中断处理函数。当定时器计数到达溢出值时,会触发中断,在中断服务函数内进行操作。
    • 在中断服务函数中,每当定时器溢出时,会翻转 LED 的状态。
  4. LED 状态翻转

    • 使用 HAL_GPIO_WritePin() 函数控制 PA0 引脚的电平,根据 LED_State 来决定是点亮还是熄灭 LED。

4. 定时器的其他应用

除了基础的定时中断应用,定时器在 STM32F103 中还可以用来实现以下功能:

  1. PWM 输出:定时器可以用来产生 PWM 信号,控制电机、LED 等设备的转速或亮度。
  2. 输入捕获:通过定时器的输入捕获功能,可以测量外部信号的频率或脉冲宽度。
  3. 输出比较:定时器可以用来比较一个预设的值,触发精确的定时事件。
PWM 输出示例
cpp 复制代码
// 生成 PWM 输出
void TIM3_PWM_Init(void) {
    // 启用 TIM3 时钟
    __HAL_RCC_TIM3_CLK_ENABLE();
    
    // 配置 PA6 为定时器 3 的 PWM 输出
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;    // 复用推挽输出模式
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    // 配置 TIM3 PWM 模式
    TIM_HandleTypeDef htim3;
    htim3.Instance = TIM3;
    htim3.Init.Prescaler = 72 - 1;             // 72MHz / 72 = 1 MHz
    htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim3.Init.Period = 1000 - 1;              // PWM 频率为 1kHz
    htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    HAL_TIM_PWM_Init(&htim3);

    // 配置 PWM 通道
    TIM_OC_InitTypeDef sConfigOC = {0};
    sConfigOC.OCMode = TIM_OCMODE_PWM1;
    sConfigOC.Pulse = 500;                    // 占空比 50%
    sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
    HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1);

    // 启动 PWM 输出
    HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
}

总结

  • 定时器是 STM32 微控制器中的重要外设,广泛应用于定时、PWM 控制、频率测量等场景。
  • 使用定时器可以轻松实现定时中断、PWM 输出等功能,特别适用于嵌入式系统的任务调度和控制。
  • 本文通过 STM32F103 的 TIM3 定时器示例,展示了如何配置定时器、使用定时中断、以及如何通过定时器生成 PWM 输出。
相关推荐
嵌入式小强工作室2 小时前
stm32 iic电阻怎么选
stm32·单片机·嵌入式硬件
jinkang_zhao2 小时前
STM32, GD32 cubemx CAN 低速率125kbps 报文丢失,解决了
stm32·单片机·嵌入式硬件
whaosoft-1433 小时前
51c嵌入式~合集3
嵌入式硬件
南城花随雪。3 小时前
单片机:实现蜂鸣器数码管的显示(附带源码)
单片机·嵌入式硬件
Be Legendary-CGK4 小时前
【硬件接口】I2C总线接口
单片机·嵌入式硬件·硬件工程
wait_for_STM324 小时前
在Proteus软件仿真STM32F103寄存器方式PID调速电机
stm32·嵌入式硬件·proteus·pid调速
哈士奇上蔚6 小时前
STM32使用SFUD库驱动W25Q64
stm32·嵌入式硬件
Peter_Gao_6 小时前
单片机STM32、GD32、ESP32开发板的差异和应用场景
stm32·单片机·嵌入式硬件
大风起兮126 小时前
STM32HAL I2C函数
stm32·单片机·嵌入式硬件