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

STM32L476 ADC外部触发异常问题

分析STM32L476 ADC单次转换仅开EOSIE时丢中断的问题

首先得明确STM32L4系列ADC在单通道单次转换模式下的核心行为:当序列转换完成(这里序列只有1个通道),EOC(End of Conversion)和EOS(End of Sequence)标志会同时置位——这是芯片参考手册里明确说明的,毕竟单通道就是整个序列的全部内容。

问题根源:未正确处理EOC标志对EOS中断的连锁影响

当你同时开启EOCIE和EOSIE时,整个流程是顺畅的:

  • 转换完成后,两个标志同时置位,先后触发EOC和EOS中断
  • 在EOC中断服务程序(ISR)中,通常会读取ADC_DR寄存器,这会自动清除EOC标志;而EOS ISR里会手动清除EOS标志(写ADC_ISR的EOS位为1)
  • 所有标志都被彻底清除,下次TIM触发时,ADC能正常完成转换并再次置位两个标志,中断序列自然正常

但当你仅开启EOSIE时,就会出现丢中断的问题,具体逻辑链是:

  1. 第一次TIM触发,ADC完成转换,EOC和EOS同时置位,EOSIE使能触发中断
  2. 假设你的EOS ISR中只清除了EOS标志,EOC标志会一直保持置位状态
  3. 第二次TIM触发,ADC再次完成转换:此时EOC标志已经是1,硬件不会再次置位它;而STM32L4的ADC硬件逻辑中,当EOC标志未被清除时,EOS标志不会被重新置位(或者说不会生成新的中断请求)
  4. 因此第二次转换完成后,没有有效的EOS中断请求,就表现为“丢失一次中断”
  5. 第三次TIM触发时,如果你在启动转换前清除了ADC_ISR寄存器(如你描述的操作),会同时清除EOC和EOS标志,所以又能正常触发中断,最终呈现“每两次丢一次”的现象

解决方案

针对这个问题,有两个直接可靠的解决办法:

1. 在EOS中断服务程序中同时清除EOC和EOS标志

即使你只开启了EOSIE,每次中断处理时也要同时清除两个标志,避免残留标志干扰下一次转换:

void ADC_IRQHandler(void) {
  if (ADC1->ISR & ADC_ISR_EOS) {
    // 清除EOS标志
    ADC1->ISR = ADC_ISR_EOS;
    // 同时清除EOC标志:两种方式二选一
    ADC1->ISR = ADC_ISR_EOC; // 直接写1清除
    // 或者读取DR寄存器自动清除EOC:
    // uint32_t adc_result = ADC1->DR;
    // 处理转换数据...
  }
}

2. 优化ADC的EOC标志配置(可选辅助)

在STM32L4的ADC_CFGR寄存器中,有一个EOCS位(EOC Selection)。当配置EOCS=1时,EOC标志会在序列中每个通道转换完成时置位,而EOS标志仅在整个序列完成时置位。虽然对于单通道单次转换来说,这个配置的影响不大,但能进一步明确标志位的触发逻辑,减少冲突概率。不过核心还是要做好标志位的清除工作。

额外检查点

  • 确认TIM15触发ADC的配置正确:比如TRGO事件的选择(如更新事件)、ADC的触发极性(上升沿/下降沿)是否与TIM的输出匹配
  • 启动转换前清除ADC_ISR寄存器时,要确保是清除所有相关标志(EOC、EOS),而不是只清除部分

内容的提问来源于stack exchange,提问作者Guillaume Petitjean

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:01:08