STM32F407定时器终极指南:从基础到高级应用全解析
本文深入剖析STM32F407的11个定时器,详细对比各类定时器的功能差异,并提供典型场景的实战配置指南。
一、STM32F407定时器全景图
STM32F407包含11个定时器,分为四大类型:
| 类型 | 包含定时器 | 数量 | 主要特性 |
|---|---|---|---|
| 高级控制定时器 | TIM1, TIM8 | 2 | 互补PWM输出,死区控制 |
| 通用定时器 | TIM2-TIM5, TIM9-TIM14 | 10 | 输入捕获/PWM/编码器接口 |
| 基本定时器 | TIM6, TIM7 | 2 | 基础时基生成 |
| 系统定时器 | SysTick | 1 | 系统节拍定时 |
💡 关键参数:
- 所有定时器均为16位(除TIM2/TIM5为32位)
- 最大计数频率:168 MHz
- 支持时钟分频:1-65536
二、定时器功能深度对比
1. 定时器核心功能矩阵
| 功能 | 高级(TIM1/8) | 通用(TIM2-5) | 通用(TIM9-14) | 基本(TIM6/7) |
|---|---|---|---|---|
| 向上计数 | ✅ | ✅ | ✅ | ✅ |
| 向下计数 | ✅ | ✅ | ✅ | ✅ |
| 中央对齐 | ✅ | ✅ | ❌ | ❌ |
| PWM输出 | ✅ (4通道) | ✅ (4通道) | ✅ (2通道) | ❌ |
| 互补PWM输出 | ✅ | ❌ | ❌ | ❌ |
| 输入捕获 | ✅ | ✅ | ✅ | ❌ |
| 编码器接口 | ✅ | ✅ | ❌ (TIM9-14无) | ❌ |
| 外部触发 | ✅ | ✅ | ❌ | ❌ |
| DMA请求 | ✅ | ✅ | ✅ | ✅ |
| 霍尔传感器接口 | ✅ | ❌ | ❌ | ❌ |
2. 中断与事件能力
| 事件类型 | TIM1/8 | TIM2-5 | TIM9-14 | TIM6/7 |
|---|---|---|---|---|
| 更新中断 | ✅ | ✅ | ✅ | ✅ |
| 捕获/比较中断 | ✅ | ✅ | ✅ | ❌ |
| 触发中断 | ✅ | ✅ | ❌ | ❌ |
| 刹车中断 | ✅ | ❌ | ❌ | ❌ |
| 中断优先级 | 可配置 | 可配置 | 可配置 | 可配置 |
三、定时器应用场景指南
1. 基础定时中断 - TIM6/TIM7
// 配置1ms定时中断
void TIM6_Init(void) {
RCC->APB1ENR |= RCC_APB1ENR_TIM6EN;// 使能时钟
TIM6->PSC = 8400 - 1;// 84MHz/8400 = 10kHz
TIM6->ARR = 10 - 1;// 10kHz/10 = 1kHz (1ms)
TIM6->DIER |= TIM_DIER_UIE; // 使能更新中断
NVIC_EnableIRQ(TIM6_DAC_IRQn);
TIM6->CR1 |= TIM_CR1_CEN;// 启动定时器
}
// 中断服务函数
void TIM6_DAC_IRQHandler(void) {
if(TIM6->SR & TIM_SR_UIF) {
TIM6->SR &= ~TIM_SR_UIF; // 清除标志
// 用户代码...
}
}
适用场景:
- 系统心跳时钟
- 简单延时任务
- ADC采样触发
2. 高级PWM控制 - TIM1/TIM8
// 配置互补PWM输出
void TIM1_PWM_Init(void) {
// 1. 时钟使能(略)
TIM1->PSC = 0;// 无分频
TIM1->ARR = 1000-1;// PWM周期 = 84MHz/1000 = 84kHz
// 通道1配置
TIM1->CCMR1 |= TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2; // PWM模式1
TIM1->CCER |= TIM_CCER_CC1E;// 使能CH1输出
TIM1->CCR1 = 300;// 占空比30%
// 互补通道配置
TIM1->CCER |= TIM_CCER_CC1NE; // 使能互补输出
TIM1->BDTR |= TIM_BDTR_MOE | TIM_BDTR_OSSR; // 主输出使能
// 死区时间配置(约100ns)
TIM1->BDTR |= (5 << TIM_BDTR_DTG_Pos);
TIM1->CR1 |= TIM_CR1_CEN; // 启动定时器
}
适用场景:
- 电机驱动(H桥控制)
- 开关电源
- 需要死区控制的逆变电路
3. 输入捕获 - TIM2/TIM3/TIM4/TIM5
// 测量脉冲宽度
void TIM2_InputCapture_Init(void) {
// 1. 时钟使能(略)
TIM2->PSC = 84-1; // 1MHz计数频率
// 通道1配置为输入捕获
TIM2->CCMR1 |= TIM_CCMR1_CC1S_0; // CC1通道输入
TIM2->CCER |= TIM_CCER_CC1E;// 使能捕获
// 双边沿触发
TIM2->CCER |= TIM_CCER_CC1P | TIM_CCER_CC1NP;
// 中断配置
TIM2->DIER |= TIM_DIER_CC1IE;
NVIC_EnableIRQ(TIM2_IRQn);
TIM2->CR1 |= TIM_CR1_CEN; // 启动
}
// 中断处理
uint32_t pulseWidth = 0;
void TIM2_IRQHandler(void) {
static uint32_t firstVal = 0;
if(TIM2->SR & TIM_SR_CC1IF) {
if(firstVal == 0) {
firstVal = TIM2->CCR1; // 记录上升沿
} else {
pulseWidth = TIM2->CCR1 - firstVal; // 计算脉宽
firstVal = 0;
}
TIM2->SR &= ~TIM_SR_CC1IF; // 清除标志
}
}
适用场景:
- 超声波测距
- 红外遥控解码
- 旋转编码器计数
4. 编码器接口模式 - TIM2/TIM3/TIM4/TIM5
// 编码器模式配置
void TIM3_Encoder_Init(void) {
// 1. 时钟使能(略)
TIM3->PSC = 0; // 无分频
// 编码器接口模式3(双沿计数)
TIM3->SMCR |= TIM_SMCR_SMS_0 | TIM_SMCR_SMS_1;
// 输入捕获配置
TIM3->CCMR1 |= TIM_CCMR1_CC1S_0 | TIM_CCMR1_CC2S_0;
TIM3->CCER |= TIM_CCER_CC1E | TIM_CCER_CC2E;
TIM3->CNT = 0; // 计数器归零
TIM3->CR1 |= TIM_CR1_CEN; // 启动
}
适用场景:
- 电机转速测量
- 位置控制系统
- 旋转角度检测
四、定时器时钟配置技巧
F407时钟树关键点:
+------------------+
| HSE (8-26 MHz)|
+--------+---------+
|
+--------v---------+
| PLL (168 MHz)|
+--------+---------+
|
+--------v---------+
| APB1 (42 MHz)|---> TIM2-7, TIM12-14
+--------+---------+(时钟x2 = 84MHz)
|
+--------v---------+
| APB2 (84 MHz)|---> TIM1,8-11, SysTick
+------------------+(时钟x1 = 84MHz)
配置公式:
定时器频率 = \frac{APB总线频率}{(PSC+1)}
定时周期 = \frac{ARR+1}{定时器频率}
计算示例:
目标:1kHz PWM,分辨率1%
- 需要ARR ≥ 100
- 定时器频率 = 1kHz * 100 = 100kHz
- 若APB2=84MHz → PSC = 84MHz/100kHz - 1 = 839
五、高级应用场景与定时器选型
1. 多定时器协同工作
2. 精密定时场景选型
| 需求 | 推荐定时器 | 理由 |
|---|---|---|
| 长时间计时 | TIM2/TIM5 | 32位计数器 |
| 高精度PWM | TIM1 + APB2 | 最高时钟频率 |
| 多通道同步 | TIM1/TIM8 | 支持主从模式 |
| 超低功耗定时 | LPTIM | 独立时钟域 |
3. 特殊功能实现
| 功能 | 实现方案 | 关键配置 |
|---|---|---|
| DAC触发 | TIM6/TIM7 | TRGO输出 |
| ADC同步采样 | TIM2/TIM3/TIM4 | 主模式 |
| 步进电机控制 | TIM1 + TIM8 | 互补PWM+死区 |
| 数字电源闭环控制 | TIM1 | 刹车输入+触发ADC |
六、避坑指南与最佳实践
- PSC/ARR配置黄金法则:
// 错误:同时修改PSC和ARR可能导致毛刺
// 正确:使用预装载寄存器
TIMx->EGR |= TIM_EGR_UG; // 产生更新事件
TIMx->CR1 |= TIM_CR1_ARPE; // 使能ARR预装载
- 中断优化技巧:
// 避免在中断中计算耗时操作
// 使用DMA传输捕获数据
TIMx->DIER |= TIM_DIER_CC1DE; // 使能捕获DMA
- PWM输出保护:
// 配置刹车输入(高级定时器)
TIM1->BDTR |= TIM_BDTR_BKE; // 使能刹车
TIM1->BDTR |= TIM_BDTR_BKP; // 刹车极性
- 32位定时器妙用:
// 联合两个16位定时器实现32位计数
TIM2->SMCR |= TIM_SMCR_TS_0 | TIM_SMCR_TS_2; // TIM3作为触发源
TIM3->CR2 |= TIM_CR2_MMS_1; // 更新事件作为触发输出
七、实战案例:呼吸灯三方案对比
方案1:基本定时器 + GPIO翻转
// TIM6中断中翻转GPIO
void TIM6_IRQHandler() {
static uint32_t cnt = 0;
if(++cnt >= brightness) {
GPIO_Toggle();
cnt = 0;
}
}
缺点:CPU占用率高,精度低
方案2:通用定时器PWM
// TIM3 PWM输出
TIM3->CCR3 = brightness; // 直接设置占空比
优点:硬件自动控制,零CPU占用
方案3:高级定时器互补PWM
// TIM1通道1主输出,通道1N互补
TIM1->CCR1 = brightness;
TIM1->CCR1N = 100 - brightness; // 互补输出
适用:需要对称控制的RGB灯带
总结:定时器选型决策树
掌握这些技巧,您将能充分发挥STM32F407定时器的强大功能!实际开发中请结合《参考手册》RM0090第13-18章进行寄存器级配置。
1万+

被折叠的 条评论
为什么被折叠?



