stm32关于PWM死区(Dead Zone)

=============================================================== 1 ====================================================================

PWM输出时的Dead Zone(死区)作用是在电平翻转时插入一个时间间隔,避免关闭前一个设备和打开后一个设备时因为开关速度的问题出现同时开启状态而增加负荷的情况(在没有彻底关闭前打开了后一个设备),尤其是电流过大时容易造成短路等损坏设备,如:互补PWM波输出在逆变器(直流转交流)中的应用。

    PWM(Pulse Width Modulation),即脉宽调制,简单来说就是一些矩形脉冲波形,PWM波形最重要的参数是频率和占空比。PWM是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在测量、通信、功率控制与信号变换的许多领域中。

    更具体的理解是,通常大功率电机、变频器等,末端都是由大功率管、IGBT等元件组成的H桥或3相桥。每个桥的上半桥和下半桥是绝对不能同时导通的,但高速的PWM驱动信号在达到功率元件的控制端时,往往会由于各种各样的原因产生延迟的效果,造成某个半桥元件在应该关断时没有关断,造成功率元件烧毁。

PWM死区(Dead <wbr>Zone)的作用和意义

PWM死区(Dead <wbr>Zone)的作用和意义
 

    当比较单元的比较操作被使能,就会产生波形PHx。PHx经过死区单元,就会输出两路互补的带有死区的PWM波形DTPHx和DTPHx_。PHx、DTPHx、DTPHx_之间的关系如上图,如果没有死区,那么DTPHx和DTPHx_应该是完全互补的。DTPHx的导通时刻是在PHx的基础上延时了1个死区时间,而关闭时刻未变。DTPHx_是在PHx取反的基础上,也将导通时间延迟了1个死区时间,而关断的时间没有发生改变。


    对于比较先进的处理一般都带有Dead Zone的配置,比如s5pv210处理器就可以配置成带有Dead Zone互补的PWM波输出,如下图所示:

PWM死区(Dead <wbr>Zone)的作用和意义

这是电机控制方面的,让桥臂上的上面两个管子或下面两个同时给高电平即为刹车。

不让同边导通 为死区。

=============================================================== 2 ====================================================================

死区,简单解释:
       通常,大功率电机、变频器等,末端都是由大功率管、IGBT等元件组成的H桥或3相桥。
每个桥的上半桥和下半桥是是绝对不能同时导通的,但高速的PWM驱动信号在达到功率元件的控制极时,往往会由于各种各样的原因产生延迟的效果,造成某个半桥元件在应该关断时没有关断,造成功率元件烧毁。
死区就是在上半桥关断后,延迟一段时间再打开下半桥或在下半桥关断后,延迟一段时间再打开上半桥,从而避免功率元件烧毁。这段延迟时间就是死区。(就是上、下半桥的元件都是关断的)死区时间控制在通常的低端单片机所配备的PWM中是没有的。

看STM32手册 高级定时器有这么一行 一直不理解deadtime什么意思


16-bit, motor control PWM timer with deadtime generation and emergency stop


死区,简单解释:通常,大功率电机、变频器等,末端都是由大功率管、IGBT等元件组成的H桥或3相桥。每个桥的上半桥和下半桥是是绝对不能同时导通的,但高速的PWM驱动信号在达到功率元件的控制极时,往往会由于各种各样的原因产生延迟的效果,造成某个半桥元件在应该关断时没有关断,造成功率元件烧毁。死区就是在上半桥关断后,延迟一段时间再打开下半桥或在下半桥关断后,延迟一段时间再打开上半桥,从而避免功率元件烧毁。这段延迟时间就是死区。(就是上、下半桥的元件都是关断的)死区时间控制在通常的低端单片机所配备的PWM中是没有的。


==============================================================================

PWM的上下桥臂的三极管是不能同时导通的。如果同时导通就会是电源两端短路。所以,两路触发信号要在一段时间内都是使三极管断开的。这个区域就叫做“死区”优点就不用说了。缺点是使谐波的含量有所增加


附:

H桥驱动电路原理

一、H桥驱动电路
图4.12中所示为一个典型的直流电机控制电路。电路得名于“H桥驱动电路”是因为它的形状酷似字母H。4个三极管组成H的4条垂直腿,而电机就是H中的横杠(注意:图4.12及随后的两个图都只是示意图,而不是完整的电路图,其中三极管的驱动电路没有画出来)。如图所示,H桥式电机驱动电路包括 4个三极管和一个电机。要使电机运转,必须导通对角线上的一对三极管。根据不同三极管对的导通情况,电流可能会从左至右或从右至左流过电机,从而控制电机的转向。


要使电机运转,必须使对角线上的一对三极管导通。例如,如图4.13所示,当Q1管和Q4管导通时,电流就从电源正极经Q1从左至右穿过电机,然后再经 Q4回到电源负极。按图中电流箭头所示,该流向的电流将驱动电机顺时针转动。当三极管Q1和Q4导通时,电流将从左至右流过电机,从而驱动电机按特定方向转动(电机周围的箭头指示为顺时针方向)。

 

图4.14所示为另一对三极管Q2和Q3导通的情况,电流将从右至左流过电机。当三极管Q2和Q3导通时,电流将从右至左流过电机,从而驱动电机沿另一方向转动(电机周围的箭头表示为逆时针方向)。


二、使能控制和方向逻辑
驱动电机时,保证H桥上两个同侧的三极管不会同时导通非常重要。如果三极管Q1和Q2同时导通,那么电流就会从正极穿过两个三极管直接回到负极。此时,电路中除了三极管外没有其他任何负载,因此电路上的电流就可能达到最大值(该电流仅受电源性能限制),甚至烧坏三极管。基于上述原因,在实际驱动电路中通常要用硬件电路方便地控制三极管的开关。

===========================================================================================================================

一、死区设置位置: 
    决定死区时间设置的位是‘刹车和死区寄存器
    TIM1->BDTR’中的DTG[7:0],设置范围是0x00~0xff。




例子:这样当我需要3us的死区持续时间时,则可这么计算:

3us在第二个公式决定的死区范围之内。所以选择第二个公式。

3000/(13.89*2)=108,所以DTG[5:0]=108-64=44,所以DTG=127+44=171=0XabTIM1->BDTR|=0xab;

反过来验算//72Mhz,死区时间=13.89nsX108*2=3000us

经示波器验证,完全正确

-----------------------------------------------------------------------------------------------------------------------------------------------

在<stm32参考手册>全文搜索:Tdts,你可以大概知道Tdts的由来,另外,注意看定时器的框图,这个很重要.

确定好Tdts,根据提供的公式计算就是了。

================================================================================



================================================================================

学习后发现stm32的定时器功能确实很强大,小总结一下方便以后使用的时候做参考。Stm32定时器一共分为三种:tim1和tim8是高级定时器,6和7是基本定时器,2—5是通用定时器。从名字就可以看得出来主要功能上的差异。今天我主要是用定时器做pwm输出,所以总结也主要是针对pwm方面的。

       先大致说下通用和高级定时器的区别。通用的可以输出四路pwm信号互不影响。高级定时器可以输出三对互补pwm信号外加ch4通道,也就是一共七路。

所以这样算下来stm32一共可以生成4*5+7*2=30路pwm信号。接下来还有功能上的区别:通用定时器的pwm信号比较简单,就是普通的调节占空比调节频率(别的不常用到的没去深究);高级定时器的还带有互补输出功能,同时互补信号可以插入死区,也可以使能刹车功能,从这些看来高级定时器的pwm天生就是用来控制电机的。

Pwm输出最基本的调节就是频率和占空比。频率当然又和时钟信号扯上了关系。高级定时器是挂接到APB2上,而通用定时器是挂接到APB1上的。APB1和APB2的区别就要在于时钟频率不同。APB2最高频率允许72MH,而APB1最高频率为36MHZ。这样是不是通用定时器只最高36MHZ频率呢,不是的;通用定时器时钟信号完整的路线应该是下面这样的:

AHB(72mhz)→APB1分频器(默认2)→APB1时钟信号(36mhz)→倍频器(*2倍)→通用定时器时钟信号(72mhz)。

在APB1和定时器中间的倍频器起到了巨大的作用,假如红色字体的“APB1分频器”假如不为1(默认是2),倍频器会自动将APB1时钟频率扩大2倍后作为定时器信号源,这个它内部自动控制的不用配置。设置这个倍频器的目的很简单就是在APB1是36mhz的情况下通用定时器的频率同样能达到72mhz。我用的库函数直接调用函数SystemInit(); 这个函数之后时钟配置好了:通用定时器和高级定时器的时钟现在都是72mhz(你也可以自己再配置一下RCC让他的频率更低,但是不能再高了)。定时器接下来还有一个分频寄存器:TIMX_PSC经过他的分频后,才是定时器计数的频率。所以真正的时钟频率应该是72mhz/(TIMX_PSC-1),我们设为tim_frepuency下面还会用到。

stm32的时钟频率弄得确实是很饶人的,所以关键就是先要把思路理清楚。时钟的频率弄好了下面终于可以开说重点PWM了。当然还少不了频率:pwm主要就是控制频率和占空比的:这两个因素分别通过两个寄存器控制:TIMX_ARR和TIMX_CCRX。ARR寄存器就是自动重装寄存器,也就是计数器记到这个数以后清零再开始计,这样pwm的频率就是tim_frequency/(TIMX_ARR-1)。在计数时会不停的和CCRX寄存器中的数据进行比较,如果小于的话是高电平或者低电平,计数值大于CCRX值的话电平极性反相。所以这也就控制了占空比。

下面是定时器1的配置代码:

        GPIO_InitTypeDef GPIO_InitStructure2;

        TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

        TIM_OCInitTypeDef TIM_OCInitStructure;

        TIM_BDTRInitTypeDef TIM_BDTRInitStructure;

        //第一步:配置时钟       

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|

                                                   RCC_APB2Periph_GPIOB|RCC_APB2Periph_TIM1,ENABLE);

        //第二步,配置goio口

/********TIM1_CH1 引脚配置*********/       

        GPIO_InitStructure2.GPIO_Pin=GPIO_Pin_8;

        GPIO_InitStructure2.GPIO_Speed=GPIO_Speed_50MHz;

        GPIO_InitStructure2.GPIO_Mode=GPIO_Mode_AF_PP;                 //设置为复用浮空输出

        GPIO_Init(GPIOA,&GPIO_InitStructure2);

        /*********TIM1_CH1N 引脚配置********/

        GPIO_InitStructure2.GPIO_Pin=GPIO_Pin_13;

        GPIO_InitStructure2.GPIO_Speed=GPIO_Speed_50MHz;

        GPIO_InitStructure2.GPIO_Mode=GPIO_Mode_AF_PP;                 //设置为复用浮空输出

        GPIO_Init(GPIOB,&GPIO_InitStructure2);

        //第三步,定时器基本配置       

TIM_TimeBaseStructure.TIM_Period=1000-1;             // 自动重装载寄存器的值

        TIM_TimeBaseStructure.TIM_Prescaler=72-1;            // 时钟预分频数

        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;    // 采样分频

        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数

        TIM_TimeBaseStructure.TIM_RepetitionCounter=0;//重复寄存器,用于自动更新pwm占空比                        TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

       

//第四步pwm输出配置

        TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_PWM2;                    //设置为pwm1输出模式

        TIM_OCInitStructure.TIM_Pulse=500;                                            //设置占空比时间

        TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_Low;                 //设置输出极性

        TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;        //使能该通道输出

        //下面几个参数是高级定时器才会用到,通用定时器不用配置

        TIM_OCInitStructure.TIM_OCNPolarity=TIM_OCNPolarity_High;        //设置互补端输出极性

        TIM_OCInitStructure.TIM_OutputNState=TIM_OutputNState_Enable;//使能互补端输出

        TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Reset;        //死区后输出状态

        TIM_OCInitStructure.TIM_OCNIdleState=TIM_OCNIdleState_Reset;//死区后互补端输出状态

        TIM_OC1Init(TIM1,&TIM_OCInitStructure);                                            //按照指定参数初始化

        //第五步,死区和刹车功能配置,高级定时器才有的,通用定时器不用配置

        TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Disable;//运行模式下输出选择

        TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Disable;//空闲模式下输出选择

        TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;         //锁定设置

        TIM_BDTRInitStructure.TIM_DeadTime = 0x90;                                         //死区时间设置

        TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;                 //刹车功能使能

        TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;//刹车输入极性

        TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;//自动输出使能

        TIM_BDTRConfig(TIM1,&TIM_BDTRInitStructure);       

//第六步,使能端的打开

TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);  //使能TIMx在CCR1上的预装载寄存器

        TIM_ARRPreloadConfig(TIM1, ENABLE);                //使能TIMx在ARR上的预装载寄存器

        TIM_Cmd(TIM1,ENABLE);                                                           //打开TIM2

        //下面这句是高级定时器才有的,输出pwm必须打开

        TIM_CtrlPWMOutputs(TIM1, ENABLE);                                   //pwm输出使能,一定要记得打开

TIM_OC1PreloadConfig(),TIM_ARRPreloadConfig();这两个函数控制的是ccr1和arr的预装在使能,使能和失能的区别就是:使能的时候这两个局存期的读写需要等待有更新事件发生时才能被改变(比如计数溢出就是更新时间)。失能的时候可以直接进行读写而没有延迟。

另外在运行当中想要改变pwm的频率和占空比调用:TIM_SetAutoreload()

TIM_SetCompare1()这两个函数就可以了。

===================================================================================================================================

参考文章:

  https://blog.csdn.net/zwl1584671413/article/details/83305715

  https://blog.csdn.net/gtkknd/article/details/52840629

=======================================================  PWM的刹车输出  ===================================================================

当触发刹车事件时立即停止PWM的输出,即紧急刹车。其参考说明图如下:

原文地址:https://www.cnblogs.com/ownDefine/p/10795830.html