文章目录
- 前言
- 基本概念
- 调制发波
- 载波同步问题
前言
最近作实验碰到了载波不同步的问题,以前也有碰到过这个问题,现在终于解决了,做个记录。
为了以示区分,实例指ePWMx,x=1,2,3,4,5,6,7,8;通道指ePWMxA/B,x=1,2,3,4,5,6,7,8
基本概念
开始接触AC-DC变换,就需要一些特殊的控制策略来进行调制了。一般是先在Simulink中搭建仿真,验证控制策略的可行性,再利用DSP复现控制策略。
在Simulink中,一般是根据调制法发出PWM波的。
即调制波和载波一同送入比较器,比较器的输出即PWM信号。
在Simulink中,载波由Repeating Sequence模块配置,多数情况下是一个正负半周对称的一个周期信号,且配置为中心对称的三角载波;而调制波一般是计算得到的,也大多情况下是一个有正有负的信号。
想想如果我们用C2000器件发出PWM波,哪些模块充当着载波和调制波的作用呢?
- TBCTR即载波
- CMPA即调制波
由于实际驱动电路放大的时延性,需要进行死区DeadBand配置,简易起见可以只用CMPA作为输入源,进行翻转,上升沿延时以及下降沿延时等操作就可以得到另一个互补通道xB的信号,所以说CMPA就可以充当调制波的作用了。
调制发波
但是有一个问题,DSP里面的TBCTR只能是非负整数呀,而且CMPA也是一个非负整数。而Simulink里的这些信号都有正有负的,该怎么对应起来呢?
我采用的办法是抬升调制波的办法。
因为在实现调制之前,各种采样,计算等等操作都是可以完全复现的,而DSP的载波相较于Simulink的载波只是变为非负了,相当于抬到了正半轴上,因此我们也可以把调制波给抬上去。
抬升后的结果就是调制波关于调制波的中心线对称。
具体的代码为
void PWM_Generate()
{
// Anti Park
float Ualpha = Sin * Uind + Cos * Uinq;
float Ubeta = -Cos * Uind + Sin * Uinq;
// Anti Clark
Ua = Ualpha;
Ub = -0.5 * Ualpha + 0.866025403784439 * Ubeta;
Uc = -0.5 * Ualpha - 0.866025403784439 * Ubeta;
// modulate wave
float temp1 = 1000 + Modulation * Ua;
float temp2 = 1000 + Modulation * Ub;
float temp3 = 1000 + Modulation * Uc;
// limit
if (temp1 > 1950)
temp1 = 1950;
if (temp1 < 50)
temp1 = 50;
if (temp2 > 1950)
temp2 = 1950;
if (temp2 < 50)
temp2 = 50;
if (temp3 > 1950)
temp3 = 1950;
if (temp3 < 50)
temp3 = 50;
EPwm1Regs.CMPA.bit.CMPA = (Uint16) temp1;
EPwm2Regs.CMPA.bit.CMPA = (Uint16) temp2;
EPwm3Regs.CMPA.bit.CMPA = (Uint16) temp3;
}
载波同步问题
在Simulink中都是共用的同一个载波,而DSP的每一个ePWM的载波都是各自独立的,就会存在不同PWM实例之间的TBCTR不相等的情况,这就是PWM实例之间载波不同步的现象。
至于如何检查不同PWM实例的载波是否同步,可以给每个PWM实例的CMPA一个固定值,然后看各个PWMxA的输出信号是否不存在明显的相移即可。
具体实施办法:
- 给想要使用的PWM实例使能相位加载PhaseShifLoad
- 填写相位加载值
- 关闭时钟
- 软件强制同步
- 打开时钟
EPwm1Regs.TBCTL.bit.PHSEN = 1;
EPwm1Regs.TBPHS.bit.TBPHS = 1;
EPwm2Regs.TBCTL.bit.PHSEN = 1;
EPwm2Regs.TBPHS.bit.TBPHS = 1;
EPwm3Regs.TBCTL.bit.PHSEN = 1;
EPwm3Regs.TBPHS.bit.TBPHS = 1;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; // disable TB clock
EPwm1Regs.TBCTL.bit.SWFSYNC = 1;
EPwm2Regs.TBCTL.bit.SWFSYNC = 1;
EPwm3Regs.TBCTL.bit.SWFSYNC = 1;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; // disable TB clock