DSP28335实现相位相差90°的两路PWM波形的输出

DSP28335实现相位相差90°的两路PWM输出

本文介绍如何在TI的DSP28335上生成两路相位相差90°的PWM波形,适用于逆变器、电机控制等需要正交PWM的应用场景。

1. 硬件配置准备

1.1 所需资源

  • DSP28335主控芯片
  • ePWM模块(使用ePWM1和ePWM2)
  • GPIO引脚配置为PWM输出功能
  • 系统时钟配置(通常为150MHz)

1.2 引脚连接

  • ePWM1A -> GPIO0
  • ePWM1B -> GPIO1
  • ePWM2A -> GPIO2
  • ePWM2B -> GPIO3

2. 软件实现步骤

2.1 初始化系统时钟和外设

void InitSystem(void)
{
    // 初始化系统控制
    InitSysCtrl();
    
    // 关闭看门狗
    DisableDog();
    
    // 初始化PIE控制
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();
    
    // 配置ePWM时钟
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;  // 先停止所有ePWM时钟
    SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // 使能ePWM1时钟
    SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // 使能ePWM2时钟
    EDIS;
}

2.2 配置ePWM模块

void InitEPwm(void)
{
    // ePWM1配置 (主PWM)
    EPwm1Regs.TBCTL.bit.CTRMODE = 0;     // 增计数模式
    EPwm1Regs.TBPRD = 1500;              // 周期值 (假设100kHz PWM,150MHz/100kHz=1500)
    EPwm1Regs.TBPHS.bit.TBPHS = 0;       // 相位寄存器清零
    EPwm1Regs.TBCTL.bit.PHSEN = 0;       // 禁用相位加载
    EPwm1Regs.TBCTL.bit.SYNCOSEL = 0;    // 同步输出选择
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0;   // 高速时钟分频
    EPwm1Regs.TBCTL.bit.CLKDIV = 0;      // 时钟分频
    
    // 配置比较寄存器
    EPwm1Regs.CMPA.bit.CMPA = 750;       // 50%占空比
    EPwm1Regs.CMPB.bit.CMPB = 750;
    
    // 动作限定器配置
    EPwm1Regs.AQCTLA.bit.CAU = 2;        // CTR=CMPA时置高
    EPwm1Regs.AQCTLA.bit.CAD = 1;        // CTR=CMPA时置低
    EPwm1Regs.AQCTLB.bit.CBU = 2;        // CTR=CMPB时置高
    EPwm1Regs.AQCTLB.bit.CBD = 1;        // CTR=CMPB时置低
    
    // ePWM2配置 (相位偏移90°的从PWM)
    EPwm2Regs.TBCTL.bit.CTRMODE = 0;     // 增计数模式
    EPwm2Regs.TBPRD = 1500;              // 与ePWM1相同周期
    EPwm2Regs.TBPHS.bit.TBPHS = 375;     // 90°相位偏移 (1500/4=375)
    EPwm2Regs.TBCTL.bit.PHSEN = 1;       // 使能相位加载
    EPwm2Regs.TBCTL.bit.SYNCOSEL = 3;    // 同步时加载相位
    EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0;
    EPwm2Regs.TBCTL.bit.CLKDIV = 0;
    
    // 配置比较寄存器
    EPwm2Regs.CMPA.bit.CMPA = 750;       // 50%占空比
    EPwm2Regs.CMPB.bit.CMPB = 750;
    
    // 动作限定器配置
    EPwm2Regs.AQCTLA.bit.CAU = 2;
    EPwm2Regs.AQCTLA.bit.CAD = 1;
    EPwm2Regs.AQCTLB.bit.CBU = 2;
    EPwm2Regs.AQCTLB.bit.CBD = 1;
    
    // 配置同步信号
    EALLOW;
    EPwm1Regs.TBCTL.bit.SYNCOSEL = 1;    // ePWM1作为同步源
    EPwm2Regs.TBCTL.bit.SYNCOSEL = 2;    // ePWM2同步到ePWM1
    
    // 启用ePWM时钟同步
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
    EDIS;
}

参考代码 DSP28335实现相位相差90°的两路PWM波形的输出

2.3 GPIO引脚配置

void InitGpio(void)
{
    EALLOW;
    
    // 配置GPIO0-3为PWM输出
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;  // ePWM1A
    GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;  // ePWM1B
    GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1;  // ePWM2A
    GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1;  // ePWM2B
    
    // 配置GPIO上拉电阻
    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;   // 启用上拉
    GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO2 = 0;
    GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0;
    
    EDIS;
}

2.4 主程序实现

void main(void)
{
    // 系统初始化
    InitSystem();
    InitGpio();
    InitEPwm();
    
    // 启用全局中断
    EINT;
    ERTM;
    
    while(1)
    {
        // 主循环中可以动态调整PWM参数
        // 例如:
        // EPwm1Regs.CMPA.bit.CMPA = new_duty_cycle;
        // EPwm2Regs.CMPA.bit.CMPA = new_duty_cycle;
        
        // 可以添加其他应用代码
        asm(" NOP");
    }
}

3. 关键参数计算

3.1 PWM频率计算

PWM频率由时基周期寄存器(TBPRD)和系统时钟决定:

PWM频率 = 系统时钟频率 / (HSPCLKDIV × CLKDIV × TBPRD)

示例中:

  • 系统时钟 = 150MHz
  • HSPCLKDIV = 1 (不分频)
  • CLKDIV = 1 (不分频)
  • TBPRD = 1500
PWM频率 = 150MHz / (1×1×1500) = 100kHz

3.2 相位差计算

90°相位差对应的相位寄存器值:

相位寄存器值 = (期望相位差 / 360°) × TBPRD

对于90°相位差:

TBPHS = (90/360) × 1500 = 375

4. 调试技巧

  1. 示波器验证
    • 使用示波器同时观察ePWM1A和ePWM2A输出
    • 确认相位差是否为90°
    • 检查PWM频率和占空比是否符合预期
  2. 动态调整测试
// 在主循环中添加测试代码
EPwm1Regs.CMPA.bit.CMPA = 500;  // 改变占空比到33%
EPwm2Regs.CMPA.bit.CMPA = 500;
DELAY_US(1000000);  // 延时1秒
EPwm1Regs.CMPA.bit.CMPA = 1000; // 改变占空比到66%
EPwm2Regs.CMPA.bit.CMPA = 1000;
  1. 错误处理
// 检查寄存器配置是否正确
if(EPwm1Regs.TBCTL.bit.CTRMODE != 0)
{
    // 计数模式设置错误处理
}

5. 高级应用扩展

5.1 动态调整相位差

void SetPhaseShift(Uint16 epwm_num, float degree)
{
    float phase_reg;
    Uint16 tbpwd;
    
    // 获取当前周期值
    if(epwm_num == 1) tbpwd = EPwm1Regs.TBPRD;
    else tbpwd = EPwm2Regs.TBPRD;
    
    // 计算相位寄存器值
    phase_reg = (degree / 360.0) * (float)tbpwd;
    
    // 设置相位寄存器
    if(epwm_num == 1) EPwm1Regs.TBPHS.bit.TBPHS = (Uint16)phase_reg;
    else EPwm2Regs.TBPHS.bit.TBPHS = (Uint16)phase_reg;
}

5.2 使用HRPWM提高分辨率

对于需要更高PWM分辨率的应用:

// 配置HRPWM
EPwm1Regs.HRCNFG.all = 0x0;
EPwm1Regs.HRCNFG.bit.EDGMODE = 3;  // 双边沿调制
EPwm1Regs.HRCNFG.bit.CTLMODE = 0;  // 与普通PWM相同的控制
EPwm1Regs.HRCNFG.bit.HRLOAD = 1;   // 影子寄存器加载使能

// 设置HRPWM扩展比较值
EPwm1Regs.HRPWR.bit.PWRSYNC = 1;   // 启用HRPWM
EPwm1Regs.HRCNFG.bit.HRPE = 1;     // 启用高分辨率周期

5.3 死区时间配置

对于需要死区时间的应用:

// 配置死区时间
EPwm1Regs.DBCTL.bit.OUT_MODE = 0x3;  // 使能上升沿和下降沿死区
EPwm1Regs.DBCTL.bit.POLSEL = 0x2;    // EPWMxA高有效,EPWMxB低有效
EPwm1Regs.DBRED.bit.DBRED = 10;      // 上升沿死区时间
EPwm1Regs.DBFED.bit.DBFED = 10;      // 下降沿死区时间

6. 常见问题解决

  1. 无PWM输出
    • 检查GPIO复用配置是否正确
    • 验证PWM模块时钟是否使能
    • 检查TBCTL.CTRMODE是否设置为非停止模式(0-2)
  2. 相位差不准确
    • 确认TBPRD值计算正确
    • 检查TBPHS寄存器是否被正确设置
    • 验证SYNCOSEL和PHSEN配置
  3. PWM频率错误
    • 检查系统时钟配置
    • 确认HSPCLKDIV和CLKDIV分频设置
    • 重新计算TBPRD值

通过以上实现,DSP28335可以稳定输出两路相位相差90°的PWM波形,适用于各种需要正交PWM的控制应用。

posted @ 2025-06-25 10:37  chen_yig  阅读(495)  评论(0)    收藏  举报