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, ®, 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。嗯,那才是真正考验硬件工程师功底的地方。