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

STM32F4 ADC多通道中断逻辑错误排查求助

解决STM32F4 ADC中断双通道控制LED异常问题

问题描述

使用STM32F4的ADC中断功能,PA0、PA1作为模拟输入,PC0、PC1接外部LED。预期PA0输入高电平时PC0点亮,PA1输入高电平时PC1点亮,但实际PA0加3.3V时两个LED都亮,PA1触发无反应,硬件无问题,代码存在两处逻辑错误。

错误定位与修正

错误1:ADC中断标志位未清除

中断函数中仅判断了EOC(转换完成)标志位,但未清除该标志,导致中断不断触发,adc_index快速循环切换,两个LED的控制逻辑被连续执行,最终出现双灯同时点亮的情况。

修正方法:在中断处理完成后清除EOC标志位:

ADC1->SR &= ~(0x1 << 1);

错误2:ADC通道1采样时间未配置

代码中仅配置了ADC通道0(PA0)的采样时间,通道1(PA1)的采样时间未设置,默认采样时间过短,导致PA1的ADC转换数据不准确,无法触发LED控制逻辑。

修正方法:添加通道1的采样时间配置:

// 通道1采样时间84周期
ADC1->SMPR2 &= ~(0x7 << 3);
ADC1->SMPR2 |= (0x4 << 3);

修正后的完整代码

#include "main.h"
volatile uint8_t adc_index = 0;
void SystemClock_Config(void);

void ADC_IRQHandler(void)
{
    if(ADC1->SR & (0x1 << 1))
    {
        uint8_t val = (uint8_t)ADC1->DR;
        if(adc_index == 0)
        {
            if(val > 127)
                GPIOC->BSRR = (1 << 0);
            else
                GPIOC->BSRR = (1 << 16);
        }
        else
        {
            if(val > 127)
                GPIOC->BSRR = (1 << 1);
            else
                GPIOC->BSRR = (1 << 17);
        }
        adc_index++;
        if(adc_index >= 2) adc_index=0;
        
        // 清除EOC中断标志位
        ADC1->SR &= ~(0x1 << 1);
    }
}

int main(void)
{
  HAL_Init();
  SystemClock_Config();

  RCC->AHB1ENR |= (0x5 << 0);
  RCC->APB2ENR |= (0x1 << 8);

  // PA0 as Analog Input for ADC
  GPIOA->MODER |= (0x3 << 0);
  // PA1 as Analog Input for ADC
  GPIOA->MODER |= (0x3 << 2);
  // PC1 as General output for external Led
  GPIOC->MODER &= ~(0x3 << 2);
  GPIOC->MODER |= (0x1 << 2);
  // PC0 as General output for external Led
  GPIOC->MODER &= ~(0x3 << 0);
  GPIOC->MODER |= (0x1 << 0);

  // ADC Cont mode on
  ADC1->CR2 |= (0x1 << 1);
  // Interrupt enable for ADC
  ADC1->CR1 |= (0x1 << 5);

  // 8 bit Resolution
  ADC1->CR1 &= ~(0x3 << 24);
  ADC1->CR1 |= (0x2 << 24);

  // 2 Channel conversion
  ADC1->SQR3 |= (0x0 << 0);
  ADC1->SQR3 |= (0x1 << 5);

  // 2 CONVERSION Selected
  ADC1->SQR1 |= (0x1 << 20);

  // Sample Rate 84 CYCLES for Channel 0
  ADC1->SMPR2 &= ~(0x7 << 0);
  ADC1->SMPR2 |= (0x4 << 0);
  // Sample Rate 84 CYCLES for Channel 1
  ADC1->SMPR2 &= ~(0x7 << 3);
  ADC1->SMPR2 |= (0x4 << 3);

  // ADC_IRQHandler unmasked
  NVIC->ISER[0] = (0x1 << 18);

  // ADC On
  ADC1->CR2 |= (0x1 << 0);

  // Software Start
  ADC1->CR2 |= (0x1 << 30);

  while (1)
  {

  }
}

验证说明

修正后,PA0输入3.3V时,ADC转换值大于127,PC0点亮;PA1输入3.3V时,PC1点亮,符合预期功能。

内容的提问来源于stack exchange,提问作者Umutcan Akyol

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 06:33:21