PWM互补输出,以及死区时间计算

本文基于野火例程进行解说

实验内容

本次实验输出一对互补的pwm波,且进行死区时间的计算说明。

代码

互补输出对应的定时器初始化代码:
bsp_advance_tim.c

/**
  ******************************************************************************
  * @file    bsp_advance_tim.c
  * @author  STMicroelectronics
  * @version V1.0
  * @date    2015-xx-xx
  * @brief   高级控制定时器互补输出范例
  ******************************************************************************
  * @attention
  *
  * 实验平台:野火  STM32 F407 开发板  
  * 论坛    :http://www.firebbs.cn
  * 淘宝    :http://firestm32.taobao.com
  *
  ******************************************************************************
  */
  
#include "./tim/bsp_advance_tim.h"

TIM_HandleTypeDef  TIM_TimeBaseStructure;
TIM_OC_InitTypeDef TIM_OCInitStructure;

__IO uint16_t ChannelPulse = 500;

/**
  * @brief  配置TIM复用输出PWM时用到的I/O
  * @param  无
  * @retval 无
  */
static void TIMx_GPIO_Config(void) 
{
	/*定义一个GPIO_InitTypeDef类型的结构体*/
	GPIO_InitTypeDef GPIO_InitStructure;

	/*开启定时器相关的GPIO外设时钟*/
	ADVANCE_OCPWM_GPIO_CLK_ENABLE();
	ADVANCE_OCNPWM_GPIO_CLK_ENABLE();
	ADVANCE_BKIN_GPIO_CLK_ENABLE(); 

	/* 定时器功能引脚初始化 */															   
	GPIO_InitStructure.Pin = ADVANCE_OCPWM_PIN;	
	GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;    
	GPIO_InitStructure.Pull = GPIO_NOPULL;
	GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; 	
	GPIO_InitStructure.Alternate = ADVANCE_OCPWM_AF;
	HAL_GPIO_Init(ADVANCE_OCPWM_GPIO_PORT, &GPIO_InitStructure);	

	GPIO_InitStructure.Pin = ADVANCE_OCNPWM_PIN;	
	GPIO_InitStructure.Alternate = ADVANCE_OCNPWM_AF;	
	HAL_GPIO_Init(ADVANCE_OCNPWM_GPIO_PORT, &GPIO_InitStructure);
	
	GPIO_InitStructure.Pin = ADVANCE_BKIN_PIN;	
	GPIO_InitStructure.Alternate = ADVANCE_BKIN_AF;	
	HAL_GPIO_Init(ADVANCE_BKIN_GPIO_PORT, &GPIO_InitStructure);
}

/*
 * 注意:TIM_TimeBaseInitTypeDef结构体里面有5个成员,TIM6和TIM7的寄存器里面只有
 * TIM_Prescaler和TIM_Period,所以使用TIM6和TIM7的时候只需初始化这两个成员即可,
 * 另外三个成员是通用定时器和高级定时器才有.
 *-----------------------------------------------------------------------------
 * TIM_Prescaler         都有
 * TIM_CounterMode			 TIMx,x[6,7]没有,其他都有(基本定时器)
 * TIM_Period            都有
 * TIM_ClockDivision     TIMx,x[6,7]没有,其他都有(基本定时器)
 * TIM_RepetitionCounter TIMx,x[1,8]才有(高级定时器)
 *-----------------------------------------------------------------------------
 */
static void TIM_Mode_Config(void)
{
	TIM_BreakDeadTimeConfigTypeDef TIM_BDTRInitStructure;
	// 开启TIMx_CLK,x[1,8] 
	ADVANCE_TIM_CLK_ENABLE(); 
	/* 定义定时器的句柄即确定定时器寄存器的基地址*/
	TIM_TimeBaseStructure.Instance = ADVANCE_TIM;
	/* 累计 TIM_Period个后产生一个更新或者中断*/		
	//当定时器从0计数到999,即为1000次,为一个定时周期
	TIM_TimeBaseStructure.Init.Period = 1000-1;
	// 高级控制定时器时钟源TIMxCLK = HCLK=168MHz 
	// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=1MHz
	TIM_TimeBaseStructure.Init.Prescaler = 168-1;	
	// 采样时钟分频
	TIM_TimeBaseStructure.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
	// 计数方式
	TIM_TimeBaseStructure.Init.CounterMode=TIM_COUNTERMODE_UP;
	// 重复计数器
	TIM_TimeBaseStructure.Init.RepetitionCounter=0;	
	// 初始化定时器TIMx, x[1,8]
	HAL_TIM_PWM_Init(&TIM_TimeBaseStructure);

	/*PWM模式配置*/
	//配置为PWM模式1
	TIM_OCInitStructure.OCMode = TIM_OCMODE_PWM1;
	TIM_OCInitStructure.Pulse = ChannelPulse;
	TIM_OCInitStructure.OCPolarity = TIM_OCPOLARITY_HIGH;
	TIM_OCInitStructure.OCNPolarity = TIM_OCNPOLARITY_HIGH;
	TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_SET;
	TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET;
	//初始化通道1输出PWM 
	HAL_TIM_PWM_ConfigChannel(&TIM_TimeBaseStructure,&TIM_OCInitStructure,TIM_CHANNEL_1);

	/* 自动输出使能,断路、死区时间和锁定配置 */
	TIM_BDTRInitStructure.OffStateRunMode = TIM_OSSR_ENABLE;
	TIM_BDTRInitStructure.OffStateIDLEMode = TIM_OSSI_ENABLE;
	TIM_BDTRInitStructure.LockLevel = TIM_LOCKLEVEL_1;
	TIM_BDTRInitStructure.DeadTime = 0xff;
	TIM_BDTRInitStructure.BreakState = TIM_BREAK_ENABLE;
	TIM_BDTRInitStructure.BreakPolarity = TIM_BREAKPOLARITY_LOW;
	TIM_BDTRInitStructure.AutomaticOutput = TIM_AUTOMATICOUTPUT_ENABLE;
	HAL_TIMEx_ConfigBreakDeadTime(&TIM_TimeBaseStructure, &TIM_BDTRInitStructure);

	/* 定时器通道1输出PWM */
	HAL_TIM_PWM_Start(&TIM_TimeBaseStructure,TIM_CHANNEL_1);
	/* 定时器通道1互补输出PWM */
	HAL_TIMEx_PWMN_Start(&TIM_TimeBaseStructure,TIM_CHANNEL_1);
}

/**
  * @brief  初始化高级控制定时器定时,1s产生一次中断
  * @param  无
  * @retval 无
  */
void TIMx_Configuration(void)
{
	TIMx_GPIO_Config();	

	TIM_Mode_Config();
}

/*********************************************END OF FILE**********************/

头文件:
bsp_advance_tim.h

#ifndef __ADVANCE_TIM_H
#define	__ADVANCE_TIM_H

#include "stm32f4xx.h"

/* 定时器 */
#define ADVANCE_TIM           				    TIM8
#define ADVANCE_TIM_CLK_ENABLE()  			  __TIM8_CLK_ENABLE()
 
/* TIM8通道1输出引脚 */
#define ADVANCE_OCPWM_PIN           		  GPIO_PIN_6              
#define ADVANCE_OCPWM_GPIO_PORT     		  GPIOC                      
#define ADVANCE_OCPWM_GPIO_CLK_ENABLE() 	__GPIOC_CLK_ENABLE()
#define ADVANCE_OCPWM_AF					        GPIO_AF3_TIM8

/* TIM8通道1互补输出引脚 */
#define ADVANCE_OCNPWM_PIN            		GPIO_PIN_5              
#define ADVANCE_OCNPWM_GPIO_PORT      		GPIOA                      
#define ADVANCE_OCNPWM_GPIO_CLK_ENABLE()	__GPIOA_CLK_ENABLE()
#define ADVANCE_OCNPWM_AF					        GPIO_AF3_TIM8

/* TIM8断路输入引脚 */
#define ADVANCE_BKIN_PIN              		GPIO_PIN_6              
#define ADVANCE_BKIN_GPIO_PORT        		GPIOA                      
#define ADVANCE_BKIN_GPIO_CLK_ENABLE()  	__GPIOA_CLK_ENABLE()
#define ADVANCE_BKIN_AF						        GPIO_AF3_TIM8


extern TIM_HandleTypeDef TIM_TimeBaseStructure;

void TIMx_Configuration(void);

#endif /* __ADVANCE_TIM_H */

代码讲解

断路功能

//在初始化文件里这几句代码配置了断路功能的模式


TIM_OCInitStructure.OCIdleState = TIM_OCIDLESTATE_SET;//当空闲状态下PWM通道置高电平
TIM_OCInitStructure.OCNIdleState = TIM_OCNIDLESTATE_RESET;//当空闲模状态下PWM互补通道置低电平
TIM_BDTRInitStructure.BreakState = TIM_BREAK_ENABLE;//开启断路功能
TIM_BDTRInitStructure.BreakPolarity = TIM_BREAKPOLARITY_LOW;//低电平断路
TIM_BDTRInitStructure.AutomaticOutput=TIM_AUTOMATICOUTPUT_ENABLE;//断路状态消失后,自动恢复输出

以上语句表示当断路功能对应的引脚输入变为低电平时,互补输出的功能就被禁止,此时变为空闲状态,而pwm对应的通道输出高电平,互补对应的通道变为低电平,而当断路功能对应的引脚变为高电平时,互补输出又再次出现。

死区时间计算请添加图片描述

请添加图片描述
通过上面两张图,就可以知道死区时间的计算公式了

下面列举出配置死区时间的代码

TIM_TimeBaseStructure.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;//设置分频系数,详细看第一张图。

TIM_BDTRInitStructure.DeadTime = 0xff;//配置死区时间,具体计算看第二章图



开始计算,假设定时器的频率为165Mhz,且配置语句TIM_BDTRInitStructure.DeadTime = 0xff,则DTG[7:0]被写入11111111,则对应第四个计算方式,TIM_TimeBaseStructure.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1表示对定时器频率1分频,则此时tDTS=1*Tck_int = (1/165000000)s,此时代码计算公式
DT=(32+DTG[4:0])*Tdtg=(32+31)16(1/165000000)*1000000us=6us

<think>好的,我现在需要解释互补PWM死区时间的原理工作方式。首先,用户提到互补PWM输出死区时间,我需要结合他们提供的引用内容来构建答案。 根据引用[2],互补PWM是两个相位相反的信号,控制互补的开关器件,比如MOS管。这两个信号的占空比之为1,确保一个高电平时另一个低电平。这样可以提高效率,减少损耗。但是,当这两个信号切换的时候,可能会因为开关延迟导致短暂的同时导通,这会产生很大的电流,损坏器件。这时候就需要死区时间。 引用[1]提到在配置互补PWM时设置了死区时间DEAD=100个定时器周期,说明死区时间是通过定时器来控制的。死区时间的作用是防止上下管同时导通,避免短路。 引用[3]展示了启动互补通道设置占空比的代码,但死区时间的设置可能在STM32CubeMX里配置定时器参数时完成,比如调整相关寄存器的值。 接下来,我需要解释死区时间的工作原理。当PWM信号需要切换状态时,比如从高到低或低到高,死区时间会在切换瞬间插入一个延迟,确保在关闭一个管后,稍等片刻再开启另一个管。这样两个管子不会同时导通。 作用方面,主要是防止短路,保护器件,提高系统可靠性。另外,引用[1][2]都提到这个保护措施的必要性。 可能用户还关心如何设置死区时间,比如在STM32中使用HAL库或者CubeMX配置,但用户现在的问题主要是原理作用,所以需要先集中解释这部分。同时,要确保用中文,数学公式用$...$,独立公式用$$...$$,并生成相关问题。 需要检查是否有遗漏点,比如死区时间的长短如何影响系统,或者不同应用中的典型值。但根据提供的引用,可能不需要深入这些细节,但可以简要提及。另外,要确保术语正确,比如互补PWM的应用场景,如电机驱动、电源转换等。 最后,生成的相关问题应该围绕死区时间的设置方法、影响、计算方式等,可能用户后续会想知道这些。</think>### 互补PWM死区时间的工作原理及作用 #### 1. 互补PWM的基本原理 互补PWM输出通过两个相位相反的信号(如$PWM$$PWM\_N$)控制一对互补的开关器件(如高侧MOS管低侧MOS管)。其占空比满足关系式: $$D + D\_N = 1$$ 其中$D$为主通道占空比,$D\_N$为互补通道占空比。这种设计可减少开关损耗并提高能量转换效率[^2]。 #### 2. 死区时间的必要性 当信号切换状态时(例如高电平转低电平或反之),由于开关器件的物理延迟(如关断时间$t_{\text{off}}$开启时间$t_{\text{on}}$),可能导致**上下管短暂同时导通**,形成短路电流。例如: - 高侧管未完全关断时,低侧管已开启 - 低侧管未完全关断时,高侧管已开启 此时会引发以下问题: $$I_{\text{short}} = \frac{V_{\text{DC}}}{R_{\text{on}}} \quad (\text{极大电流})$$ 其中$R_{\text{on}}$为导通电阻。这种电流可能烧毁器件[^1]。 #### 3. 死区时间的工作原理 死区时间通过插入延迟避免重叠导通: 1. **关闭当前导通管** 2. **等待固定时间$t_{\text{dead}}$**(死区时间) 3. **再开启另一侧管** 具体时序如下: - 主通道$PWM$下降沿 → 插入死区时间互补通道$PWM\_N$上升沿 - 互补通道$PWM\_N$下降沿 → 插入死区时间 → 主通道$PWM$上升沿 ![PWM死区时间示意图](https://img-blog.csdnimg.cn/direct/1d5d0caf8c6f4c6ab9a0b0c3d5d0d4b2.png) (注:示意图中灰色区域为死区时间) #### 4. 死区时间的实现方式 在MCU中通过定时器配置实现,例如STM32的TIM模块: - **寄存器设置**:直接写入死区时间参数(如`TIMx_BDTR`寄存器的`DTG`位) - **CubeMX配置**:在图形界面设置`Dead Time`值(单位为定时器时钟周期)[^3] 代码示例(HAL库): ```c HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2); // 主通道 HAL_TIMEx_PWMN_Start(&htim1, TIM_CHANNEL_2); // 互补通道 __HAL_TIM_SET_AUTORELOAD(&htim1, 1000); // 周期=1000个时钟周期 __HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, 250); // 占空比=25% ``` #### 5. 死区时间的作用总结 | 作用 | 说明 | |--------------|----------------------------------------------------------------------| | 防止短路 | 避免上下管同时导通导致的直通电流 | | 保护器件 | 降低开关损耗热应力,延长器件寿命 | | 提高可靠性 | 确保信号切换的确定性,减少电磁干扰(EMI) | #### 6. 典型应用场景 - 电机驱动(H桥电路) - DC-DC电源转换(同步整流) - 逆变器系统
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值