树莓派4上MCP3208读数错误且极不稳定问题求助
MCP3208 ADC读数错误且噪声极大的排查问题
我使用MCP3208这款ADC通过放大器读取传感器输出。已验证运算放大器的输出符合预期,且直接测量ADC引脚的电压也正常。该ADC由树莓派提供的3.3V供电,Vref引脚同样接3.3V。
问题出在ADC上(已更换两片芯片测试),其读数错误且噪声极大,以下是ADC引脚输入为3.3V时的输出示例:
Raw Value: 1338 | Voltage: 1.078V Raw Value: 1079 | Voltage: 0.870V Raw Value: 88 | Voltage: 0.071V Raw Value: 816 | Voltage: 0.658V Raw Value: 1250 | Voltage: 1.007V Raw Value: 1496 | Voltage: 1.206V Raw Value: 0 | Voltage: 0.000V Raw Value: 1095 | Voltage: 0.882V Raw Value: 711 | Voltage: 0.573V Raw Value: 1482 | Voltage: 1.194V Raw Value: 327 | Voltage: 0.264V Raw Value: 1344 | Voltage: 1.083V Raw Value: 967 | Voltage: 0.779V Raw Value: 38 | Voltage: 0.031V Raw Value: 647 | Voltage: 0.521V Raw Value: 3673 | Voltage: 2.960V Raw Value: 967 | Voltage: 0.779V Raw Value: 704 | Voltage: 0.567V Raw Value: 1087 | Voltage: 0.876V Raw Value: 999 | Voltage: 0.805V Raw Value: 384 | Voltage: 0.309V Raw Value: 583 | Voltage: 0.470V Raw Value: 1112 | Voltage: 0.896V Raw Value: 1343 | Voltage: 1.082V Raw Value: 1279 | Voltage: 1.031V Raw Value: 2672 | Voltage: 2.153V Raw Value: 1248 | Voltage: 1.006V
以下是读取ADC值所用的库代码:
#include "MCP3208.h" #include <wiringPi.h> using namespace std; MCP3208::MCP3208(int CS, int CLK, int MOSI, int MISO) { this->CS = CS; this->CLK = CLK; this->MOSI = MOSI; this->MISO = MISO; } void MCP3208::setupSPI() { wiringPiSetup(); pinMode(CS, OUTPUT); pinMode(CLK, OUTPUT); pinMode(MOSI, OUTPUT); pinMode(MISO, INPUT); digitalWrite(CS, HIGH); digitalWrite(CLK, LOW); digitalWrite(MOSI, LOW); } int MCP3208::readADC(int channel) { if (channel > 7 || channel < 0) return -1; digitalWrite(CS, LOW); //启动通信 // 构造命令 // 0b -> 二进制 // 11 -> 命令起始位 // (channel << 3) -> 将指定通道转为二进制后移至第5、4、3位 // 最后三位000 -> 无关位 unsigned char command = 0b11000000 | (channel << 3); // 从左到右发送命令 for (int i = 7; i >= 0; i--) { digitalWrite(MOSI, (command >> i) & 1); // 通过右移和掩码'& 1'提取第i位的值 digitalWrite(CLK, HIGH); digitalWrite(CLK, LOW); } // 读取12位ADC数据 int value = 0; for (int i = 11; i >= 0; i--) { value <<= 1; // 将现有位左移,为下一位读取腾出空间 digitalWrite(CLK, HIGH); // 向ADC发送信号,使其在MISO输出下一位 if (digitalRead(MISO)) { value |= 1; // 当位为1时添加该位,左移时默认位为0 } digitalWrite(CLK, LOW); } digitalWrite(CS, HIGH); return value; }
以下是用于打印值的程序代码:
#include "/home/pi/Desktop/MCP3208/MCP3208.h" #include <wiringPi.h> #include <stdio.h> // MCP3208参数 #define CS 10 // 片选引脚 #define CLK 14 // 时钟引脚 #define MOSI 12 // 主出从入引脚 #define MISO 13 // 主入从出引脚 MCP3208 adc(CS, CLK, MOSI, MISO); int main() { adc.setupSPI(); while (1) { int value = adc.readADC(1); // 读取通道1 float voltage = value * 3.3 / 4095.0; printf("Raw Value: %d | Voltage: %.3fV\n", value, voltage); delay(500); } return 0; }
补充说明:该电路此前使用MCP3008测试正常,为提高读数精度更换为MCP3208。根据两款ADC的数据手册,理论上无需更改电路即可直接替换,但不确定是否因此导致问题,也不清楚需具体检查哪些点。
内容的提问来源于stack exchange,提问作者LoneRetriever
相关产品推荐
相关产品推荐

