STM32高级定时器死区时间配置实战:从理论到寄存器设置

张开发
2026/4/11 12:49:18 15 分钟阅读

分享文章

STM32高级定时器死区时间配置实战:从理论到寄存器设置
1. 死区时间到底是什么我第一次接触死区时间这个概念是在做一个电机驱动项目的时候。当时用STM32的高级定时器输出互补PWM信号控制H桥电路结果电机转动时总是发出奇怪的噪音测量波形发现上下管居然有同时导通的情况后来才知道是因为没有正确配置死区时间。简单来说死区时间就是在互补PWM信号切换时插入的一段安全间隔。想象一下十字路口的红绿灯如果绿灯刚灭红灯就亮可能会有车来不及刹车导致事故。所以实际设计中红灯亮之前会留出几秒的黄灯时间这就是死区。在电力电子中这个黄灯时间更加关键。以常见的H桥电路为例上管Q1和下管Q2绝对不能同时导通但MOS管/IGBT的关断需要时间t_off如果Q1刚关断就立即开通Q2由于Q1还没完全关断就会导致直通短路死区时间就是确保Q1完全关断后再开通Q2的安全延时2. STM32如何生成带死区的PWMSTM32的高级定时器TIM1/TIM8有个很实用的功能 - 硬件死区发生器。它可以在互补PWM输出通道CHx和CHxN之间自动插入可编程的死区时间完全由硬件实现不占用CPU资源。2.1 关键寄存器解析死区配置主要涉及两个寄存器TIMx_CR1控制寄存器1CKD[1:0]时钟分频因子决定t_DTS时钟频率00t_DTS t_CK_INT01t_DTS t_CK_INT/210t_DTS t_CK_INT/4TIMx_BDTR刹车和死区寄存器DTG[7:0]死区时间配置值这个8位值会根据不同区间采用不同的计算公式2.2 死区时间计算公式死区时间DT的计算有四种模式取决于DTG[7:0]的取值模式1DTG[7:0] ≤ 127 DT DTG[7:0] × t_DTS例如DTG10t_DTS13.89ns → DT138.9ns模式264 ≤ DTG[5:0]64 ≤ 127 DT (64 DTG[5:0]) × 2 × t_DTS例如DTG0x88136实际使用低6位8DT (648)×2×13.89ns 2000ns模式332 ≤ DTG[4:0]32 ≤ 63 DT (32 DTG[4:0]) × 8 × t_DTS模式432 ≤ DTG[4:0]32 ≤ 63 DT (32 DTG[4:0]) × 16 × t_DTS实际项目中我通常会先用Excel做个计算器输入需要的死区时间自动推荐最佳DTG值这比手动计算方便多了。3. 实战配置步骤下面以STM32F407的TIM1为例演示如何配置1us的死区时间。假设系统时钟为168MHz定时器不分频t_CK_INT1/168MHz5.95ns。3.1 初始化代码// 时基单元配置 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period 1000-1; // 自动重装载值 TIM_TimeBaseStructure.TIM_Prescaler 0; // 无预分频 TIM_TimeBaseStructure.TIM_ClockDivision TIM_CKD_DIV1; // t_DTS t_CK_INT TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, TIM_TimeBaseStructure); // 输出比较配置 TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse 500; // 50%占空比 TIM_OCInitStructure.TIM_OCPolarity TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity TIM_OCPolarity_High; TIM_OC1Init(TIM1, TIM_OCInitStructure); // 死区时间配置 TIM_BDTRInitTypeDef TIM_BDTRInitStructure; TIM_BDTRInitStructure.TIM_DeadTime 168; // 计算过程见下文 TIM_BDTRInitStructure.TIM_OSSRState TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_Break TIM_Break_Disable; TIM_BDTRInitStructure.TIM_AutomaticOutput TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, TIM_BDTRInitStructure); // 使能定时器 TIM_Cmd(TIM1, ENABLE); TIM_CtrlPWMOutputs(TIM1, ENABLE);3.2 死区时间计算我们需要1us的死区时间t_DTS t_CK_INT 5.95ns选择模式1DT DTG × t_DTSDTG 1us / 5.95ns ≈ 168由于168 127不能使用模式1。改用模式2 DT (64 DTG[5:0]) × 2 × t_DTS解得DTG[5:0] (1us / (2×5.95ns)) - 64 ≈ 20所以DTG[7:0] 0b10100100 0xA44. 常见问题排查在实际项目中我遇到过几个典型的死区时间配置问题4.1 死区时间不生效症状测量CH和CHN信号发现没有死区 可能原因忘记调用TIM_CtrlPWMOutputs()使能主输出BDTR寄存器的MOE位没有置1互补输出通道没有使能TIM_OutputNState4.2 死区时间值不对症状实测死区时间与计算值不符 检查点确认系统时钟和定时器时钟分频配置检查TIMx_CR1的CKD设置是否正确确保DTG值落在正确的区间内用示波器测量时注意探头接地要尽量短4.3 奇怪的波形失真症状死区区间波形出现振荡或毛刺 解决方法检查PCB布局PWM走线要尽量短增加适当的RC滤波通常10-100Ω 100pF在MOS管栅极加下拉电阻10kΩ5. 进阶技巧5.1 动态调整死区时间有些应用需要根据温度或负载动态调整死区时间。可以通过修改BDTR的DTG位实现// 运行时修改死区时间为2us uint16_t deadtime (uint16_t)(2000 / (2 * 5.95)) - 64; TIM1-BDTR ~TIM_BDTR_DTG; // 清除原值 TIM1-BDTR | (deadtime 0x7F) | TIM_BDTR_MOE; // 设置新值5.2 使用CubeMX配置对于新手推荐使用STM32CubeMX图形化配置在Timers标签页选择高级定时器开启互补通道和死区时间输入期望的死区时间ns生成代码时会自动计算正确的DTG值5.3 示波器测量技巧准确测量死区时间需要使用两个探头分别测量CH和CHN设置触发模式为边沿触发打开示波器的延迟测量功能适当调整时基建议每个格子显示100-500ns我在电机控制项目中总结出一个经验实际死区时间应该比理论计算值多留20%余量以应对元件老化带来的开关速度变化。

更多文章