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/TMS320F28335:通过 ePWM 中断生成 SPWM

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/769025/ccs-tms320f28335-spwm-generation-through-epwm-interrupt

器件型号:TMS320F28335

工具/软件:Code Composer Studio

我正在尝试从 ePWM 中断生成 SPWM。 在每次 ePWM 中断时、我都会尝试将 θ 递增1.8度、并找到正弦值、然后将该值与 TBPRD 相乘以更新 CMPA 值。 再次超过'theta' 2*pi 后,我将尝试重置它。 但问题是 θ 仅增加51倍、此后它不会改变任何值、CMPA 值也不会更新。  

请在这方面帮助我。 请查找随附的代码。  

#include "DSP28x_Project.h" //器件头文件和示例包括文件
#include 

void InitEPwm1Example (void);
void GPIO_Setup1 (void);

float pi=2.0f*3.14159f;
_IQ 输入、sin_out;
long












void Q=global_Q;float a、b;float theta=0.0f;//float deltheta=0.31415926f;//float deltheta=(float)(1.8f*PI/180);float deltheta=0.031415f;uint16 v1[200];uint16 count=0;// void intran/
//(void int_isr)//////(intran_interrupt)//////////(void intrupt_main_tintranituan/(void)
//
//步骤1. 初始化系统控制:
// PLL、安全装置、启用外设时钟
//此示例函数位于 DSP2833x_SYSCTRL.c 文件中。
//
InitSysCtrl();

//
//步骤2. 初始化 GPIO:
//此示例函数位于 DSP2833x_GPIO.c 文件和中
//说明了如何将 GPIO 设置为其默认状态。
//
//InitGpio();//针对此示例跳过

//
//步骤3. 清除所有中断并初始化 PIE 矢量表:
//禁用 CPU 中断
//
Dint;

//
//将 PIE 控制寄存器初始化为默认状态。
//默认状态为禁用所有 PIE 中断和标志
//被清除。
//此函数位于 DSP2833x_PIECTRL.c 文件中。
//
InitPieCtrl();

//
//禁用 CPU 中断并清除所有 CPU 中断标志:
//
IER = 0x0000;
IFR = 0x0000;

//
//使用指向 shell 中断的指针初始化 PIE 矢量表
//服务例程(ISR)。
//这将填充整个表,即使是中断也是如此
//在本例中未使用。 这对于调试很有用。
//可以在 DSP2833x_DefaultIsr.c 中找到 shell ISR 例程
//此函数可在 DSP2833x_PieVect.c 中找到
//
InitPieVectTable();

//
//此示例中使用的中断被重新映射到
//此文件中的 ISR 函数。
//
EALLOW; //写入 EALLOW 受保护的寄存器需要此操作
PieVectTable.EPWM1_INT =&ePWM1A_COMPARE_ISR;
EDIS;//这是禁止写入 EALLOW 受保护寄存器所必需的

//
//步骤4. 初始化器件外设。 该函数可以是
// 可在 DSP2833x_CpuTimers.c 中找到
//
//InitCpuTimer();//对于本示例,仅初始化 CPU 计时器
/*#if (CPU_FRQ_150MHz)
//
//将 CPU 定时器0配置为每500毫秒中断一次:
// 150MHz CPU 频率,50毫秒周期(以 uSeconds 为单位)
//
ConfigCpuTimer (&CpuTimer0、150、50);
#endif
(CPU_FRQ_100MHz)
//
//将 CPU 定时器0配置为每500毫秒中断一次:
// 100MHz CPU 频率,50毫秒周期(以 uSeconds 为单位)
//
ConfigCpuTimer (&CpuTimer0、100、50000);
#endif*/
GPIO_Setup1 ();
InitEPwm1Examples();
//
//为了确保精确的时序,请使用只写指令来写入
//整个寄存器。 因此、如果任何配置位发生更改
//在 ConfigCpuTimer 和 InitCpuTimers (在 DSP2833x_CpuTimer.h 中)中、
//下面的设置也必须更新。
//

//
//使用只写指令将 TSS 位设置为0
//
//CpuTimer0Regs.TCR.ALL = 0x4000;

//
//步骤5. 特定于用户的代码、启用中断
//

//
//将 GPIO32配置为 GPIO 输出引脚


//
//启用连接到 CPU 定时器0的 CPU INT1:
//


//
//在 PIE 中启用 TINT0:组1中断7
//
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
IER |= 4;
//
//启用全局中断和更高优先级的实时调试事件
//
EINT; //启用全局中断 INTM
ERTM; //启用全局实时中断 DBGM

//
//步骤6. 空闲循环。 只需坐下来循环(可选):
//
for (;;);
}


void GPIO_Setup1 (void){
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;//启用 GPIO0上的上拉
GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;//启用 GPIO1上的上拉
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1;// GPIO0 = PWM1A
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1;// GPIO1 = PWM1B
GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 0;
GpioCtrlRegs.GPBDIR.bit.GPIO32 = 1;
EDIS;

}
void
InitEPwm1Examples()
{
//
//设置 TBCLK
//
//EPWM1 A 和 B 为 GPIO 0和1
EPwm1Regs.TBCTL.bit.CTRMODE = 2;//向上计数递减
EPwm1Regs.TBPRD = 3750; //设置计时器周期
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;//禁用相位加载
EPwm1Regs.TBPHS.Half.TBPHS = 0x0000; //相位为0
EPwm1Regs.TBCTR = 0x0000; //清除计数器
EPwm1Regs.TBCTL.bit.HSPCLKDIV = 001;//时钟与 SYSCLKOUT 之比
EPwm1Regs.TBCTL.bit.CLKDIV = 000;
EPwm1Regs.TBCTL.bit.SYNCOSEL=1;
EPwm1Regs.CMPA.half.CMPA =1875;//设置比较值
EPwm1Regs.CMPB = 1875; //设置比较 B 值
EPwm1Regs.DBCTL.bit.out_mode=3;
EPwm1Regs.DBCTL.bit.POLSEL=2;
EPwm1Regs.DBCTL.bit.in_mode=0;
EPwm1Regs.DBRED=10;
EPwm1Regs.DBFED=10;
//EPwm1Regs.PCCTL.bit.CHPEN=1;
//EPwm1Regs.PCCTL.bit.CHPFREQ=0x111;
//EPwm1Regs.PCCTL.bit.OSHTWTH=0x1111;
//EPwm1Regs.PCCTL.bit.CHPDUTY=0x011;
//
//设置操作
//
EPwm1Regs.AQCTLA.bit.CAU=2;//将 PWM1A 设置为零
EPwm1Regs.AQCTLA.bit.CAD=1;
EPwm1Regs.AQCTLB.bit.CBU=2;
EPwm1Regs.AQCTLB.bit.CBD = 1;
EPwm1Regs.ETSEL.bit.INTEN = 1;
EPwm1Regs.ETSEL.bit.INTSEL=4;
EPwm1Regs.ETPS.bit.INTPRD=1;
}
__interrupt void
ePWM1A_COMPARE_ISR (void)
{
//CpuTimer0.InterruptCount++;

//
//每500毫秒切换一次 GPIO32
//
input=_iQ24 (theta);
SIN_OUT =_IQ24sin (输入);
A=_IQ24toF (输入);
B=_IQ24toF (SIN_OUT);
V1[count]=(uint16)((b+1.0f)*0.5f*EPwm1Regs.TBPRD);
EPwm1Regs.CMPA.half.CMPA =v1[count];//设置比较值
EPwm1Regs.CMPB = v1[计数]; //设置比较 B 值
// v1[count]=b;*/
//EPwm1Regs.CMPA.half.CMPA=EPwm1Regs.TBPRD-_IQsat (_IQ28mpy (b、EPwm1Regs.TBPRD)、EPwm1Regs.TBPRD、0);
// v1[count]=b;
计数=计数+ 1;
Theta=theta+deltheta;
IF (theta->PI){
计数= 0;
Theta=0.0f;
}
GpioDataRegs.GPBTOGGLE.bit.GPIO32=1;
EPwm1Regs.ETCLR.bit.INT=1;
PieCtrlRegs.PIEACK.All=4;
//
//确认此中断以从组1接收更多中断
//
//PieCtrlRegs.PIEACK.ALL = PIEACK_Group1;
} 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    CMPA 的值是多少? 它与 TBPRD 相比如何? 它是否超出范围? 您是否仍然在51次计数后获得中断?

    惠特尼
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当 CMPA 值达到等于 TBPRD 的3750后、它的 SOP 将递增、不会生成任何中断。 我在 TBPRD 上编程的中断等于 CMPA。
    请在这方面帮助我。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当 TBPRD 等于 CMPA 时、你用来触发中断的"TBCTR = CMPA"条件不会发生。 当 TBCTR = TBPRD 时、计数方向被视为递减、因此不会得到中断。 当 TBPRD = CMPA 时、您需要找到另一种获得中断的方法。 或许暂时将 INTSEL 更改为其他值?

    惠特尼