你是不是也遇到过STM32 采一个电位器串口打印出来的 ADC 值一直跳。明明手没碰数据却在 2040、2058、2033 之间来回晃。然后你开始怀疑ADC 配置错了HAL 库有问题DMA 出 bug 了代码改了一晚上最后发现——还是抖。说实话ADC 这东西最坑初学者的地方就在这里它看起来是软件问题实际经常是硬件、电源、采样参数一起在搞你。先记住一句话ADC 不是在测一个绝对电压它是在拿输入电压和参考电压做比较。如果你的 3.3V 本身不稳ADC 结果一定跟着跳。项目里很常见继电器一吸合、电机一启动、WiFi 模块一发射3.3V 掉一下ADC 数值马上变。这时候你在代码里疯狂平均意义不大。因为根上是电源在抖。我之前调过一个板子ADC 测电池电压静态很稳一开电机就乱跳。最后不是 ADC 配置问题而是电机电流把地线拉动了。ADC 看到的不是电池电压是整块板子的噪声。第二个常见坑采样时间太短。很多人配置 ADC 时采样周期随手选最小。看起来转换速度快实际很容易翻车。比如你用 100K、100K 电阻分压测电池。万用表看着很稳ADC 读出来却飘。原因很简单输入阻抗太高ADC 内部采样电容还没充满就开始转换了。低速信号别贪快。电池电压、温度、电位器这些东西根本不需要特别快。采样时间适当加长反而更稳。第三个坑输入脚悬、线太长、旁边有 PWM。ADC 引脚很敏感。传感器线从电机线旁边走PWM 线贴着模拟信号线跑数据不抖才怪。正确做法很朴素ADC 输入脚附近加个小电容比如 0.01uF 到 0.1uF。响应速度要求不高的场景这招非常管用。但注意电容不是越大越好。你测旋钮可以大一点测快速变化信号就不能乱加。软件上最常用的不是复杂算法而是多次采样取平均。uint16_tADC_ReadOnce(void){HAL_ADC_Start(hadc1);HAL_ADC_PollForConversion(hadc1,10);uint16_tvalueHAL_ADC_GetValue(hadc1);HAL_ADC_Stop(hadc1);returnvalue;}uint16_tADC_ReadAverage(uint8_ttimes){uint32_tsum0;for(uint8_ti0;itimes;i){sumADC_ReadOnce();HAL_Delay(1);}returnsum/times;}比如你主循环里这样用uint16_tadc_rawADC_ReadAverage(16);floatvoltageadc_raw*3.3f/4095.0f;16 次平均对电池电压、温度检测、电位器读取这类场景已经够用了。如果你想让显示更平滑可以再加一个简单的一阶滤波uint16_tADC_Filter(uint16_tnew_value){staticuint16_told_value0;if(old_value0)old_valuenew_value;old_value(old_value*7new_value)/8;returnold_value;}使用方式uint16_tadc_avgADC_ReadAverage(16);uint16_tadc_showADC_Filter(adc_avg);这段代码的效果很直接数据不会突然乱跳显示也更舒服。但我要提醒一句滤波只能让数据好看不能替你解决硬件问题。如果 ADC 接 GND 都还在乱跳那先查配置、供电、地线、参考电压。如果接 GND 稳接 3.3V 也稳接传感器才抖那就重点查传感器输出、分压电阻、线长、干扰和输入阻抗。我自己排查 ADC 问题一般按这个顺序来先把 ADC 脚接 GND看是不是接近 0。再接 3.3V看是不是接近 4095。再接一个稳定分压点看抖动范围。最后才接传感器。这一步很关键。它能快速判断到底是 ADC 本身的问题还是外部电路的问题。很多初学者最大的问题就是一上来盯着代码改。ADC 不是纯软件模块它站在硬件和软件中间。电源不干净、参考电压不稳、采样时间太短、输入阻抗太高、走线被干扰最后都会变成你串口里的“数值乱跳”。所以ADC 采样不稳别急着怀疑 HAL 库。先把电源稳住把采样时间加长把输入阻抗降下来再谈滤波。真正做项目的人都知道ADC 稳不稳代码只占一半另一半藏在电源、地线和那根你没注意的模拟信号线上。如果你也被 ADC 数值乱跳折磨过建议收藏这篇。下次项目翻车时按这个顺序排查能少走很多弯路。