You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 22:01:37