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.
工具/软件: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; }
您好!
感谢您的建议。 我使用的是 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