280049芯片,相同的一段ISR()函数,代码开始和结束利用GPIO作为测试信号,链接示波器检测GPIO信号
工程1:利用EPWM1 ZERO中断触发10us的周期中断,执行ISR()函数,通过示波器测量执行之间约6us。
工程2:利用EPWM2 ZERO中断触发10us的周期中断,执行CLATASK1,内部调用ISR()函数,通过示波器测量执行时间10us不能完成。
测试1:验证工程2中断的正确性,在工程2的ISR()函数内减少代码量,通过示波器检测中断时间,确认10us的中断是正确的。但是执行时间还是不正常。
例如:ISR()内代码只留下两行读取AD寄存器的代码:示波器检测执行时间需要120ns
//########################################################################################
// Function Name: CLALoopCtrlISR
// Input:// Output:// Return:// Description://########################################################################################
#pragma FUNC_ALWAYS_INLINE(CLALoopCtrlISR)
inline void CLALoopCtrlISR()
{ TEST3_SET(); // GPIO测试
stClaToCpuPara.iVoutADFbk = AdccResultRegs.ADCRESULT0; stClaToCpuPara.iPriCurADFbk = AdcbResultRegs.ADCRESULT0;
TEST3_CLR(); // GPIO测试
// Clear INT Flag
EPwm1Regs.ETCLR.bit.INT = 1;
}
请问,我时不时哪里还没有配置正确,盼专家解答,谢谢!
Aiden:ISR()内完整代码如下:
#pragma FUNC_ALWAYS_INLINE(CLALoopCtrlISR)
inline void CLALoopCtrlISR()
{ TEST3_SET();
stClaToCpuPara.iVoutADFbk = AdccResultRegs.ADCRESULT0; stClaToCpuPara.iPriCurADFbk = AdcbResultRegs.ADCRESULT0; stClaToCpuPara.iVoutADFbk = ((stClaToCpuPara.iVoutADFbk * AD_CAL_K / stSysFbkParaADFilter.stV2V5AD.lSample) & 0x0FFF);stClaToCpuPara.iPriCurADFbk = ((stClaToCpuPara.iPriCurADFbk * AD_CAL_K / stSysFbkParaADFilter.stV2V5AD.lSample) & 0x0FFF); if((stCpuToClaPara.bPIWorkEn == 1)&& (unFaultCode.uiWord == 0)){if(stCpuToClaPara.bSoftStartFlag == STATE_STARTING_OPENLOOP){stClaToCpuPara.iVoltLoopErr = stCpuToClaPara.iVoutSetPiont – stClaToCpuPara.iVoutADFbk;
if((stClaToCpuPara.iVoltLoopErr >= PI_CHANGE_VOUTERR_VALUE)&& (stClaToCpuPara.iVoltLoopErr >= stClaToCpuPara.iVoltLoopErrOld)){stClaToCpuPara.iVoltLoopKp = stCpuToClaPara.iVoltLoopKpDn;stClaToCpuPara.iVoltLoopKi = stCpuToClaPara.iVoltLoopKiDn;}else if((stClaToCpuPara.iVoltLoopErr <= -PI_CHANGE_VOUTERR_VALUE)&& (stClaToCpuPara.iVoltLoopErr <= stClaToCpuPara.iVoltLoopErrOld)){ stClaToCpuPara.iVoltLoopKp = stCpuToClaPara.iVoltLoopKpUp;stClaToCpuPara.iVoltLoopKi = stCpuToClaPara.iVoltLoopKiUp;}else{stClaToCpuPara.iVoltLoopKp = stCpuToClaPara.iVoltLoopKpNormal;stClaToCpuPara.iVoltLoopKi = stCpuToClaPara.iVoltLoopKiNormal;}if((stClaToCpuPara.iVoltLoopErr > 5) || (stClaToCpuPara.iVoltLoopErr < -5)){stClaToCpuPara.lVoltLoopPIOut += (int32)stClaToCpuPara.iVoltLoopKp * (stClaToCpuPara.iVoltLoopErr- stClaToCpuPara.iVoltLoopErrOld)+ (int32)stClaToCpuPara.iVoltLoopKi * stClaToCpuPara.iVoltLoopErr; } if(stClaToCpuPara.lVoltLoopPIOut > PI_OUT_MAX){stClaToCpuPara.lVoltLoopPIOut = PI_OUT_MAX;}else if(stClaToCpuPara.lVoltLoopPIOut < PI_OUT_MIN){stClaToCpuPara.lVoltLoopPIOut = PI_OUT_MIN;}
stClaToCpuPara.iVoltLoopErrOld = stClaToCpuPara.iVoltLoopErr;stClaToCpuPara.lActivePIOut = stClaToCpuPara.lVoltLoopPIOut;
//stClaToCpuPara.lCurrentLoopPIOut = stClaToCpuPara.lVoltLoopPIOut;}else{stClaToCpuPara.iVoltLoopErr = stCpuToClaPara.iVoutSetPiont – stClaToCpuPara.iVoutADFbk;stClaToCpuPara.iCurrentLoopErr = stCpuToClaPara.iCurrentSetPiont – stClaToCpuPara.iPriCurADFbk;
// VoltLoop PIif((stClaToCpuPara.iVoltLoopErr >= PI_CHANGE_VOUTERR_VALUE)&& (stClaToCpuPara.iVoltLoopErr >= stClaToCpuPara.iVoltLoopErrOld)){stClaToCpuPara.iVoltLoopKp = stCpuToClaPara.iVoltLoopKpDn;stClaToCpuPara.iVoltLoopKi = stCpuToClaPara.iVoltLoopKiDn;}else if((stClaToCpuPara.iVoltLoopErr <= -PI_CHANGE_VOUTERR_VALUE)&& (stClaToCpuPara.iVoltLoopErr <= stClaToCpuPara.iVoltLoopErrOld)){ stClaToCpuPara.iVoltLoopKp = stCpuToClaPara.iVoltLoopKpUp;stClaToCpuPara.iVoltLoopKi = stCpuToClaPara.iVoltLoopKiUp;}else{stClaToCpuPara.iVoltLoopKp = stCpuToClaPara.iVoltLoopKpNormal;stClaToCpuPara.iVoltLoopKi = stCpuToClaPara.iVoltLoopKiNormal;}
// CurrentLoop PIif((stClaToCpuPara.iCurrentLoopErr <= -PI_CHANGE_VOUTERR_VALUE)&& (stClaToCpuPara.iCurrentLoopErr <= stClaToCpuPara.iCurrentLoopErrOld)){ stClaToCpuPara.iCurrentLoopKp = stCpuToClaPara.iCurrentLoopKpUp;stClaToCpuPara.iCurrentLoopKi = stCpuToClaPara.iCurrentLoopKiUp;}else{stClaToCpuPara.iCurrentLoopKp = stCpuToClaPara.iCurrentLoopKpNormal;stClaToCpuPara.iCurrentLoopKi = stCpuToClaPara.iCurrentLoopKiNormal;}if((stClaToCpuPara.iVoltLoopErr > 5) || (stClaToCpuPara.iVoltLoopErr < -5)){stClaToCpuPara.lVoltLoopPIOut += (int32)stClaToCpuPara.iVoltLoopKp * (stClaToCpuPara.iVoltLoopErr-stClaToCpuPara.iVoltLoopErrOld)+ (int32)stClaToCpuPara.iVoltLoopKi * stClaToCpuPara.iVoltLoopErr; } if(stClaToCpuPara.lVoltLoopPIOut > PI_OUT_MAX){stClaToCpuPara.lVoltLoopPIOut = PI_OUT_MAX;}else if(stClaToCpuPara.lVoltLoopPIOut < PI_OUT_MIN){stClaToCpuPara.lVoltLoopPIOut = PI_OUT_MIN;}
stClaToCpuPara.lCurrentLoopPIOut += (int32)stClaToCpuPara.iCurrentLoopKp * (stClaToCpuPara.iCurrentLoopErr- stClaToCpuPara.iCurrentLoopErrOld)+ (int32)stClaToCpuPara.iCurrentLoopKi * stClaToCpuPara.iCurrentLoopErr;
if(stClaToCpuPara.lCurrentLoopPIOut > PI_OUT_MAX){stClaToCpuPara.lCurrentLoopPIOut = PI_OUT_MAX;}else if(stClaToCpuPara.lCurrentLoopPIOut < PI_OUT_MIN){stClaToCpuPara.lCurrentLoopPIOut = PI_OUT_MIN;}// Currentloop to Voltage loopif((stClaToCpuPara.lVoltLoopPIOutOld == PI_OUT_MAX) && (stClaToCpuPara.lVoltLoopPIOut < PI_OUT_MAX)){if(stClaToCpuPara.lCurrentLoopPIOutOld < stClaToCpuPara.lVoltLoopPIOut){stClaToCpuPara.lVoltLoopPIOut = stClaToCpuPara.lCurrentLoopPIOutOld;}}// Voltageloop to Currentloopelse if((stClaToCpuPara.lCurrentLoopPIOutOld == PI_OUT_MAX) && (stClaToCpuPara.lCurrentLoopPIOut < PI_OUT_MAX)){if(stClaToCpuPara.lVoltLoopPIOutOld < stClaToCpuPara.lCurrentLoopPIOut){stClaToCpuPara.lCurrentLoopPIOut = stClaToCpuPara.lVoltLoopPIOutOld;}}stClaToCpuPara.lVoltLoopPIOutOld = stClaToCpuPara.lVoltLoopPIOut;stClaToCpuPara.lCurrentLoopPIOutOld = stClaToCpuPara.lCurrentLoopPIOut;stClaToCpuPara.iCurrentLoopErrOld = stClaToCpuPara.iCurrentLoopErr;stClaToCpuPara.iVoltLoopErrOld = stClaToCpuPara.iVoltLoopErr;
if(stClaToCpuPara.lVoltLoopPIOut > stClaToCpuPara.lCurrentLoopPIOut){stClaToCpuPara.lActivePIOut = stClaToCpuPara.lCurrentLoopPIOut;}else{stClaToCpuPara.lActivePIOut = stClaToCpuPara.lVoltLoopPIOut;}}}
if(stCpuToClaPara.bSoftStartFlag == STATE_FINISH){CLASRSwitchCtrl();}
#if (OPENLOOP == 0)CLABurstModeCtrl();#endif
#if (OPENLOOP == 1)stClaToCpuPara.iPWMDutyCnt = stCpuToClaPara.iPWMDutyCntOpenLoop; #elsestClaToCpuPara.iPWMDutyCnt = stClaToCpuPara.lActivePIOut >> PI_OUT_Q;#endif
EPwm1Regs.CMPA.bit.CMPA = stClaToCpuPara.iPWMDutyCnt;EPwm1Regs.CMPB.bit.CMPB = PWM_DUTY_FULL – stClaToCpuPara.iPWMDutyCnt;
EPwm2Regs.CMPA.bit.CMPA = stClaToCpuPara.iPWMDutyCnt;EPwm2Regs.CMPB.bit.CMPB = PWM_DUTY_FULL – stClaToCpuPara.iPWMDutyCnt;EPwm7Regs.CMPA.bit.CMPA = stClaToCpuPara.iPWMDutyCnt + DOUBLE_PHASE_PWM7;EPwm7Regs.CMPB.bit.CMPB = PWM_DUTY_FULL – stClaToCpuPara.iPWMDutyCnt – DOUBLE_PHASE_PWM7;
stClaToCpuPara.iSOCTrigPoint = (stClaToCpuPara.iPWMDutyCnt >> 1) + SOC_TRIG_HW_DELAY;EPwm2Regs.CMPC = stClaToCpuPara.iSOCTrigPoint;
TEST3_CLR();// Clear INT FlagEPwm1Regs.ETCLR.bit.INT = 1;
}
如需要其他信息便于定位问题,请告知。由于公司加密软件原因工程无法直接上传,请谅解。谢谢!
280049芯片,相同的一段ISR()函数,代码开始和结束利用GPIO作为测试信号,链接示波器检测GPIO信号
工程1:利用EPWM1 ZERO中断触发10us的周期中断,执行ISR()函数,通过示波器测量执行之间约6us。
工程2:利用EPWM2 ZERO中断触发10us的周期中断,执行CLATASK1,内部调用ISR()函数,通过示波器测量执行时间10us不能完成。
测试1:验证工程2中断的正确性,在工程2的ISR()函数内减少代码量,通过示波器检测中断时间,确认10us的中断是正确的。但是执行时间还是不正常。
例如:ISR()内代码只留下两行读取AD寄存器的代码:示波器检测执行时间需要120ns
//########################################################################################
// Function Name: CLALoopCtrlISR
// Input:// Output:// Return:// Description://########################################################################################
#pragma FUNC_ALWAYS_INLINE(CLALoopCtrlISR)
inline void CLALoopCtrlISR()
{ TEST3_SET(); // GPIO测试
stClaToCpuPara.iVoutADFbk = AdccResultRegs.ADCRESULT0; stClaToCpuPara.iPriCurADFbk = AdcbResultRegs.ADCRESULT0;
TEST3_CLR(); // GPIO测试
// Clear INT Flag
EPwm1Regs.ETCLR.bit.INT = 1;
}
请问,我时不时哪里还没有配置正确,盼专家解答,谢谢!
Annie Liu:
回复 Aiden:
为更加有效地解决您的问题,我们建议您将问题发布在E2E英文技术论坛上https://e2e.ti.com/support/microcontrollers/c2000/f/171,将由资深的工程师为您提供帮助。我们的E2E英文社区有TI专家进行回复,并得到全球各地工程师的支持,分享他们的知识和经验。