当前位置:首页 > 嵌入式 > 嵌入式分享
[导读]12位ADC理论分辨率是1/4096≈0.024%,压到0.1%看起来宽松,但工程里真做不到——不是算法不行,是硬件没兜底。先说结论:0.1%精度=稳定参考源+足够采样时间+两点校准+“中值削尖峰→过采样提有效位→滑动平均压噪声”三段滤波。只写“采16次求平均”永远到不了。


12位ADC理论分辨率是1/4096≈0.024%,压到0.1%看起来宽松,但工程里真做不到——不是算法不行,是硬件没兜底。先说结论:0.1%精度=稳定参考源+足够采样时间+两点校准+“中值削尖峰→过采样提有效位→滑动平均压噪声”三段滤波。只写“采16次求平均”永远到不了。

一、先堵硬件漏点

软件洗不掉系统误差:

VREF用VDDA→电源纹波直接进读数,必须外置基准(REF3033/REF5030类)

高阻信号采样时间太短→采样电容没充满,读数偏低,按源阻抗拉长Sampling Time

输入前加RC(1k~10k+10nF~1μF),运放缓冲高阻源

上电先做ADC自校准,消偏移和增益误差

HAL_ADCEx_Calibration_Start(&hadc1);   // 校准在使能后、主循环前

二、过采样提有效位数

每4倍过采样多约1位有效分辨率:16倍≈多2位,把12位洗到接近14位有效。

#define OS_N 16

uint32_t adc_oversample(void){

   uint32_t sum=0;

   for(int i=0;i<OS_N;i++){

       sum += adc_single();   // 硬件触发,固定间隔

   }

   return sum>>4;             // 16倍右移4位

}

前提:信号带自然噪声做dither,纯直流无噪时过采样不增值。

三、中值滤波削单点尖峰

静电、PWM耦合、接触不良会产生离群点,平均会被带偏,先中值:

#define MED_N 5

uint16_t median5(uint16_t*b){

   uint16_t t;

   for(int i=0;i<MED_N-1;i++)

   for(int j=i+1;j<MED_N;j++)

       if(b[i]>b[j]){t=b[i];b[i]=b[j];b[j]=t;}

   return b[2];

}

N=5或7够用,太大响应迟滞。

四、滑动平均收尾

中值输出再进环形缓冲做滑动平均,压随机白噪声:

#define AVG_N 8

static uint16_t ring[AVG_N];

static uint32_t idx=0, sum=0;


uint16_t adc_chain(uint16_t raw){

   uint16_t m = median5(window_push(raw));

   sum -= ring[idx];

   ring[idx]=m; sum += m;

   idx=(idx+1)%AVG_N;

   return sum/AVG_N;

}

工程组合顺序固定:过采样→中值→滑动平均。反过来先平均再中值,尖峰已经污染累加值。

五、两点校准补系统误差

滤波只压噪声,不补偏移/增益。上电用标准源做两点:

float adc_cal(uint16_t raw){

   // offset: 零点码值, gain: 满量程斜率

   return (raw - cal_offset)*cal_gain;

}


void calib_do(uint16_t raw0v, uint16_t raw_full, float vref){

   cal_offset = raw0v;

   cal_gain   = vref/(raw_full-raw0v);

}

零点接GND测offset,满量程接基准电压测gain,存Flash,每次上电加载。

六、完整采集节拍

float sample_voltage(void){

   uint16_t raw = adc_chain(adc_oversample());

   float v = adc_cal(raw) * VREF / 4095.0f;

   return v;

}

慢信号(温度、电池电压)窗口可以长;控电流环里平均窗口别太长,相位延迟会带偏闭环。

七、落坑清单

VREF接VDDA→电源抖全部进读数

采样时间按默认最短→高阻源读偏低

只平均不过中值→单点毛刺拉偏

不过校准→整体偏移0.1V查不出

过采样但信号纯直流无噪→白采

滑动窗口32点→阶跃响应慢半拍

短接输入还对称抖才叫噪声,单向偏是硬件错

滤波后不校准→精度卡在1%上不去

中断里跑排序中值→ISR超时

参考源没去耦电容→高频纹波残留

八、落地顺序

外置基准+RC前端+长采样时间

上电自校准+两点标定存Flash

过采样16倍提有效位

中值滤波削脉冲

滑动平均压随机噪声

校准参数回灌电压换算

短接输入看噪声底,再接标准源看系统误差

实测0.1%内才进业务,否则回查硬件

ADC高精度不是“多采几次”,是硬件把系统误差控住、软件把噪声洗掉:基准和采样时间是地基,过采样换有效位,中值砍尖峰,滑动平均收尾,校准补偏移增益。只靠平均永远压不到0.1%——先短接输入端看一眼,对称抖动是能救的噪声,单向偏移是救不回来的硬件病。

你想继续深入校准实现、噪声分析,还是代码优化?



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除( 邮箱:macysun@21ic.com )。
关闭