我想用相位寄存器来实现PWM的相移,用的是以PWM3为基准,通过改PWM1和2的相位寄存器来实现。但是发现这样做PWM1和2的频率和占空比都发生了变化,如图所示。下面是我的代码,请问各位大佬是什么原因导致的?
#include "F28x_Project.h"
#define TBPRD_VALUE 999 // 50MHz / 50kHz = 1000
#define CMPA_VALUE 249 // 50% 占空比
#define CMPB_VALUE 749 // 50% 占空比
void InitEPwm1Example(void);
void InitEPwm2Example(void);
void InitEPwm3Example(void);
void main(void)
{
InitSysCtrl();
// Enable PWM module clocks
CpuSysRegs.PCLKCR2.bit.EPWM1 = 1;
CpuSysRegs.PCLKCR2.bit.EPWM2 = 1;
CpuSysRegs.PCLKCR2.bit.EPWM3 = 1;
// Initialize GPIO for PWM
InitEPwm1Gpio();
InitEPwm2Gpio();
InitEPwm3Gpio();
// Disable interrupts and initialize PIE
DINT;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
// 关键:必须先关闭同步,再配置所有PWM
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0;
EDIS;
// 初始化顺序很重要:先主桥,后从桥
InitEPwm3Example(); // 主桥,产生同步信号
InitEPwm1Example(); // 从桥1,120°相位
InitEPwm2Example(); // 从桥2,240°相位
// 所有配置完成后,同时启动所有PWM
EALLOW;
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
// 强制同步一次,确保所有PWM同时启动
EALLOW;
EPwm3Regs.TBCTL.bit.SWFSYNC = 1; // 软件强制同步
EDIS;
for(;;)
{
asm(" NOP");
}
}
//============================== EPWM1 ==============================
void InitEPwm1Example(void)
{
// 时基配置
EPwm1Regs.TBPRD = TBPRD_VALUE;
EPwm1Regs.TBCTR = 0x0000; // 清零计数器
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
EPwm1Regs.TBCTL.bit.PHSEN = TB_ENABLE; // 使能相位加载
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // 接收同步信号
EPwm1Regs.TBPHS.bit.TBPHS = 100; // 120°相位
// 比较值设置
EPwm1Regs.CMPA.bit.CMPA = CMPA_VALUE;
EPwm1Regs.CMPB.bit.CMPB = CMPB_VALUE;
// 比较控制
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 动作限定器 - 标准上下计数PWM
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; // 上计数匹配时置位
EPwm1Regs.AQCTLA.bit.CBU = AQ_CLEAR; // 下计数匹配时清零
}
//============================== EPWM2 ==============================
void InitEPwm2Example(void)
{
// 时基配置
EPwm2Regs.TBPRD = TBPRD_VALUE;
EPwm2Regs.TBCTR = 0x0000; // 清零计数器
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; // 使能相位加载
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // 接收同步信号
EPwm2Regs.TBPHS.bit.TBPHS = 200; // 240°相位
// 比较值设置
EPwm2Regs.CMPA.bit.CMPA = CMPA_VALUE;
EPwm2Regs.CMPB.bit.CMPB = CMPB_VALUE;
// 比较控制
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 动作限定器 - 标准上下计数PWM
EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // 上计数匹配时置位
EPwm2Regs.AQCTLA.bit.CBU = AQ_CLEAR; // 下计数匹配时清零
}
//============================== EPWM3(主桥) ==============================
void InitEPwm3Example(void)
{
// 时基配置 - 主模块
EPwm3Regs.TBPRD = TBPRD_VALUE;
EPwm3Regs.TBCTR = 0x0000; // 清零计数器
EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;
EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE; // 主桥禁止相位加载
EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm3Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO ; // 输出同步信号
EPwm3Regs.TBPHS.bit.TBPHS = 0; // 主桥无相位移
// 比较值设置
EPwm3Regs.CMPA.bit.CMPA = CMPA_VALUE;
EPwm3Regs.CMPB.bit.CMPB = CMPB_VALUE;
// 比较控制
EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// 动作限定器 - 标准上下计数PWM
EPwm3Regs.AQCTLA.bit.CAU = AQ_SET; // 上计数匹配时置位
EPwm3Regs.AQCTLA.bit.CBU = AQ_CLEAR; // 下计数匹配时清零
}
举报
更多回帖