前言
定时器是微控制器中的一种重要外设,用于测量时间间隔或生成精确的时间延迟。在STM32微控制器中,定时器具有多种功能和应用,是嵌入式系统开发中的基础内容。
一、定时器基本介绍
1. STM32定时器
STM32微控制器提供了多种类型的定时器,包括基本定时器、通用定时器和高级控制定时器。这些定时器可以用于定时、计数、PWM输出等多种应用。
2. 通用定时器功能和特点
通用定时器具有以下功能和特点:
-
多种计数模式(向上计数、向下计数、中央对齐模式)
-
可编程的预分频器
-
自动重装载功能
-
输入捕获和输出比较功能
-
支持产生更新事件和中断
3. 计数器模式
定时器可以配置为不同的计数模式,如向上计数模式、向下计数模式和中央对齐模式。在向上计数模式中,计数器从0开始计数,达到预设值后重新从0开始。在向下计数模式中,计数器从预设值开始计数,减到0后重新从预设值开始。
4. 定时器工作原理
a. 定时器框图
定时器的基本框图包括时钟产生器、时基单元、输入捕获通道和输出比较通道等部分。
b. 时钟产生器部分
时钟产生器部分负责为定时器提供时钟信号,可以通过内部时钟、外部时钟或外部触发信号作为时钟源。
c. 时基单元
时基单元包括预分频器和自动重装载寄存器,用于生成精确的时间间隔。
d. 输入捕获通道
输入捕获通道用于捕获外部信号的边沿,可以用于测量外部信号的频率或脉宽。
e. 输出比较通道(PWM)
输出比较通道可以生成PWM信号,用于控制电机、LED等设备。
二、定时器中断应用
1. 内部时钟选择
定时器可以使用内部时钟作为时钟源,通过配置时钟控制寄存器(CR1)选择内部时钟。
2. 计数器模式
定时器可以配置为向上计数模式或向下计数模式,通过配置计数器模式寄存器(CR1)选择计数模式。
3. 定时器中断实验相关寄存器
定时器中断实验主要涉及以下寄存器:
-
控制寄存器(CR1)
-
预分频器寄存器(PSC)
-
自动重装载寄存器(ARR)
-
中断使能寄存器(DIER)
-
状态寄存器(SR)
-
中断清除寄存器(EGR)
4. 常用库函数
STM32标准外设库提供了一系列函数用于定时器配置,如TIM_TimeBaseInit
、TIM_ITConfig
、TIM_Cmd
等。
TIM_TimeBaseInit:
- 功能: 初始化定时器的基本结构,包括预分频器、自动重装载寄存器、计数模式等。
- 函数原型:
void TIM_TimeBaseInit(TIM_TypeDef* TIMx, TIM_TimeBaseInitTypeDef* TIM_TimeBaseInitStruct);
- 参数:
-
TIMx
: 定时器外设,例如TIM1
,TIM2
等。 -
TIM_TimeBaseInitStruct
: 指向TIM_TimeBaseInitTypeDef
结构体的指针,包含定时器的配置信息。
-
TIM_ITConfig:
功能: 配置定时器的中断,使能或禁用指定的中断。
- 函数原型:
void TIM_ITConfig(TIM_TypeDef* TIMx, uint16_t TIM_IT, FunctionalState NewState);
- 参数:
-
TIMx
: 定时器外设,例如TIM1
,TIM2
等。 -
TIM_IT
: 指定要使能或禁用的中断,可以是更新中断、触发中断等。 -
NewState
: 新的状态,可以是ENABLE
或DISABLE
。
-
TIM_Cmd:
-
功能: 使能或禁用指定的定时器。
- 函数原型:
void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
- 参数:
-
TIMx
: 定时器外设,例如TIM1
,TIM2
等。 -
NewState
: 新的状态,可以是ENABLE
或DISABLE
。
-
5. 定时器中断实现步骤
-
初始化定时器,配置时钟源、预分频器和自动重装载值。
-
配置定时器中断,使能更新中断。
-
配置NVIC,使能定时器中断。
-
在中断处理函数中添加处理代码。
6. 应用实例
#include "stm32f10x.h"
void TIM2_Init(uint16_t arr, uint16_t psc) {
// 使能TIM2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 配置定时器
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = arr - 1; // 自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler = psc - 1; // 预分频器
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// 使能TIM2更新中断
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
// 使能TIM2
TIM_Cmd(TIM2, ENABLE);
}
void NVIC_Configuration(void) {
NVIC_InitTypeDef NVIC_InitStructure;
// 设置优先级分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
// 配置TIM2中断
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void TIM2_IRQHandler(void) {
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) {
// 清除中断标志
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
// 在此处添加定时器中断处理代码
GPIO_WriteBit(GPIOA, GPIO_Pin_1, (BitAction)(1 - GPIO_ReadOutputDataBit(GPIOA, GPIO_Pin_1)));
}
}
int main(void) {
// 初始化GPIO
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置NVIC
NVIC_Configuration();
// 初始化TIM2,设置定时周期为1s
TIM2_Init(1000, 7200);
while (1) {
// 主循环
}
}
三、定时器PWM输出实验
1. 通用定时器PWM概述
通用定时器可以配置为PWM模式,生成脉宽可调的PWM信号,用于控制电机、LED等设备。
2. PWM模式
PWM模式通过输出比较通道实现,可以配置为边沿对齐模式或中央对齐模式。在边沿对齐模式中,PWM信号在一个计数周期内只有一个跳变沿。在中央对齐模式中,PWM信号在一个计数周期内有两个跳变沿。
3. 相关寄存器介绍
PWM模式主要涉及以下寄存器:
-
控制寄存器(CR1)
-
输出比较模式寄存器(CCMR)
-
输出比较寄存器(CCR)
-
输出使能寄存器(CCER)
4. 定时器输出通道引脚
通用定时器的每个通道都有一个对应的输出引脚,如TIMx_CH1、TIMx_CH2等。
5. 定时器PWM库函数配置
STM32标准外设库提供了一系列函数用于PWM配置,如TIM_OCInit
、TIM_OC1PreloadConfig
、TIM_ARRPreloadConfig
等。
6. 实例
#include "stm32f10x.h"
void TIM2_PWM_Init(uint16_t arr, uint16_t psc) {
// 使能TIM2时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
// 使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 配置PA0为复用推挽输出
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 配置定时器
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_TimeBaseStructure.TIM_Period = arr - 1; // 自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler = psc - 1; // 预分频器
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
// 配置PWM模式
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = arr / 2; // 设置占空比
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC1Init(TIM2, &TIM_OCInitStructure);
// 使能TIM2
TIM_Cmd(TIM2, ENABLE);
}
int main(void) {
// 初始化TIM2,设置定时周期为1ms,PWM频率为1kHz
TIM2_PWM_Init(1000, 7200);
while (1) {
// 主循环
}
}
总结
STM32定时器是嵌入式系统开发中的基础内容,通过定时器,开发者可以实现精确的时间控制、PWM输出等功能。本文介绍了STM32定时器的基本概念、分类、工作方式、使用方法、通道,并通过多个示例展示了如何使用STM32定时器进行中断和PWM输出应用。希望这篇文章能帮助你更好地理解STM32定时器应用开发。