【WB32库开发】第11章 PWM互补输出——死区时间计算

本章内容意在简单的补充第十章PWM互补输出实验中的高级定时器死区时间计算部分。

11.1 死区时间计算

11.1.1 死区时间计算方式详解

配置PWM互补输出的死区时间,本质上就是在配置TIM1高级控制定时器的刹车和死区寄存器(TIMx_BDTR)中的DTG[7:0](死区发生器设置)部分。

在WB32参考手册中找到该部分:
在这里插入图片描述

                     图11-1 刹车和死区寄存器(TIMx_BDTR)中的DTG[7:0](死区发生器设置)部分。

先介绍一下公式中的各个变量代表的含义:
1)DT:死区持续时间(DT=步长值×步长时间)。

2)T-DTS:系统时钟周期时长。
例:WB32F103CBT6的系统时钟频率为72M,则T-DTS = 1/72M = 13.89ns

3)Tdtg:步长时间,等于系统时钟周期时长乘以倍数,这个值用于计算最终死区时间。

4)DTG[7 : 5] = 0xx,DTG[7 : 5] = 10x,DTG[7 : 5] = 110,DTG[7 : 5] = 111。这四个部分分别对应四种死区时间计算方式。
可以简单理解为将DTG[7 : 0]这8位分为两部分,一部分决定步长值(二进制),另一部分决定与步长时间相乘的系数。

请大家仔细阅读死区时间计算表:

项目方式1方式 2方式 3方式4
步长位置DTG[7]DTG[7 : 6]DTG[7 : 5]DTG[7 : 5]
步长值(二进制)010110111
乘数位置DTG[6 : 0]DTG[5 : 0]DTG[4 : 0]DTG[4 : 0]
乘数最大值(十进制)12764+6332+3132+31
乘数范围(十进制)0-12764-12732-6332-63
步长时间倍数12816
Tdtg(步长时间)1*13.89ns2*13.89ns8*13.89ns16*13.89ns
系统时钟时钟周期为13.89ns时死区时间范围0-1764ns1778-3528ns3556-7000ns7112-14000ns

请注意:

DTG[7 : 5] = 0xx和DTG[7 : 5] = 10x中是含有x的,x部分并不参与决定步长值,但含x部分可和DTG剩余部分一起决定与步长值相乘的系数部分。

结合图11-1中公式,当DTG[7 : 5] = 10x时,其步长值(二进制)为10,步长时间Tdtg等于系统时钟周期时长的两倍,对应计算公式DT = (64 + DTG[5 : 0])×Tdtg,Tdtg = 2×T-DTS。
DTG[5 : 0]的取值范围为“00 0000(二进制)”到“11 1111(二进制)”,换算成十进制,则DTG[5 : 0]可取值范围为“0-63”。

即时钟频率72M,DTG[7 : 5] = 10x时:
最小死区时间DT=(64+0)Tdtg=64(2T-DTS)=64213.89=1778ns
最大死区时间DT=(64+63)Tdtg=127(2
T-DTS)=127213.89=3528ns

11.1.2 死区时间结构体成员参数值计算

上述过程讲解了死区时间的计算方法,但我们在代码编写时该如何传值呢?

例如现在需要2us(2000ns)的死区时间,依据上述表格应选方式3计算:2000 = (64+DTG[5 : 0]) Tdtg = (64+x) * 2 13.89 ns
解出DTG[5 : 0]为8,换算为二进制“0b1000”。

则DTG[7 : 0]=0b10001000=0x88

11.2 死区时间配置

11.2.1 配置2us死区时间

使用第十章讲解的固件库例程中的TIM_ComplementarySignals工程,仅需修改刹车和死区结构体配置部分,将例程中的刹车和死区结构体成员TIM_DeadTime由11修改为0x88:

  /* 断路和死区结构体配置*/
  TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;              //使能运行模式下的关闭状态
  TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;              //使能空闲模式下的关闭状态
  TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_1;                   //配置锁定级别为1
  TIM_BDTRInitStructure.TIM_DeadTime = 0x88;                               //定义死区持续时间为152ns。设置范围为 0x0 至 0xFF。
  TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;                      //使能断路输入功能。
  TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;        //配置断路输入通道 BRK 极性为高。
  TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;  //自动输出使能,可选使能或禁止

  TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);                            //初始化断路和死区结构体

配置好后,编译程序并烧录,将示波器探头通道1接在PA8上,探头通道2接在PB13上,即可观察到如下波形:

请添加图片描述
放大后:
请添加图片描述
请添加图片描述

可以观察到PA8输出的PWM波形的高电平和PB13输出的PWM波形的高电平永远差了2us的死区时间。

11.2.2 配置死区时间时“11”与“0x11”的不同

在第十章中我们设置死区时间时,将刹车和死区结构体成员TIM_DeadTime的值赋为11,这是一个十进制值。
根据死区时间计算表,由于传入的十进制值小于127,且方式1的计算方法比较简单,我们在上一章中的153ns就是由“11*13.89ns”直接计算得出的结果,在示波器中也验证了这个结果。

如果使用的是0x11(十六进制)来赋值刹车和死区结构体成员TIM_DeadTime,0x11=0b00010001=17,得到的死区时间为:17*13.89ns=236ns。在示波器中验证:
请添加图片描述
请添加图片描述

综上,我们验证了在给刹车和死区结构体成员TIM_DeadTime赋值时,使用十进制数和使用十六进制数是不同的。

11.3 小结

本章内容主要在第十章的基础上,教会大家如何计算死区时间,但在实际的项目设计中配置死区时间时还需要考虑更多。

我们还需注意,在实际项目中,往往是根据硬件的电气参数来确定死区时间的值,在确定死区时间的值之后,我们尽量选用11.1.2节中的方法来计算应赋值给刹车和死区结构体成员TIM_DeadTime的值,尽量采用十六进制方式传入,以保证结果准确性。

  • 39
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在STM32的高级定时器中,可以通过配置定时器的输出比较模式来实现PWM输出。而互补输出则是指使用两个定时器通道来实现互补输出,其中一个通道输出PWM波的高电平部分,另一个通道输出PWM波的低电平部分,从而实现互补输出的效果。同时,为了避免MOS管同时导通,可以设置死区时间来控制两个通道的输出时间间隔。 以下是一个简单的代码示例,实现了使用TIM1作为高级定时器,PA8和PA9作为互补输出通道,同时设置了死区时间为100个时钟周期: ```c #include "stm32f4xx.h" void TIM1_PWM_Init(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource8, GPIO_AF_TIM1); GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_TIM1); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); TIM_TimeBaseStructure.TIM_Period = 8399; TIM_TimeBaseStructure.TIM_Prescaler = 0; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = 4199; TIM_OC1Init(TIM1, &TIM_OCInitStructure); TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OCInitStructure.TIM_Pulse = 4199; TIM_OC2Init(TIM1, &TIM_OCInitStructure); TIM_BDTRInitTypeDef TIM_BDTRInitStructure; 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 = 100; TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_Low; TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure); TIM_Cmd(TIM1, ENABLE); } ``` 在该代码中,首先开启了TIM1和GPIOA的时钟,然后配置了PA8和PA9为复用输出模式,并将它们的复用引脚分别与TIM1的通道1和通道2相连。接着,配置了TIM1的计数器周期为8399,即定时器频率为84MHz/8400=10kHz。通道1和通道2都选择了PWM模式1,输出极性为高电平,占空比均为50%。最后,通过TIM_BDTRInitStructure结构体设置了死区时间为100个时钟周期,并启用了自动输出功能。 需要注意的是,该例程中使用的是STM32F407VG开发板,所以使用的是TIM1定时器。如果使用其他型号的开发板,需要根据具体情况修改代码中使用的定时器和GPIO引脚。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值