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ı
相关产品推荐
相关产品推荐

