4. ADC选型与驱动:常用ADC芯片介绍、I2C/SPI接口驱动、采样率与分辨率权衡

好,咱们进入第四讲。ADC选型,说白了就是给万用表选一双「好眼睛」。眼睛要看得清,还得看得快。但这两者往往互相矛盾。我这些年折腾过不少ADC芯片,踩过的坑能写一本小册子。今天咱们就聊聊怎么选、怎么用。

4.1 常用ADC芯片:ADS1115与MCP3421

先说说市面上最常见的两款低功耗ADC。我个人习惯,做便携式万用表时,首选就是它们俩。

4.1.1 ADS1115:TI的经典之作

ADS1115是TI出品的一款16位Δ-Σ型ADC。它内置了可编程增益放大器(PGA),支持±256mV到±6.144V的输入范围。嗯,这里要注意,它的实际分辨率是15位,因为最高位是符号位。

核心参数:

  • 分辨率:16位(实际有效位15位)
  • 采样率:8SPS ~ 860SPS(可编程)
  • 接口:I2C(地址可选,最多4个设备)
  • 供电:2.0V ~ 5.5V

我在项目中遇到过一个问题:用ADS1115测电池电压,发现读数跳得厉害。后来查了半天,原来是PGA增益设置太高,输入信号噪声被放大了。你想想看,16位分辨率下,哪怕1mV的噪声都会被量化成几十个LSB。所以,增益不是越大越好

4.1.2 MCP3421:Microchip的省心之选

MCP3421是Microchip的18位Δ-Σ型ADC。它比ADS1115多2位分辨率,但采样率更低。说白了,它更适合测缓慢变化的信号,比如温度、压力。

参数 ADS1115 MCP3421
分辨率 16位 18位
最大采样率 860 SPS 240 SPS(12位模式)
接口 I2C I2C
内置参考电压 有(2.048V) 有(2.048V)
价格 约2-3元 约5-8元

我建议,如果做万用表的直流电压档,ADS1115就够用了。但如果你要做高精度电阻测量,MCP3421的18位分辨率会更合适。当然,代价就是采样慢——240SPS在18位模式下,其实只有15SPS左右。

4.2 I2C/SPI接口驱动:选对总线,事半功倍

这两种ADC都支持I2C接口。I2C的好处是引脚少——只需要SDA和SCL两根线。但坏处是速度慢,而且容易受干扰。

我曾经在一个项目中,I2C总线长度超过30cm,结果通信经常出错。后来加了上拉电阻,又把速率降到100kHz,才算稳定。所以,I2C总线布线要短,上拉电阻要选对(一般4.7kΩ左右)。

4.2.1 ADS1115的I2C驱动示例

下面是我常用的ADS1115初始化代码。注意看配置寄存器的设置——这是最容易出错的地方。

// ADS1115 I2C地址:0x48(ADDR接GND)
#define ADS1115_ADDR 0x48

// 配置寄存器:连续转换模式,±4.096V范围,128SPS
uint16_t config = 0x0183;  // 二进制:0000 0001 1000 0011

void ADS1115_Init(void) {
    uint8_t data[3];
    data[0] = 0x01;  // 指向配置寄存器
    data[1] = (config >> 8) & 0xFF;  // 高字节
    data[2] = config & 0xFF;          // 低字节
    I2C_Write(ADS1115_ADDR, data, 3);
}

uint16_t ADS1115_Read(void) {
    uint8_t reg = 0x00;  // 指向转换寄存器
    uint8_t buf[2];
    I2C_Write(ADS1115_ADDR, &reg, 1);
    I2C_Read(ADS1115_ADDR, buf, 2);
    return (buf[0] << 8) | buf[1];
}

小技巧:配置寄存器的第15位是「启动转换」位。如果你用单次转换模式,每次读取前都要置1。我习惯用连续转换模式,省事。

4.2.2 MCP3421的I2C驱动示例

MCP3421的驱动稍微复杂一点,因为它的一次性转换模式需要等待转换完成。我一般用轮询方式——读取配置寄存器,检查第7位(RDY)是否为0。

// MCP3421 I2C地址:0x68(默认)
#define MCP3421_ADDR 0x68

// 配置字节:18位分辨率,连续转换,增益x1
uint8_t config = 0x18;  // 二进制:0001 1000

uint32_t MCP3421_Read(void) {
    uint8_t buf[4];
    uint8_t status;
    
    // 发送配置字节,启动转换
    I2C_Write(MCP3421_ADDR, &config, 1);
    
    // 等待转换完成(18位模式下约67ms)
    do {
        I2C_Read(MCP3421_ADDR, buf, 4);
        status = buf[3];  // 最后一个字节是配置字节
    } while (status & 0x80);  // 检查RDY位
    
    // 组合数据:18位,左对齐
    uint32_t value = ((uint32_t)buf[0] << 16) | 
                     ((uint32_t)buf[1] << 8) | 
                     buf[2];
    return value;
}

注意:MCP3421的转换时间与分辨率有关。12位模式约1ms,14位约4ms,16位约17ms,18位约67ms。如果你在循环里频繁读取,记得加延时,否则会读到旧数据。

4.3 采样率与分辨率权衡:鱼和熊掌不可兼得

这是ADC选型中最核心的问题。你想想看,ADC内部有个数字滤波器,采样率越低,滤波器带宽越窄,噪声越小,有效分辨率就越高。反之亦然。

我举个例子。ADS1115在860SPS时,有效分辨率只有12位左右。但在8SPS时,有效分辨率能达到15位。说白了,每降低一倍采样率,分辨率大约提升0.5位

采样率(SPS) ADS1115有效位 MCP3421有效位
860 12位
240 13位 12位
60 14位 14位
15 15位 16位
8 15位 18位

那么,怎么选?我建议遵循以下原则:

  • 测直流电压/电阻:用低采样率(8-15SPS),追求高分辨率。万用表显示更新慢一点没关系,读数稳定才重要。
  • 测交流信号/频率:用高采样率(240-860SPS),但要做好数字滤波。我曾经用ADS1115测50Hz交流电,采样率设到860SPS,然后做64点平均,效果还不错。
  • 测温度/压力:用中等采样率(60SPS),兼顾速度和精度。MCP3421的16位模式在这里很合适。

避坑指南:我曾经在做一个电池内阻测试仪时,为了追求高分辨率,把采样率设到了8SPS。结果发现读数更新太慢,用户按一下测试按钮,要等125ms才出结果。后来改到60SPS,虽然分辨率降了1位,但用户体验好多了。所以,不要盲目追求高分辨率,要考虑实际应用场景

最后,再提一句。如果你需要同时测量多个通道,ADS1115有4个输入通道(差分或单端),而MCP3421只有1个。但MCP3421可以通过外部多路复用器扩展。我个人习惯,如果通道数不超过4个,直接用ADS1115;超过4个,就用MCP3421加模拟开关(比如CD4051)。

好了,这一讲就到这里。下一讲咱们聊聊前端信号调理电路——怎么把高压信号安全地送进ADC。嗯,那才是真正考验硬件工程师功底的地方。