STM32L431 ADC中断异常:无触发标志时频繁进入ISR求助
STM32L431 ADC DMA+中断模式下ISR无标志误触发问题
我在STM32L431上同时使用ADC的DMA和中断功能,整体运行正常,但经常出现无任何已启用中断标志置位时,ISR仍被触发进入的情况。
初始ISR代码:
void ADC1_IRQHandler() { if(LL_ADC_IsActiveFlag_JEOC(ADC1)) { inj_buf[BL - DMA1_Channel1->CNDTR] = ADC1->JDR1; } else if(LL_ADC_IsActiveFlag_OVR(ADC1)) { LL_ADC_ClearFlag_OVR(ADC1); } else { __NOP(); // 此处设了断点,经常会命中 } }
在ST论坛发帖后,有人推测这是因为ISR退出过快,中断标志尚未完成清除导致重复触发,进入ISR后标志才最终清除。
之后我尝试了三种修复方法,但均未解决问题:
方法1:添加数据同步屏障指令
void ADC1_IRQHandler() { if(LL_ADC_IsActiveFlag_JEOC(ADC1)) { inj_buf[BL - DMA1_Channel1->CNDTR] = ADC1->JDR1; __DSB(); } else if(LL_ADC_IsActiveFlag_OVR(ADC1)) { LL_ADC_ClearFlag_OVR(ADC1); __DSB(); } else { __NOP(); } }
方法2:添加读改写操作延长ISR执行时间
依据ARM官方文档,尝试通过读改写操作增加ISR执行时长:
void ADC1_IRQHandler() { if(LL_ADC_IsActiveFlag_JEOC(ADC1)) { inj_buf[BL - DMA1_Channel1->CNDTR] = ADC1->JDR1; loop_cnt++; // 读-改-写操作 if(loop_cnt >= 1024) loop_cnt = 0; } else if(LL_ADC_IsActiveFlag_OVR(ADC1)) { LL_ADC_ClearFlag_OVR(ADC1); loop_cnt++; loop_cnt--; } else { __NOP(); } }
方法3:读取ISR寄存器确保标志同步
依据第三方技术帖子,尝试在操作后立即读取ISR寄存器:
void ADC1_IRQHandler() { if(LL_ADC_IsActiveFlag_JEOC(ADC1)) { inj_buf[BL - DMA1_Channel1->CNDTR] = ADC1->JDR1; temp_isr = ADC1->ISR & 0x7FF; // 操作后立即读取ISR寄存器 } else if(LL_ADC_IsActiveFlag_OVR(ADC1)) { LL_ADC_ClearFlag_OVR(ADC1); temp_isr = ADC1->ISR & 0x7FF; } else { __NOP(); } }
恳请各位提供技术帮助,谢谢!
内容的提问来源于stack exchange,提问作者Zhi
相关产品推荐
相关产品推荐

