This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/TMS320F28379D:TMS320F28379D - ePWM 偶尔初始化(ePWM6完全不工作)

Guru**** 2039500 points
Other Parts Discussed in Thread: TMS320F28379D
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/721750/ccs-tms320f28379d-tms320f28379d---epwms-getting-initialized-sporadically-epwm6-not-working-at-all

器件型号:TMS320F28379D

工具/软件:Code Composer Studio

您好!

我正在 TMS320F28379D 控制卡(R1.3)上使用四个 ePWM 通道(1、2、5、6)和两个 ADC 通道(使用 ePWM4触发)来处理一个简单的代码。 我面临以下问题:

PWM 寄存器不会每次都被设置-每次我尝试调试代码时、我会得到不同数量的 EPWM 实际工作。 有时没有 ePWM 工作、有时只有 ePWM 1和2工作、而其他时间1、2和5工作。

2、不管我做什么、ePWM6寄存器没有正确设置、因此 ePWM 根本不起作用。 我在 F28335 DSP 方面拥有丰富的经验、但从未遇到过这样的问题。 我们非常感谢您提供任何帮助或提供可能的指导。

谢谢、

Akshay

下面随附了使用相同代码的不同情形中的一些图片、当我对其进行两次不同的调试时

    

(ePWM1在两个不同的调试会话、完全相同的代码)

给定调试会话中的 ePWM6 (每次的寄存器值不同)

请找到我使用过的代码:

// CPU1上开关的开环控制

#include "F28x_Project.h"
#include "math.h"

//函数
void ConfigureADC (void);
void SetupADCeppwm (void);
void ConfigureEPWM (void);
void InitEPwm1 (void);
void InitEPwm2 (void);
void InitEPwm5 (void);
void InitEPwm6 (void);
中断 void adca1_ISR (void);

//模块变量
#define PWM_Period 2000
#define PWM_HALFPERIOD 1000
UINT16 M1 = 0;
UINT16 M2 = 0;
UINT16标志= 0;
UINT16 delta = 500;UINT16





= 500;UINT16主周期= 1000;UINT16控制= 0;UINT16 void = 1 /空初始化系统

InitSysCtrl();
EALLOW;
ClkCfgRegs.PERCLKDIVSEL.bit.EPWMCLKDIV=1;/ePWM 时钟为100MHz
EDIS;

//初始化默认 GPIO
InitGpio();
//配置 ePWM GPIO 引脚
InitEPwm1Gpio();
InitEPwm2Gpio();
InitEPwm5Gpio();
InitEPwm6Gpio();

EALLOW;
GpioCtrlRegs.GPADIR.bit.GPIO18 = 1; //启用 gpio18作为输出
GpioDataRegs.GPACLEAR.bit.GPIO18=1; //强制拉低
EDIS;

//清除所有中断、初始化 PIE 控制寄存器和矢量表
Dint;
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();

//映射 ISR 函数
EALLOW;
PieVectTable.ADCA1_INT =&adca1_ISR;// ADCA1中断
EDIS;

//为每个模块启用 ePWM 时钟
EALLOW;
CpuSysRegs.PCLKCR2.bit.EPWM1=1;
CpuSysRegs.PCLKCR2.bit.EPWM2=1;
CpuSysRegs.PCLKCR2.bit.EPWM4=1;
CpuSysRegs.PCLKCR2.bit.EPWM5=1;
CpuSysRegs.PCLKCR2.bit.EPWM6=1;
EDIS;

//同步所有 ePWM
EALLOW;
CpuSysRegs.PCLKCR0.bit.GTBCLKSYNC=0;//全局同步
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=0;
EDIS;

//启动 ADC 和 ePWM
ConfigureADC();
ConfigureEPWM();
SetupADCepwm(); //EPWM4

InitEPwm1();
InitEPwm2();
InitEPwm5();
InitEPwm6 ();

//启用 PIE 中断
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // ADC ISR

//启用全局中断和更高优先级的实时调试事件:
IER |= M_INT1; //启用组1中断
EINT; //启用全局中断 INTM
ERTM; //启用全局实时中断 DBGM



//同步所有 ePWM
EALLOW;
CpuSysRegs.PCLKCR0.bit.GTBCLKSYNC= 1;//全局同步
CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1;

//启动 ADC ePWM
EPwm4Regs.ETSEL.bit.SOCAEN = 1; //启用 SOCA
EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; //取消冻结并进入向上计数模式
EDIS;

while (1)
{
;
}
}


void ConfigureADC (void)
{
EALLOW;
AdcaRegs.ADCCTL2.bit.prescale = 6; //将 ADCCLK 分频器设置为/4
AdcaRegs.ADCCTL2.bit.resolution = 0; // 12位分辨率
AdcaRegs.ADCCTL2.bit.SGNALMODE = 0; //单端通道转换(仅12位模式)
AdcaRegs.ADCCTL1.bit.INTPULSEPOS=1; //将脉冲位置设置为晚期
AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1; //为 ADC 加电
EDIS;

DELAY_US (1000); //延迟1ms 以允许 ADC 加电时间
Flag++;
}

void ConfigureEPWM (void)
{
EALLOW;
EPwm4Regs.TBCTL.bit.CTRMODE = TB_FREEZE; //冻结计数器
EPwm4Regs.TBCTL.bit.CLKDIV = 0;
EPwm4Regs.TBCTL.bit.HSPCLKDIV = 0; // TBCLK 预分频器=/1
EPwm4Regs.TBPRD = PWM_PERIOD; //将周期设置为2000个计数(50kHz)
EPwm4Regs.ETSEL.bit.SOCAEN = 0; //禁用组上的 SOC

EPwm4Regs.TBCTR = 0x0000; //清除计数器
EPwm4Regs.ETSEL.bit.SOCASEL = 2;
EPwm4Regs.ETPS.bit.SOCAPRD = 1; //在发生第一个事件时生成脉冲
EDIS;
Flag++;
}

void InitEPwm1 (void)
{
EALLOW;
//假设 ePWM 时钟已启用
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; //冻结计数器
EPwm1Regs.TBPRD = PWM_PERIOD;
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm1Regs.TBPHS.bit.TBPHS=0;
EPwm1Regs.TBCTR = 0x0000;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK 预分频器=/1
EPwm1Regs.TBCTL.bit.CLKDIV = 0;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;

//将影子寄存器加载设置为零
EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = 0;
EPwm1Regs.CMPCTL.bit.LOADAMODE = 0;
EPwm1Regs.CMPCTL.bit.LOADBMODE = 0;

//设置比较值
EPwm1Regs.CMPA.bit.CMPA = dutyCycle; //设置比较 A 值

//设置操作
EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; //在事件 B 上设置 PWM1A
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; //在事件 A 上清除 PWM5A,向上计数
EPwm1Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // PWM1B 与 PWM1A 相反
EPwm1Regs.AQCTLB.bit.CAU = AQ_SET;

//设置死区
EPwm1Regs.DBCTL.bit.OUT_MODE = 3; //启用红色和 FED
EPwm1Regs.DBCTL.bit.POLSEL = 2; // PWMB 反相
EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL; // PWMA 为上升沿和下降沿
EPwm1Regs.DBRED.bit.DBRED = 10; // 50ns (假设系统时钟为200MHz)
EPwm1Regs.DBFED.bit.DBFED = 10;

EDIS;
Flag++;
}

void InitEPwm2 (void)
{

EALLOW;
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; //向上计数
EPwm2Regs.TBPRD = PWM_PERIOD;
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE; //启用相位加载
EPwm2Regs.TBPHS.bit.TBPHS = PWM_HALFPERIOD; //相位
EPwm2Regs.TBCTR = 0x0000; //清除计数器
EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; // TBCLK 预分频器=/1
EPwm2Regs.TBCTL.bit.CLKDIV = 0;
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; CTR = 0时为//同步输出

//将影子寄存器加载设置为零
EPwm2Regs.CMPCTL.bit.SHDWAMODE = 0;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = 0;
EPwm2Regs.CMPCTL.bit.LOADAMODE = 0;
EPwm2Regs.CMPCTL.bit.LOADBMODE = 0;

//设置比较值
EPwm2Regs.CMPA.bit.CMPA =占空比; //设置比较 A 值

//设置操作
EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET; //将 PWM5A 设置为零
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR; //在事件 A 上清除 PWM5A,向上计数
EPwm2Regs.AQCTLB.bit.ZRO = AQ_CLEAR; // PWM5B 与 PWM5A 相反
EPwm2Regs.AQCTLB.bit.CAU = AQ_SET;

//设置死区
EPwm2Regs.DBCTL.bit.OUT_MODE = 3; //启用红色和 FED
EPwm2Regs.DBCTL.bit.POLSEL = 2; // PWMB 反相
EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL; // PWMA 为上升沿和下降沿
EPwm2Regs.DBRED.bit.DBRED = 10; // 50ns (假设系统时钟为200MHz)
EPwm2Regs.DBFED.bit.DBFED = 10;

EDIS;
Flag++;
}

void InitEPwm5 (void)
{
EALLOW;
EPwm5Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; //向上计数
EPwm5Regs.TBPRD = PWM_PERIOD;
EPwm5Regs.TBCTL.bit.PHSEN = TB_ENABLE; //启用相位加载
EPwm5Regs.TBPHS.bit.TBPHS =Δ; //相位
EPwm5Regs.TBCTR = 0x0000; //清除计数器
EPwm5Regs.TBCTL.bit.HSPCLKDIV = 0; //时钟与 SYSCLKOUT 的比率
EPwm5Regs.TBCTL.bit.CLKDIV = 0;
EPwm5Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; CTR = 0时为//同步输出

//将影子寄存器加载设置为零
EPwm5Regs.CMPCTL.bit.SHDWAMODE = 0;
EPwm5Regs.CMPCTL.bit.SHDWBMODE = 0;
EPwm5Regs.CMPCTL.bit.LOADAMODE = 0;
EPwm5Regs.CMPCTL.bit.LOADBMODE = 0;

//设置比较值
EPwm5Regs.CMPA.bit.CMPA =占空比; //设置比较 A 值
EPwm5Regs.CMPB.bit.CMPB = 0;

//设置操作
EPwm5Regs.AQCTLA.bit.CBU = AQ_SET; //将 PWM5A 设置为零
EPwm5Regs.AQCTLA.bit.CAU = AQ_CLEAR; //在事件 A 上清除 PWM5A,向上计数
EPwm5Regs.AQCTLB.bit.CBU = AQ_CLEAR; // PWM5B 与 PWM5A 相反
EPwm5Regs.AQCTLB.bit.CAU = AQ_SET;

//设置死区
EPwm5Regs.DBCTL.bit.OUT_MODE = 3; //启用红色和 FED
EPwm5Regs.DBCTL.bit.POLSEL = 2; // PWMB 反相
EPwm5Regs.DBCTL.bit.IN_MODE = DBA_ALL; // PWMA 为上升沿和下降沿
EPwm5Regs.DBRED.bit.DBRED = 10; // 50ns (假设系统时钟为200MHz)
EPwm5Regs.DBFED.bit.DBFED = 10;

EDIS;
Flag++;
}

void InitEPwm6 (void)
{

EALLOW;
EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; //向上计数
EPwm6Regs.TBPRD = PWM_PERIOD; //与 PWM5的周期相同
EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE; //启用相位加载
EPwm6Regs.TBPHS.bit.TBPHS = 0; //相位
EPwm6Regs.TBCTR = 0x0000; //清除计数器
EPwm6Regs.TBCTL.bit.HSPCLKDIV = 0; // TBCLK 预分频器=/1
EPwm6Regs.TBCTL.bit.CLKDIV = 0;
EPwm6Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; CTR = 0时为//同步输出

//将影子寄存器加载设置为零
EPwm6Regs.CMPCTL.bit.SHDWAMODE = 0;
EPwm6Regs.CMPCTL.bit.SHDWBMODE = 0;
EPwm6Regs.CMPCTL.bit.LOADAMODE = 0;
EPwm6Regs.CMPCTL.bit.LOADBMODE = 0;

//设置比较值
EPwm6Regs.CMPA.bit.CMPA = dutyCycle; //设置比较 A 值
EPwm6Regs.CMPB.bit.CMPB = 0;

//设置操作
EPwm6Regs.AQCTLA.bit.CBU = AQ_CLEAR; //将 PWM6A 设置为零
EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; //在事件 A 上清除 PWM6A,向上计数
EPwm6Regs.AQCTLB.bit.CBU = AQ_SET; // PWM6B 与 PWM6A 相反
EPwm6Regs.AQCTLB.bit.CAU = AQ_CLEAR;

//设置死区
EPwm6Regs.DBCTL.bit.OUT_MODE = 3; //启用红色和 FED
EPwm6Regs.DBCTL.bit.POLSEL = 2; // PWMB 反相
EPwm6Regs.DBCTL.bit.IN_MODE = DBA_ALL; // PWMA 为上升沿和下降沿
EPwm6Regs.DBRED.bit.DBRED = 10; // 50ns (假设系统时钟为200MHz)
EPwm6Regs.DBFED.bit.DBFED = 10;

EDIS;
Flag++;
}


void SetupADCepwm (void)
{
//选择要转换的通道和转换结束标志
EALLOW;
AdcaRegs.ADCSOC0CTL.bit.CHSEL = 0; // SOC0将转换引脚 A0
AdcaRegs.ADCSOC0CTL.bit.ACQPS = 14; //采样窗口为100个 SYSCLK 周期
AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 11; //在 ePWM4 SOCA/C 上触发

AdcaRegs.ADCSOC1CTL.bit.CHSEL = 1; //SOC1转换 A1
AdcaRegs.ADCSOC1CTL.bit.ACQPS = 14; //SYSCLK 周期
AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 11; // EPWM4上的触发


AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; // SOC0结束将设置 INT1标志
AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //启用 INT1标志
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //确保清除 INT1标志
EDIS;
Flag++;
}


中断 void adca1_ISR (void)
{
Flag++;
if (flag>30000) flag=0;
GpioDataRegs.GPATOGGLE.bit.GPIO18=1;

//读取 ADC 结果并存储在 M1中
M1 = AdcaResultRegs.ADCRESULT0;
M2 = AdcaResultRegs.ADCRESULT1;

//从中断返回
EALLOW;
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //清除 ADC INT1标志
PieCtrlRegs.PIEACX.ALL = PIEACK_Group1; //确认 PIE 组1以启用进一步的中断

AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;
GpioDataRegs.GPATOGGLE.bit.GPIO18=1;
EDIS;
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    你(们)好

    您用于此测试的硬件平台是什么? 您是否使用 TI 的 controlCARD 或 LaunchPad 硬件?
    您注意到的行为异常-请检查时钟配置。
    我建议您检查输入时钟、PLL 配置、系统和 PWM 时钟配置。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    感谢您的建议。 我使用的是 TMS320F28379D 控制卡(R1.3)、我使用 1日技术讲座 (修订版2.0)中的实验项目示例之一构建了代码

    #ifdef _LAUNCHXL_F28379D
    InitSysPll (XTAL_OSC、IMULT_40、FULT_0、PLLCLK_by_2);
    #else
    InitSysPll (XTAL_OSC、IMULT_20、FULT_0、PLLCLK_By_2);
    #endif //_LAUNCHXL_F28379D 

    C2000团队的某个人可能会确认我的假设是否正确、但我似乎忽略了代码是为 Launchpad 设计的这一事实(因此 _LAUNCHXL_F28379D 位于项目属性中的预定义符号列表中)。 因此、我的代码使用的是40的乘法器值。 这可能意味着我以规定的时钟频率的两倍推动 DSP、也意味着我的 ePWM (可以有人确认这一点吗?)

    但是、删除 _LAUNCHXL_F28379D 定义后、代码和 ePWM 初始化已100%正常运行。

    谢谢、

    Akshay