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

STM32F401CB无法读取模拟电位器值,LED不亮问题排查

STM32F401CB ADC读取电位器控制LED无响应问题

我正在编写STM32F401CB的代码,希望通过模数转换后的电位器值控制LED亮灭。已将PA2配置为模拟输入,PB2配置为连接LED的通用输出。无论电位器阻值如何调整,LED始终不亮——按逻辑,当电位器转换值大于4300时LED应点亮,但目前完全没反应,我怀疑ADC未完成模数转换。

以下是我的代码:

#include "stm32f4xx.h"
uint16_t value=0;

void gpioa_config(void) {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
    GPIO_InitTypeDef gpioa_init_struct;
    gpioa_init_struct.GPIO_Pin=GPIO_Pin_2;
    gpioa_init_struct.GPIO_Mode=GPIO_Mode_AN;
    gpioa_init_struct.GPIO_OType=GPIO_OType_PP;
    gpioa_init_struct.GPIO_PuPd=GPIO_PuPd_NOPULL;
    gpioa_init_struct.GPIO_Speed=GPIO_Speed_25MHz;
    GPIO_Init(GPIOA,&gpioa_init_struct);
}

void gpiob_config(void) {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
    GPIO_InitTypeDef gpiob_init_struct;
    gpiob_init_struct.GPIO_Pin=GPIO_Pin_2;
    gpiob_init_struct.GPIO_Mode=GPIO_Mode_OUT;
    gpiob_init_struct.GPIO_OType=GPIO_OType_PP;
    gpiob_init_struct.GPIO_PuPd=GPIO_PuPd_NOPULL;
    gpiob_init_struct.GPIO_Speed=GPIO_Speed_25MHz;
    GPIO_Init(GPIOB,&gpiob_init_struct);
}

void adc_config() {
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
    ADC_InitTypeDef adc_init_struct;
    ADC_CommonInitTypeDef adc_common_init_struct;
    adc_common_init_struct.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;
    adc_common_init_struct.ADC_Mode=ADC_Mode_Independent;
    adc_common_init_struct.ADC_Prescaler=ADC_Prescaler_Div8;
    ADC_CommonInit(&adc_common_init_struct);

    adc_init_struct.ADC_Resolution=ADC_Resolution_12b;
    ADC_Init(ADC1,&adc_init_struct);
    ADC_Cmd(ADC1,ENABLE);
}
uint16_t adc_read() {
    ADC_RegularChannelConfig(ADC1,ADC_Channel_2,1,ADC_SampleTime_480Cycles);
    ADC_SoftwareStartConv(ADC1);

    while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET) {

    }

    return ADC_GetConversionValue(ADC1);
}

int main(void)
{
    gpioa_config();
    gpiob_config();
    adc_config();
    GPIO_ResetBits(GPIOB,GPIO_Pin_2);

  while (1)
  {
      value=adc_read();
      if (value>4300) {
          GPIO_SetBits(GPIOB,GPIO_Pin_2);
      }
      else {
          GPIO_ResetBits(GPIOB,GPIO_Pin_2);
      }
  }
}

问题排查与修复方案

1. 补全ADC核心配置参数

你的adc_config函数缺少连续转换模式、数据对齐等关键配置,导致ADC无法正常完成转换,需添加以下代码:

adc_init_struct.ADC_ContinuousConvMode = ENABLE; // 开启连续转换
adc_init_struct.ADC_DataAlign = ADC_DataAlign_Right; // 12位结果右对齐(默认配置但显式声明更可靠)
adc_init_struct.ADC_ScanConvMode = DISABLE; // 单通道无需扫描
adc_init_struct.ADC_NbrOfConversion = 1; // 单次转换通道数为1

添加后再执行ADC_Init(ADC1,&adc_init_struct);。

2. 优化ADC读取逻辑

  • 规则通道配置无需每次读取都重复执行,可移到adc_config函数末尾:
// 在adc_config函数的ADC_Cmd(ADC1,ENABLE);之前添加
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_480Cycles);
  • 等待转换完成后必须清除EOC标志,否则下次读取会误判转换状态:
uint16_t adc_read() {
    ADC_SoftwareStartConv(ADC1);
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
    ADC_ClearFlag(ADC1, ADC_FLAG_EOC); // 清除转换完成标志
    return ADC_GetConversionValue(ADC1);
}

3. 简化模拟引脚配置

PA2为模拟输入时,GPIO_OType和GPIO_Speed参数无效,可删除这两行简化代码:

void gpioa_config(void) {
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
    GPIO_InitTypeDef gpioa_init_struct;
    gpioa_init_struct.GPIO_Pin = GPIO_Pin_2;
    gpioa_init_struct.GPIO_Mode = GPIO_Mode_AN;
    gpioa_init_struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &gpioa_init_struct);
}

4. 硬件检查要点

  • 确认电位器两端接VCC和GND,中间抽头正确连接PA2
  • 确认LED串联220Ω~1kΩ限流电阻,且阳极接PB2、阴极接GND
  • 确认STM32芯片供电正常

5. 调试建议

可添加串口打印输出ADC读取值,确认数据是否正常变化:

// 需提前配置USART1串口
printf("ADC读取值:%d\r\n", value);

如果数值始终固定,检查ADC硬件或配置;如果数值变化但未达4300,可适当降低阈值(如改为3000)或调整电位器电压范围。

内容的提问来源于stack exchange,提问作者Onur Yağcı

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 17:06:00