Seeed XIAO nRF52840的analogRead()读数不准确问题求助
问题:Seeed XIAO nRF52840 analogRead 读数偏低
我原本以为只是忽略了一些简单问题,但已经困扰许久,网上也找不到解决方案。
我使用Seeed XIAO nRF52840开发板,执行简单的analogRead(A3)操作时出现异常:当输入3V电压,代码输出结果为2.7V;测试其他电压的结果如下:
- 输入0.5V → 输出0.47V
- 输入1.5V → 输出1.41V
- 输入3.3V → 输出3.05V
低电压区间读数相对更准确。
接线方式:电源地连接nRF的GND引脚,电源输出直接连A3引脚,nRF通过USB供电。已经用万用表确认台式电源输出准确,更换全新开发板后问题依旧。
使用的代码如下:
#include <Arduino.h> #include <Adafruit_SPIFlash.h> float mv_per_lsb = 3300.0F / 1024.0F; // 10-bit ADC with 3.3V input range void setup() { Serial.begin(9600); } void loop() { // read the input on analog pin 3: int sensorValue = analogRead(A3); // print out the value as mV: Serial.println((float)sensorValue * mv_per_lsb); delay(50); // delay in between reads for stability }
解决方案
1. 修正ADC参考电压的错误假设
nRF52840的ADC默认参考电压不是3.3V,而是内部1.2V参考电压。你直接用3300/1024计算LSB的逻辑完全错误——当输入电压超过1.2V时,ADC读数会被压缩,这就是高电压区间偏差极大的核心原因。
2. 切换ADC参考电压为VDD
在Arduino环境下,针对nRF52840可以通过analogReference()函数切换参考电压为芯片供电电压(USB供电时约3.3V),修改后的代码如下:
#include <Arduino.h> void setup() { Serial.begin(9600); analogReference(AR_VDD); // 设置参考电压为芯片VDD(USB供电时≈3.3V) } void loop() { int sensorValue = analogRead(A3); // 先用万用表实测开发板3.3V引脚的真实电压,替换下面的3290(示例值) float mv_per_lsb = 3290.0F / 1024.0F; Serial.println((float)sensorValue * mv_per_lsb); delay(50); }
3. 移除无关库
你的代码中引入了Adafruit_SPIFlash.h但完全未使用,虽然不一定直接影响ADC,但建议移除该库,避免潜在的初始化冲突或资源占用。
4. 执行ADC硬件校准
nRF52840的ADC支持硬件校准,可以进一步提升读数精度,在setup中加入校准逻辑:
#include <Arduino.h> #include <nrf.h> void setup() { Serial.begin(9600); analogReference(AR_VDD); // 执行ADC偏移校准 NRF_ADC->TASKS_CALIBRATEOFFSET = 1; while(NRF_ADC->EVENTS_CALIBRATEDONE == 0); NRF_ADC->EVENTS_CALIBRATEDONE = 0; } void loop() { int sensorValue = analogRead(A3); float mv_per_lsb = 3290.0F / 1024.0F; Serial.println((float)sensorValue * mv_per_lsb); delay(50); }
5. 排查接线与驱动能力
确保使用短导线连接输入信号与A3引脚,避免因导线过长引入的分压误差;同时确认台式电源的输出阻抗足够低,能为ADC引脚提供稳定的电压驱动。
内容的提问来源于stack exchange,提问作者MattG
相关产品推荐
相关产品推荐

