在死区之前,还有移相角、比较子模块。我觉着这两个知识点简单的应用会很快掌握,复杂的是要与 PID、ADC采样配合起来。
参考文献:《轻松玩转DSP——基于TMS320F2833x》是2018年机械工业出版社出版的图书,作者:马骏杰
一、死区模块的构成
死区模块的内部结构图,主要就是六个开关、两个非门、两个延时组成,看懂了电路图,就基本上原理就懂了。
1.1 延时时间计算
上升沿、下降沿的延迟时间分别为
=DBRED*
=DBFED*
=1/TBCLK TBCLK=SYSCLKOUT/(HSPCLKDIV*CLKDIV)
EPwm1Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1 定时器时间分频系数 默认为0
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // HSPCLKDIV = 2 高速外设时间分频系数 默认1
假设两个分频系数如代码中默认
TBCLK=150M/(2^1*2^0)=150M/2=75M
如果延时时间,都是设置10us的话
=750/75M=10us
=750/75M=10us
1.2 输出模式选择
OUT_MODE主要看开关S0、S1,如果是1就延迟,0就无
1.3 输入模式选择
IN_MODE也是看开关S4、S5,搭在哪,哪个就是输入源
1.4 极性选择
这个着重讲一下,首先规定一下程序,还是以频率为1KHz、占空比为50%的方波信号为例
1、上升沿和下降沿均延时10us
2、ePWMA作为RED FED输入源
3、OUT_MODE设置均延迟
代码如下:
void EPWM_Init(void)
{
EPwm1Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1 定时器时间分频系数 默认为0
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // HSPCLKDIV = 2 高速外设时间分频系数 默认1
EPwm1Regs.TBCTL.bit.CTRMODE = 2; // 定义ePWM单元的工作模式:增减计数模
// 增计数时,ePWM1A 计数值等于CMPA置高电平。
// 减计数时,ePWM1A 计数值等于CMPA置低电平。
EPwm1Regs.AQCTLA.all = 0x0060;//具体位格式表见P134
EPwm1Regs.TBPRD = 37500; // 1KHz PWM
EPwm1Regs.CMPA.half.CMPA = 18750; // 50%占空比
EPwm1Regs.DBRED = 750; // 上升沿延时10 us
EPwm1Regs.DBFED = 750; // 下降沿延时10 us
EPwm1Regs.DBCTL.bit.OUT_MODE = 3; // ePWM1A = RED
EPwm1Regs.DBCTL.bit.POLSEL = 0; //
EPwm1Regs.DBCTL.bit.IN_MODE = 0; // ePWM1A 作为输入信号
}
1)POLSEL = 0, 00高电平有效(图中上为ePWMA 下为ePWMB)
开关S2=0 S3=0均未经过非门直接与上下沿延时相连,那么理论上ePWMA的高电平会延迟10us,低电平会多10us,而ePWMA则会相反。实验波形也确实如此。
2)POLSEL = 1, 01低电平有效(死区补偿)(图中上为ePWMA 下为ePWMB)
开关S2=1 S3=0,上升沿过后,经过非门,再输出ePWMA,那么理论上经过非门后原本的上升沿延迟会变成下降沿延迟。ePWMB则与1)中的不变。实验波形如下图所示:
3)POLSEL = 2,10高电平有效(死区补偿)(图中上为ePWMA 下为ePWMB)
这里不分析了,直接上图
4)POLSEL = 3,11 低电平有效(图中上为ePWMA 下为ePWMB)
1.5 完整代码
下面是搭好的工程环境,代码复制在里面就能跑
链接:https://pan.baidu.com/s/1-3l1qC0upZVbk2A-3SZkDQ?pwd=of4k
提取码:of4k
#include "DSP28x_Project.h"
#include "math.h"
#include "IQmathLib.h"
#define LED1 GpioDataRegs.GPADAT.bit.GPIO6
void GPIO_Init(void);
void EPWM_Init(void);
interrupt void Time0_ISR(void);
void main(void)
{
int counter=0; // 记录产生中断次数
/*系统初始化*/
InitSysCtrl();
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
//此处为烧录FLASH的代码,在调试好RAM前,不用管它
// MemCopy(&RamfuncsLoadStart,&RamfuncsLoadEnd,&RamfuncsRunStart);
// InitFlash();
EALLOW;
SysCtrlRegs.WDCR= 0x00AF; // 使能看门狗
EDIS;
GPIO_Init(); // GPIO初始化
EPWM_Init(); // ePWM1, ePWM2 and ePWM3初始化
EALLOW;
PieVectTable.TINT0 = &Time0_ISR;//将定时器0的函数入口提供给PIE中断向量表
EDIS;
InitCpuTimers(); // 初始化定时器
ConfigCpuTimer(&CpuTimer0,150,100000);// 定时时间为100ms
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;// 使能PIE定时器0中断
IER |=1;// 使能INT1中断
EINT; //使能总中断
ERTM;
CpuTimer0Regs.TCR.bit.TSS = 0; // 启动定时器0
while(1)
{
LED1 = 1; //点亮LED1;因为我的原理图的低电平,点亮
while(CpuTimer0.InterruptCount == 0);
LED1 = 0;
while(CpuTimer0.InterruptCount == 1);
CpuTimer0.InterruptCount = 0;
counter++;
}
}
void GPIO_Init(void)
{
EALLOW;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0 复用成 ePWM1A
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // GPIO1 复用成 ePWM1B
GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 0; // GPIO1复用为GPIO功能
GpioCtrlRegs.GPADIR.bit.GPIO6 = 1; // GPIO1设置为输出
GpioCtrlRegs.GPAPUD.bit.GPIO6 = 0; // GPIO1允许上拉
EDIS;
}
void EPWM_Init(void)
{
EPwm1Regs.TBCTL.bit.CLKDIV = 0; // CLKDIV = 1 定时器时间分频系数 默认为0
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 1; // HSPCLKDIV = 2 高速外设时间分频系数 默认1
EPwm1Regs.TBCTL.bit.CTRMODE = 2; // 定义ePWM单元的工作模式:增减计数模
// 增计数时,ePWM1A 计数值等于CMPA置高电平。
// 减计数时,ePWM1A 计数值等于CMPA置低电平。
EPwm1Regs.AQCTLA.all = 0x0060;//具体位格式表见P134
EPwm1Regs.TBPRD = 37500; // 1KHz PWM
EPwm1Regs.CMPA.half.CMPA = 18750; // 50%占空比
EPwm1Regs.DBRED = 750; // 上升沿延时10 us
EPwm1Regs.DBFED = 750; // 下降沿延时10 us
EPwm1Regs.DBCTL.bit.OUT_MODE = 3; // ePWM1A = RED
EPwm1Regs.DBCTL.bit.POLSEL = 3; // S3=1 ePWM1B反相信号
EPwm1Regs.DBCTL.bit.IN_MODE = 0; // ePWM1A 作为输入信号
}
interrupt void Time0_ISR(void)
{
CpuTimer0.InterruptCount++;
EALLOW;
SysCtrlRegs.WDKEY = 0x55;
SysCtrlRegs.WDKEY = 0xAA; // 喂狗
EDIS;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;//应答
}