第一次接触NRF52832的SAADC模块时,我被它灵活的工作模式所吸引。这个12位精度的逐次逼近型ADC,在实际项目中能应对大多数传感器信号采集需求。与常见的单片机内置ADC不同,SAADC提供了单端和差分两种输入模式的选择,这让我在电池监测和工业传感器项目中有了更多设计空间。
记得最初调试光敏电阻电路时,单端模式简单粗暴的接线方式确实节省了不少时间。但当项目转移到电机控制环境后,地线噪声让单端采样的数据跳变得厉害。这时候差分模式就像救星一样,通过两根线抵消共模干扰的特性,让信号质量明显提升。不过差分模式也并非万能,它需要占用两个ADC通道,这在多路信号采集时就需要权衡了。
SAADC的参考电压选择也值得注意。相比早期型号,NRF52832取消了外部参考源,只能在内部0.6V和VDD/4之间选择。我在锂电池项目中就遇到过尴尬:当电池电压降到3V以下时,使用VDD/4作为参考会导致ADC量程自动缩小,这时如果还用之前的转换公式计算电压,结果就会偏差很大。
单端模式下的硬件连接看似简单,但有几个细节容易踩坑。以测量光敏电阻为例,正确的接法应该是将传感器分压电路的输出端连接到AIN0-AIN7中的任意引脚,同时确保传感器地线与NRF52832的GND可靠连接。我曾犯过一个低级错误——用杜邦线随意连接,结果引入的接触电阻导致测量值波动超过10%。
对于高阻抗信号源,建议在ADC输入端增加RC滤波。具体参数可以这样配置:1kΩ电阻串联10nF电容组成低通滤波器,截止频率约16kHz。这个组合既能滤除高频噪声,又不会对信号建立时间造成明显影响。实测显示,加入滤波后信号稳定性提升约40%。
配置单端模式时,CH[n].CONFIG寄存器的MODE位必须设为0。这里有个容易忽略的点:即使使用单端模式,PSELN引脚也需要明确配置为NC(未连接),否则可能引入额外噪声。以下是典型配置代码:
c复制nrf_saadc_channel_config_t config = {
.resistor_p = NRF_SAADC_RESISTOR_DISABLED,
.resistor_n = NRF_SAADC_RESISTOR_DISABLED,
.gain = NRF_SAADC_GAIN1_6,
.reference = NRF_SAADC_REFERENCE_INTERNAL,
.acq_time = NRF_SAADC_ACQTIME_10US,
.mode = NRF_SAADC_MODE_SINGLE_ENDED,
.pin_p = NRF_SAADC_INPUT_AIN0,
.pin_n = NRF_SAADC_INPUT_DISABLED
};
增益(GAIN)选择需要特别注意:当输入信号幅度较小时,可以选用1/6增益放大信号,但要注意此时满量程电压也会同比缩小。我在温度传感器项目中就曾因忽略这点,导致ADC值始终饱和。
差分模式真正的价值在工业现场才能充分体现。在变频器附近部署的压力传感器项目中,单端模式采集的数据完全不可用,切换差分模式后信噪比立即提升20dB以上。关键技巧在于双绞线的使用——将信号正负端用双绞线传输,能有效抑制电磁耦合干扰。
另一个实用技巧是共模电压的设定。NRF52832的SAADC要求差分信号的两个输入端电压都必须保持在0.3V至VDD-0.3V范围内。对于输出共模电压较高的传感器,可以通过电阻分压网络将信号调整到合适范围。我曾用10kΩ+30kΩ的分压组合成功适配了工业4-20mA变送器。
差分模式下的校准尤为重要。推荐上电后先执行OFFSET校准:
c复制nrf_saadc_offset_calibrate(NRF_SAADC, NRF_SAADC_CALIBRATION_OFFSET);
对于精度要求高的应用,还需要注意温度漂移的影响。我的做法是在PCB上靠近ADC引脚处放置NTC热敏电阻,建立温度补偿曲线。实测表明,这种方法可以将温漂误差控制在±0.5%以内。
差分信号的采样时序也需要特别关注。TACQ参数应该根据信号源阻抗适当调整,对于输出阻抗大于10kΩ的传感器,建议将采集时间设为40μs以上。配置示例如下:
c复制config.acq_time = NRF_SAADC_ACQTIME_40US;
选择单端还是差分,我总结了一个简单的决策流程:首先测量信号幅度,如果超过VDD的80%,直接使用单端模式;其次检查信号源与MCU是否共地,非共地系统必须用差分;最后评估环境噪声,电机、变频器等干扰源存在时优先考虑差分。
有个典型案例:在智能农业项目中监测土壤湿度,虽然传感器与控制器共地,但由于长达10米的传输线引入了感应噪声,最终差分模式的表现完胜单端,测量稳定性提升约35%。
差分模式需要权衡通道资源。NRF52832虽然有8个模拟通道,但差分模式下每路信号占用两个通道。当需要采集4路以上信号时,可能需要采用时分复用方案。我的惯用做法是给关键信号分配差分通道,次要信号使用单端模式。
功耗也是考量因素。差分模式由于要维持两个输入端的采样电路,功耗会比单端模式高15%-20%。在电池供电设备中,可以通过间歇采样的方式平衡功耗与性能需求。
监测锂电池电压是单端模式的典型应用。这里有个精妙的设计技巧:利用VDD/4作为参考电压,配合1/6增益,可以直接测量0-3.6V范围的电池电压,无需额外分压电路。具体配置如下:
c复制config.reference = NRF_SAADC_REFERENCE_VDD4;
config.gain = NRF_SAADC_GAIN1_6;
转换公式需要相应调整:
c复制#define ADC_BATTERY_VOLTAGE(ADC_VALUE) \
((ADC_VALUE) * 3.6f * 6.0f / 1024.0f)
称重传感器等电桥输出最适合差分模式。我的经验是配合仪表放大器使用,比如AD623将mV级信号放大到适合ADC采样的范围。关键参数匹配要点:
这种组合在实际称重系统中实现了0.1%的测量精度,完全满足商业电子秤要求。
ADC值跳变严重时,首先检查电源质量。用示波器查看VDD纹波,如果超过50mVpp,需要加强滤波。我在一个案例中发现,仅仅在MCU电源引脚增加47μF钽电容,就将ADC波动幅度从3%降到0.5%。
采样值始终为0或满量程,通常是引脚配置错误。用万用表测量实际输入电压,确认是否在允许范围内。特别提醒:NRF52832的ADC引脚不能承受负电压,哪怕-0.3V也可能损坏器件。
使用EasyDMA时,缓冲区地址必须对齐到4字节边界。我习惯这样定义缓冲区:
c复制__ALIGN(4) static nrf_saadc_value_t m_buffer[2];
对于需要快速响应的应用,建议采用事件驱动方式而非轮询。例如配置PPI将SAADC的RESULTDONE事件直接关联到DMA传输任务,这样能节省约20μs的CPU处理时间。
在低功耗设计中,每次采样后及时调用nrfx_saadc_uninit()关闭模块,实测可使系统待机电流降低约300μA。但要注意重新初始化时需要完整配置所有参数。