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.
您好专家、
我的客户正在使用 ePWM 载波以连续模式触发 ADC ISR、而 ADC ISR 在2.5us 间隔内触发。
当它们在 ISR 中添加代码时、我们可以发现 ISR 将在 ISR 执行时间接近2.3us 时丢失(彼此跳过)。
在我们的侦察中、我们仍有0.2 us 的时间用于进入和退出 ISR、但为什么我们在这个负载下开始错过 ISR?
我们用 GPIO 切换、将 ISR - GPIO 输入为高电平、将 ISR GPIO 输出为低电平来标记 CPU 执行。 在本例中、我们可以了解运行 ISR 需要多长时间以及是否缺少 ISR。 (在正常情况下、高 ISR/CPU 负载、我们应该会看到 GPIO 上的低电压较窄)
您能帮我们进一步了解它是否正常? 为什么?
谢谢
谢尔登
您好、Sheldon、
根据您所说的内容、似乎由于以下原因之一而跳过 ISR:
1. PIEIFR 被软件清零。 如果在软件中清除 PIEIFR、则可能会丢失中断、这就是为什么永远不应在软件中清除中断的原因。 相反、您应该让 CPU 获取中断以使其清除。 请检查您的代码中正在修改 PIEIFR 的所有实例、并确保没有地方可以通过软件手动清除 PIEIFR。
2.意外的嵌套中断。 默认情况下、不能嵌套中断。 如果在 ISR 中更改了全局优先级或组优先级、则可能会无意中嵌套中断。 有关我通过嵌套中断描述的内容的更多信息、请在 C2000Ware 中查看中断嵌套文档: \docs\C28x_interrupt_besting\html\index.html。
3.如果您每次在 CCS 中单步执行一行代码、可能会发生一些奇怪的行为。 如果使用调试器、请删除所有断点并让程序自由运行、然后查看这是否也解决了问题。
这些是我可以认为可能导致完全错过中断的主要原因、因此请在您检查这些内容后告知我、这是否可以解决您的问题! 唯一真正的另一种可能是触发器本身不会发生、但只要您正确配置了 ADC/ePWM ISR 及其设置、就可能不会发生此问题。
此致、
Vince
尊敬的 Vince:
对于第2点和第3点、我们的代码中没有以下设置。
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; PieCtrlRegs.PIEACk.bit.ACK1=1;
我们的事情做得正确吗?
谢谢
谢尔登
您好、Sheldon、
如果该代码位于 ISR 末尾、则看起来正确。
我还想说的是、假设 ISR 只剩下0.2us 的时间、并且您使用的是20MHz 时钟频率、那么对于 ISR 所需的时间、有一件事可以发挥作用:
从技术上讲、仅中断内部部分的中断延迟最多可以达到32个周期(考虑到最小14个周期+ 8个定点推入+ 10个浮点推入)。 在20MHz 频率下、这将是~1.6us。 这意味着在这段时间内一个较高优先级的中断有可能挤占。 如果考虑 RPT 指令、多周期指令、等待内存中的代码执行等项目、从技术上讲、周期数可能会更高
要检查是否存在这种情况、是否确定中断不是在另一个中断之后发生? 这意味着您是否看到 ISR 刚刚发生得晚? 还是真的完全被跳过了?
我还不知道会像您描述的那样导致中断丢失、那么您能提供更多详细信息吗?
此致、
Vince
尊敬的 Vince:
感谢您在此处提供非常详细的解释!
我们已经看到 ISR 完全跳过、而不是只是晚了。
我们在这里不使用嵌套 ISR、代码中只有一个 ISR、配置如下所示:
EALLOW; PieVectTable.ADCA1_INT =&adca_ISR; EDIS; EALLOW; PieCtrlRegs.PIECTRL.bit.ENPIE = 1;//启用 PIE 块 PieCtrlRegs.PIEIER1.bit.INTx1 = 1;//启用 ADCA1中断 //PieCtrlRegs.PIEIER1.bit.INTx3=1;//启用 ADCC1中断 EDIS; IER |= M_INT1; EINT; ERTM;
关于 ACK1的上下文、请参阅下面的 ISR:
// ADC 中断服务例程、由 ADC EOC #pragma CODE_SECTION (adca_ISR、".TI.ramfunc") _interrupt void adca_ISR (void) { GpioDataRegs.GPASET.BIT.GPIO7 = 1; // AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; // PieCtrlRegs.PIEACK.bit.ACK1 = 1; // ADC 输入范围= 0到4096 //使用偏移减法,范围将为-2048到+2047 InputADC =(Int16_t)(AdcResultRegs.ADCRESULT0 - ADC_OFFSET); // offset // temp_val[0]=(uint16)(single_Turn >> 16); // temp_val[1]=(uint16) single_Turn; //强制 CLA 任务 // Cla1ForceTask1 (); #ifdef 欠采样 switch (demo_i){ 情况0: DualFilter.InFilter1 = 0; DualFilter.InFilter2 = InputADC; DEMO_I = 1; 中断; 案例1: DualFilter.InFilter1 = InputADC; DualFilter.InFilter2 = 0; DEMO_I = 2; 中断; 案例2: DualFilter.InFilter1 = 0; DualFilter.InFilter2 =-InputADC; DEMO_I = 3; 中断; 案例3: DualFilter.InFilter1 =-InputADC; DualFilter.InFilter2 = 0; DEMO_I = 0; 中断; } 其他 DualFilter.InFilter1 =(Int16_t)((InputADC * sinVal[demo_i])>> 19); DualFilter.InFilter2 =(Int16_t)((InputADC * cosVal[demo_i])>> 19); DEMO_I++; DEMO_I =(DEMO_I <= 7)? DEMO_I:0; #endif DualFIRCAL_V1 (DualFilter); #ifndef Algorithm2// OutFilter1_CPU_TO_CLA = DualFilter.OutFilter1; // OutFilter2_CPU_TO_CLA = DualFilter.OutFilter2; Theta =__atan2puf32 (((float) DualFilter.OutFilter1、(float) DualFilter.OutFilter2); 单个=(单个和0x1E0000)+θ* 131071 + 5535; if (pre_theta > 98304 && tmp_theta < 32767) 单通道=单通道+ 131072; 否则{ if (tmp_theta > 98304 && pre_theta < 32767) 单个=单个- 131072; } pre_theta = tmp_theta; #else switch (demo_i2){ 情况0: DualFilter2.InFilter1 = 0; DualFilter2.InFilter2 = 0; DEMO_i2 = 1; 中断; 案例1: DualFilter2.InFilter1 = DualFilter.OutFilter1; DualFilter2.InFilter2 = DualFilter.OutFilter2; DEMO_i2 = 2; 中断; 案例2: DualFilter2.InFilter1 = 0; DualFilter2.InFilter2 = 0; DEMO_i2 = 3; 中断; 案例3: DualFilter2.InFilter1 =-DualFilter.OutFilter1; DualFilter2.InFilter2 =-DualFilter.OutFilter2; DEMO_i2 = 0; 中断; } DualFIRCALC_V1 (DualFilter2); OutFilter1_CPU_TO_CLA =(浮点) DualFilter2.OutFilter1; OutFilter2_CPU_TO_CLA =(浮点) DualFilter2.OutFilter2; #endif temp_val[0]=(UINT16)(单路>> 16); temp_val[1]=(uint16)单通道; //重新初始化中断 AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; PieCtrlRegs.PIEACk.bit.ACK1=1; GpioDataRegs.GPACLEAR.bit.GPIO7=1; }
要继续...
是的、我每2.5us 触发一次具有 ePWM 的 ADC SOC。
ePWM 设置为:
// EPWM1 A/B 和 EPWM2 A/B 执行 SVPWM 输出 // EPWM3 SOCA 触发 ADC S + H void ConfigureEPWM (void) { // PWM 时钟设置为100MHz,愚蠢的复位值 EPwm1Regs.TBCTL.bit.CLKDIV = 0; EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0; EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADODE;//必须使用影子模式 EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm2Regs.TBCTL.bit.CLKDIV = 0; EPwm2Regs.TBCTL.bit.HSPCLKDIV = 0; EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADODE;//必须使用影子模式 EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADODE;//必须使用影子模式 EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; EPwm3Regs.TBCTL.bit.CLKDIV = 0; EPwm3Regs.TBCTL.bit.HSPCLKDIV = 0; EPwm4Regs.TBCTL.bit.CLKDIV = 7; //设置/128 EPwm4Regs.TBCTL.bit.HSPCLKDIV = 5; //设置/10 EPwm4Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; //必须使用阴影模式 EPwm4Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; //停止 ePWM 时钟 EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC=0; EDIS; EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; //反向向上向下计数模式 EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO; //主设备:CTR = 0时输出 SYNC 信号 EPwm1Regs.TBPRD = PERIOD_50K_UD; //载波周期 EPwm1Regs.CMPA.bit.CMPA = PERIOD_50K_UD / 2; EPwm1Regs.CMPB.bit.CMPB = PERIOD_50K_UD / 2; EPwm1Regs.AQCTLA.bit.CAU = AQ_SET; EPwm1Regs.AQCTLA.bit.CBD = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CAU = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.CBD = AQ_SET; EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;//计数器向上向下计数模式 EPwm2Regs.TBPRD = PERIOD_50K_UD; //载波周期 EPwm2Regs.CMPA.bit.CMPA = PERIOD_50K_UD / 2; EPwm2Regs.CMPB.bit.CMPB = PERIOD_50K_UD / 2; EPwm2Regs.AQCTLA.bit.ZRO = AQ_CLEAR; EPwm2Regs.AQCTLA.bit.PRD = AQ_SET; EPwm2Regs.AQCTLB.bit.ZRO = AQ_SET; EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR; EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE; EPwm3Regs.ETSEL.bit.SOCAEN = 1; //启用 EPWMxSOCA 脉冲 EPwm3Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; //在向上计数时选择 SOC EPwm3Regs.ETPS.bit.SOCAPRD = ET_1ST; //在第1个偶数时生成脉冲 EPwm3Regs.ETCNTINITCTL.bit.SOCAINITEN = 1; EPwm3Regs.TBPRD = Sampling_RATE 400K; //设置采样率 EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; //递增计数模式 EPwm3Regs.CMPA.bit.CMPA = 10; // EPwm3Regs.AQCTLA.bit.ZRO = AQ_SET; // EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm4Regs.ETSEL.bit.SOCAEN = 1;//启用 EPWMxSOCA 脉冲 EPwm4Regs.ETSEL.bit.SOCASEL = 1;//在递增计数时选择 SOC EPwm4Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP;//计数器递增模式 EPwm4Regs.ETPS.bit.SOCAPRD = 1; //在发生第一个事件时生成脉冲 EPwm4Regs.TBPRD = 39061; // SOC 为2Hz }
ADC 配置:
void ConfigureADC (void) { // ADC SetVREF (ADC_ADCA、ADC_EXTERNAL、ADC_VREF2P5); EALLOW; AdcaRegs.ADCCTL2.bit.prescale = 6; //除以4 AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;// EOC 中断脉冲 AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1; //已通电 DELAY_US (1000); //等待初始化 AdcaRegs.ADCSOC0CTL.bit.CHSEL = 2; // SOC0将转换引脚 A2 AdcaRegs.ADCSOC0CTL.bit.ACQPS = 39; //采样窗口为40个 SYSCLK 周期 AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 9;//在 ePWM3 SOCA 上触发 AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0;// EOC0将设置 INT1标志 AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;//启用 INT1标志 AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//确保 INT1标志被清除 EDIS; // ADC 测量温度 SetVREF (ADC_ADCC、ADC_EXTERNAL、ADC_VREF2P5); EALLOW; AdccRegs.ADCCTL2.bit.prescale = 6; //除以4 AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1;// EOC 中断脉冲 AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1; //已通电 DELAY_US (1000); //等待初始化 AdccRegs.ADCSOC1CTL.bit.CHSEL = 0; // SOC1将转换引脚 C0 AdccRegs.ADCSOC1CTL.bit.ACQPS = 99; //采样窗口为100个 SYSCLK 周期 AdccRegs.ADCSOC1CTL.bit.TRIGSEL = 11;//在 ePWM4 SOCA 上触发 AdccRegs.ADCINTSEL1N2.bit.INT1SEL = 0;// EOC1将设置 INT1标志 AdccRegs.ADCINTSEL1N2.bit.INT1E = 0;//启用 INT1标志 AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;//确保 INT1标志被清除 EDIS; }
为了回答问题3、我们的 ePWM 触发器始终是固定的、变量是我们希望在 ISR 中执行的操作量或我们希望在 ISR 中运行的代码量。 ISR 检测时间随我们在每个构建中添加的内容而变化。 在同一个构建中、ISR 执行时间是固定的。
我想澄清一下、ADC 转换本身非常短、即在 ADC ISR 中运行的代码会耗费大量时间。
BTW、我们以100M 系统时钟运行、中断进入时间可能长达0.32us。 我的理解是否正确?
谢谢
谢尔登
您好、Sheldon、
感谢详细的跟进! 感谢您提供 ISR 代码、因为这现在澄清了中断进入时间+ ISR 时间可能是导致这种情况的原因。 我将在内部对此进行讨论、并将在星期二之前回复您。
此致、
Vince
您好、Sheldon、
在讨论之后、您可能会在另一个中断仍在处理时(如果我正确理解了您的问题)通过写入 ADC 中断缓冲区而使其溢出。 换句话说、如果您的中断请求(req2)在第一个请求(req1)正在处理时进入、那么在中断结束时、两个标志都会被清除。
编辑:此外、我想指出、如果由于等待状态存储器、 RPT 指令、多周期指令等而导致流水线延迟、那么理论上前面提到的周期数(32)可能会更高 因此、中断本身(从请求到完成执行)的时间肯定会超过2.5us。 例如、如果它是前面提到的最少32个周期、那么0.32us 将用于进入、加上 ISR 进程本身的2.3us、这将比2.5us 周期长。 必须认识到这些项目。
请告诉我、这是否提供了一点更清晰的信息。
此致、
Vince
尊敬的 Vince:
感谢您的详细解释和跟进。 我想我现在对此很清楚。
谢尔登