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.
波形的占空比跟ADC、ePWM中断是否启用没什么特别直接的关系啊。主要是看你CMPA、CMPB等等寄存器的设置。
你可以看一下芯片TRM第247页开始的一些例子,里面讲了占空比控制
void EPWM1_Init(Uint16 tbprd)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Disable TBCLK within the ePWM
SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1
EDIS;
// ePWM频率=TBCLK/(2*TBPRD)=150000000/(2*50000)
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
//PieVectTable.EPWM1_INT = &epwm1_timer_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks
EDIS;
InitEPwm1Gpio();
// Setup Sync
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through
// Allow each timer to be sync'ed
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;// 失能关闭(如使能为将相依移位值装载到计数器)
EPwm1Regs.TBPHS.half.TBPHS = 0;
EPwm1Regs.TBPRD = tbprd;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
EPwm1Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV=TB_DIV1;
// ePWM频率=TBCLK/(2*TBPRD)=150000000/(2*50000)
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event 在第一个事件中产生INT
EPwm1Regs.CMPA.half.CMPA =375;
EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR;//时基计数器的值等于0时输出低电平
EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;//向上计数时,时基计数器的值与cmpa寄存器的值相等不动作时输出高电平
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced 启动所有同步的定时器
EDIS;
// Enable CPU INT3 which is connected to EPWM1-6 INT: 启用与EPWM1-6 INT相连的CPU INT3。
IER |= M_INT3;
// Enable EPWM INTn in the PIE: Group 3 interrupt 1-6启用PIE中的EPWM INTn:第3组中断1-6
PieCtrlRegs.PIEIER3.bit.INTx1 = 1;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
}
void EPWM2_Init(Uint16 tbprd)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Disable TBCLK within the ePWM
SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2
EDIS;
EALLOW; // This is needed to write to EALLOW protected registers
// PieVectTable.EPWM2_INT = &epwm2_timer_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks
EDIS;
InitEPwm2Gpio();
// Setup Sync
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through
EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;// 失能关闭(如使能为将相依移位值装载到计数器)
EPwm2Regs.TBPHS.half.TBPHS = 0;
EPwm2Regs.TBPRD = tbprd;
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
EPwm2Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
EPwm2Regs.TBCTL.bit.CLKDIV=TB_DIV1;
EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT
EPwm2Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event 在第一个事件中产生INT
EPwm2Regs.CMPA.half.CMPA =0;
EPwm2Regs.CMPB = 0;
EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;//时基计数器的值等于0时输出高电平
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;//向上计数时,时基计数器的值与cmpa寄存器的值相等不动作时输出低电平
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced 启动所有同步的定时器
EDIS;
// Enable CPU INT3 which is connected to EPWM1-6 INT: 启用与EPWM1-6 INT相连的CPU INT3。
IER |= M_INT3;
// Enable EPWM INTn in the PIE: Group 3 interrupt 1-6启用PIE中的EPWM INTn:第3组中断1-6
PieCtrlRegs.PIEIER3.bit.INTx2 = 3;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
}
interrupt void epwm1_timer_isr(void)
{
Uint16 pwmval;
result1=(AdcRegs.ADCRESULT3)>>4;
t1=(float)result1*(3.3/4095); //转换成电压;
PID1.sum_error+=(incPIDcalcu(&PID1,t1));
pwmval=(Uint16)PID1.sum_error;
EPWM1A_set(pwmval);
/if(pwmval>=750) pwmval=750;
if(pwmval<=300) pwmval=300;
EPWM1A_set(pwmval);
EPwm1Regs.CMPA.half.CMPA =pwmval;
// Clear INT flag for this timer
EPwm1Regs.ETCLR.bit.INT = 1;
// Acknowledge this interrupt to receive more interrupts from group 3
PieCtrlRegs.PIEACK.bit.ACK3 = 1;
LED6_TOGGLE;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //清楚排序器中断位
asm (" ESTOP0");
for(;;);
}
/* interrupt void epwm2_timer_isr(void)
{
Uint16 pwmval;
result2=(AdcRegs.ADCRESULT2)>>4;
t2=(float)result2*(3.3/4095)*2.34; //转换成电流;
// if(pwmval<=640)
//电流环
PID2.sum_error+=(incPIDcalcu(&PID2,t2));
pwmval=(Uint16)PID2.sum_error;
//pwm限幅处理
if(pwmval>=6700) pwmval=6700; //720*32/36=640 最大输出32V
if(pwmval<=2000) pwmval=2000; //720*10/36=200 最小输出10v 最小输出10v
EPWM2A_set(pwmval);
LED7_TOGGLE;
// Clear INT flag for this timer
EPwm2Regs.ETCLR.bit.INT = 1;
// Acknowledge this interrupt to receive more interrupts from group 3
PieCtrlRegs.PIEACK.bit.ACK3 = 1;
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //清楚排序器中断位
}*/
void EPWM1A_set(Uint16 val)
{
EPwm1Regs.CMPA.half.CMPA = val;
}
void EPWM2A_set(Uint16 val)
{
EPwm2Regs.CMPA.half.CMPA = val;
}
void PID1init(void)
{
PID1.setpoint=0; //设定值
PID1.sum_error=0; //误差累计
PID1.proportion=0; //比例常熟
PID1.integral=0; //积分常数
PID1.differential =0; //微分常数
PID1.error_1=0; //e(t-1)
PID1.error_2=0; //e(t-2)
void PID2init(void)
{
PID2.setpoint=0; //设定值
PID2.sum_error=0; //误差累计
PID2.proportion=0; //比例常数
PID2.integral=0; //积分常数
PID2.differential =0; //微分常数
PID2.error_1=0; //e(t-1)
PID2.error_2=0; //e(t-2)
}
float incPIDcalcu(PIDtypedef *PIDx,float present_point)
{
float ierror,incpid;
ierror=PIDx->setpoint-present_point;
//公式一
// incpid=(PIDx->proportion+PIDx->integral+PIDx->differential) *ierror
// -(PIDx->proportion+2*PIDx->differential) *(PIDx->error_1)
// +(PIDx->differential)*(PIDx->error_2);
//公式二
incpid= (PIDx->proportion) *(ierror-(PIDx->error_1))
+(PIDx->integral) *ierror
+(PIDx->differential) *(ierror-2*(PIDx->error_1)+(PIDx->error_2));
return (incpid);
}
void PID_set(PIDtypedef *PIDx,float Pp,float Ii,float Dd)
{
PIDx->proportion=Pp;
PIDx->integral=Ii;
PIDx->differential=Dd;
}
抱歉代码有点多,另外建议上传的时候用回复框里面的“插入” - “代码”,语言选择“C”或者“C++”,否则看起来太累了。
我的理解,你是希望程序运行过程中实时得修改CMPx的值是吗?运行的时候有没有查看过对应寄存器的值有没有改变?
抱歉,前几天一直再改代码,我已经知道了怎么去修改这个的值了,但新的问题又来了,首先是我的ADC采样电压虽然可以采到值,但因为PID运算问题导致pwm波形不能完全修改,我尝试改变CMPx的值却没有效果,但通过改变TBPRD的值可以修改我的pwm波,但就在刚刚,我的板子又出了点问题,谢谢您的解答。