SAMD21G18 ADC库采样数变更后结果异常求助
SAMD21G18 ADC采样数配置异常与归一化输出解决方案
问题根源分析
你遇到的核心问题是采样累加结果未做平均处理,且可能存在寄存器配置错误:
- SAMD21的ADC开启多采样时,
ADC.RESULT.reg存储的是多次采样的累加值,而非平均值。比如SAMPLENUM_2时,结果是2次12位采样的和(范围0~8190),但你直接读取成16位值,甚至可能因为寄存器对齐问题导致数值溢出(87800已超过16位最大值65535)。 - 另一个可能是
ADC.SAMPCTRL.reg配置错误:SAMD21的SAMPLENUM字段是「采样次数-1」,比如要2次采样需设为SAMPCTRL_SAMPLENUM(1),如果误设为SAMPCTRL_SAMPLENUM(2)会变成3次采样,累加值会更大。
修复步骤与代码实现
1. 修正采样结果处理逻辑
无论采样数多少,先将累加结果除以采样次数得到平均12位值,再归一化到16位范围:
#include <samd21.h> // 采样数定义(对应实际采样次数) #define SAMPLENUM_1 1 #define SAMPLENUM_2 2 uint16_t readPin_once(uint8_t pin, uint8_t sample_num) { // 复用你已实现的ADC引脚配置、参考电压初始化逻辑 adc_init_pin(pin); // 设置采样数:SAMPLENUM = 采样次数 - 1 ADC.SAMPCTRL.reg = sample_num - 1; while(ADC.SYNCBUSY.reg & ADC_SYNCBUSY_SAMPCTRL); // 等待同步完成 // 启动转换并等待结果就绪 ADC.COMMAND.reg = ADC_COMMAND_START; while(!(ADC.INTFLAG.reg & ADC_INTFLAG_RESRDY)); // 读取累加结果(注意:RESULT是16位寄存器,实际有效位随采样数增加) uint32_t accumulated = ADC.RESULT.reg; // 计算平均12位值 uint16_t avg_12bit = accumulated / sample_num; // 归一化到16位整数:(avg_12bit * 65535) / 4095 // 加2047是为了四舍五入,避免截断误差 uint16_t normalized_16bit = (avg_12bit * 65535 + 2047) / 4095; return normalized_16bit; }
2. 实现参考电压转换功能
基于归一化16位值计算实际电压,只需按比例映射:
float adc_to_voltage(uint16_t normalized_16bit, float ref_voltage) { // 65535是16位最大值,对应满量程参考电压 return (normalized_16bit / 65535.0f) * ref_voltage; }
关键验证点
- 测试SAMPLENUM_1时,归一化结果应在0~65535之间,对应原始12位值的线性映射(比如12位值2048对应16位值32768)。
- 切换SAMPLENUM_2后,结果应与SAMPLENUM_1基本一致(误差在采样噪声范围内),而非倍数关系。
- 确认
ADC.REFCTRL.reg配置的参考电压与你传入adc_to_voltage的ref_voltage一致(比如内部1.0V、1.5V或外部参考源)。
内容的提问来源于stack exchange,提问作者GlumandaGandalf
相关产品推荐
相关产品推荐

