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):
- 例如
TIM1
和TIM8
,具有高级功能,支持更复杂的 PWM 控制,适用于电机控制等高精度应用。
- 例如
1.2 定时器的工作原理
定时器基于一个内置的时钟源(通常是系统时钟),并通过分频器将系统时钟降低为定时器时钟。定时器会不断递增计数器的值,直到计数器的值达到预设的 自动重载寄存器(ARR),然后产生一个定时器溢出事件或中断。
1.3 定时器的常见功能
- 定时器中断:定时器溢出时触发中断,可以用来定时执行任务。
- PWM 输出:通过定时器控制占空比生成 PWM 波形,适用于电机控制、LED 灯光调光等。
- 输入捕获(IC):测量外部信号的频率和脉宽。
- 输出比较(OC):定时器比较当前计数值与预设值,生成精确的定时事件。
2. 定时器的配置
定时器配置通常包括以下几个步骤:
- 启用定时器时钟 :通过
RCC
模块启用定时器的时钟。 - 配置定时器参数:设置计数器的计数方向、预分频器、自动重载值等。
- 启动定时器:启动定时器工作。
- 配置定时器中断(可选):如果需要中断,启用定时器溢出中断,并在中断服务程序中处理。
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 代码解释
-
定时器初始化:
- 使用
__HAL_RCC_TIM3_CLK_ENABLE()
启用TIM3
的时钟。 - 使用
HAL_TIM_Base_Init()
配置定时器的预分频器和自动重载值(ARR)。在此示例中,预分频器设置为 8000,将时钟频率降低至 9kHz。自动重载值设置为 9000,使得定时器每秒溢出一次,生成一个 1Hz 的定时中断。
- 使用
-
定时器启动:
- 使用
HAL_TIM_Base_Start_IT()
启动定时器并使能中断。
- 使用
-
定时器中断服务函数:
TIM3_IRQHandler()
是定时器溢出的中断处理函数。当定时器计数到达溢出值时,会触发中断,在中断服务函数内进行操作。- 在中断服务函数中,每当定时器溢出时,会翻转 LED 的状态。
-
LED 状态翻转:
- 使用
HAL_GPIO_WritePin()
函数控制PA0
引脚的电平,根据LED_State
来决定是点亮还是熄灭 LED。
- 使用
4. 定时器的其他应用
除了基础的定时中断应用,定时器在 STM32F103 中还可以用来实现以下功能:
- PWM 输出:定时器可以用来产生 PWM 信号,控制电机、LED 等设备的转速或亮度。
- 输入捕获:通过定时器的输入捕获功能,可以测量外部信号的频率或脉冲宽度。
- 输出比较:定时器可以用来比较一个预设的值,触发精确的定时事件。
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 输出。