PIC16F1947驱动MCP3421/MCP3551 实现高精度ADC转换实战
在工业控制现场,4-20mA电流信号是最常见的模拟量传输方式。它抗干扰能力强、传输距离远、便于现场布线。4-20mA信号到了控制板之后,怎么转换成单片机能够识别的数字量?
最直接的办法是用取样电阻把电流变成电压,再用ADC采集。今天,就以PIC16F1947为主控,配合MCP3421(18位I2C接口) 和MCP3551(22位SPI接口) 两款高精度Δ-Σ ADC,讲讲从4-20mA到数字量的完整链路。
一、信号调理:4-20mA转1-5V
在工业现场,4-20mA信号通常代表某个传感器的量程范围(如0-100°C、0-10MPa等)。要让ADC采集这个信号,第一步是把它转换成电压。
最简单的方法:串联一个250Ω精密电阻
根据欧姆定律:U = I × R
4mA × 250Ω = 1V
20mA × 250Ω = 5V
4-20mA信号流过250Ω电阻后,就变成了1-5V的电压信号。这个电压范围正好落在大多数ADC的输入范围内。
设计要点:
电阻精度:建议使用0.1%、25ppm以内的精密金属膜电阻,阻值误差直接影响采集精度
电阻功率:P = I² × R = 0.02² × 250 = 0.1W,用1/8W或更高功率的电阻即可
并联电容:在电阻两端并联一个0.1μF的陶瓷电容,滤除高频噪声
TVS或稳压管保护:在输入端并联TVS管(如SMBJ6.5CA)或5.1V稳压管,防止浪涌损坏ADC
二、PIC16F1947片内ADC:10位是否够用
PIC16F1947内部集成了17通道10位SAR型ADC。10位分辨率意味着将参考电压(如5V)分成1024份,每份约4.88mV。
计算一下精度:
4-20mA对应1-5V,每1mA对应250mV。10位ADC的分辨率约4.88mV,折算成电流约0.0195mA。
在工业控制场景下,需要的是对现场传感器的精确采集转换,进一步精确控制现场设备,考虑现场及转换过程中的各种误差因素,10位ADC就不太够用了。如果你的应用需要更高精度,就需要外接高分辨率ADC了。
三、MCP3421:18位I2C接口Δ-Σ ADC
当精度要求更高时,MCP3421是一个比较好的选择。
3.1 核心特性
MCP3421是一款单通道、低噪声、高精度的18位Δ-Σ ADC,采用微型SOT-23-6封装。
|
基本参数如下: 分辨率:18位(可配置为12/14/16/18位) 接口:I2C(支持标准/快速/高速模式) 片内基准:2.048V ±0.05% PGA:增益1/2/4/8可编程 采样率:3.75/15/60/240 SPS 功耗:145μA(连续转换),39μA(单次) 供电:2.7V ~ 5.5V 最大亮点:内置2.048V高精度基准和PGA,不需要外部参考电压和放大电路,外围元件极少。 |
||
3.2 硬件连接 |
||
![]() |
||
3.3 软件实现
MCP3421通过I2C接口通信,用户通过配置寄存器选择PGA增益、采样率和转换模式。
读取18位数据的时序:
- 主器件发送START + 器件地址(R/W=1)
- MCP3421应答
- 主器件连续读取3个数据字节 + 1个配置字节
- 第1字节的高7位是转换数据的MSB,第3字节的LSB是转换数据的LSB-
- 主器件发送STOP
代码示例(18位模式,单次转换) :
#include <pic16f1947.h>
#include <i2c.h>
#define MCP3421_ADDR 0x68 // 器件地址(取决于A2/A1/A0引脚连接)
// 配置寄存器值:单次转换,18位(3.75SPS),PGA=1
// 0b10011100 = 0x9C
// RDY=1(写1启动转换), C1C0=00, O/C=0(单次), S1S0=11(18位), G1G0=00(PGA=1)
#define CONFIG_18BIT_PGA1 0x9C
// 读取MCP3421 18位数据(单次转换模式)
long MCP3421_Read(void) {
unsigned char data[4];
long result = 0;
// 1. 发送配置字节(启动单次转换)
I2C_Start();
I2C_Write(MCP3421_ADDR << 1); // 写地址
I2C_Write(CONFIG_18BIT_PGA1); // 写配置,启动转换
I2C_Stop();
// 2. 等待转换完成(18位模式约267ms)
__delay_ms(300);
// 3. 读取转换结果(3字节数据+1字节配置)
I2C_Start();
I2C_Write((MCP3421_ADDR << 1) | 0x01); // 读地址
data[0] = I2C_Read(1); // 数据字节1(MSB),发送ACK
data[1] = I2C_Read(1); // 数据字节2,发送ACK
data[2] = I2C_Read(1); // 数据字节3(LSB),发送ACK
data[3] = I2C_Read(0); // 配置字节,发送NACK
I2C_Stop();
// 4. 合成18位数据(二进制补码格式)
// data[0]的高7位是D17-D11,data[1]是D10-D3,data[2]的高2位是D2-D1
result = ((long)(data[0] & 0x7F) << 11) | (data[1] << 3) | (data[2] >> 5);
// 如果符号位为1,扩展符号
if(data[0] & 0x80) {
result |= 0xFFFC0000; // 扩展为32位有符号数
}
return result;
}
计算实际电压:
18位模式下,LSB = 2.048V × 2 / 2^18 = 4.096 / 262144 ≈ 15.625μV
实际电压 = result × 15.625μV
四、MCP3551:22位SPI接口Δ-Σ ADC
对于需要极高精度的应用(如电子秤、高精度压力传感器),MCP3551是更好的选择。
4.1 核心特性
MCP3551是一款单通道22位Δ-Σ ADC,采用8引脚MSOP或SOIC封装。
基本参数:
分辨率:22位(有效分辨率21.9位)
接口:3线SPI
基准:外部参考(0.1V ~ VDD)
采样率:13.75 SPS
功耗:120Μa/5V,100Μa/2.7V
供电:2.7V ~ 5.5V
自动内部偏移和增益校准:每次转换都自动校准,无需用户干预
总不可调整误差小于10ppm
单命令启动转换:通过CS下降沿即可启动
注意:MCP3551需要外部参考电压,这一点与MCP3421不同。对于4-20mA采集,如果取样电阻电压范围是1-5V,参考电压应选择5V或4.096V等稳定电压源。
4.2 硬件连接
与MCP3421的电路基本一致,可以不用上拉电阻,但要加参考电压,参考电压的精度直接影响转换精度。
4.3 软件实现
MCP3551通过SPI接口通信,数据格式为24位:
读取时序:
- CS下降沿启动转换(单次模式)或开始读取(连续模式)
- 等待SDO/RDY引脚变低(转换完成)
- 在SCK下降沿读取24位数据
- CS上升沿结束读取
代码示例(单次转换模式) :
#include <pic16f1947.h>
#include <spi.h>
// SPI引脚定义
#define MCP3551_CS LATBbits.LATB0
#define MCP3551_CS_TRIS TRISBbits.TRISB0
#define MCP3551_RDY PORTBbits.RB1
// 读取MCP3551 22位数据
long MCP3551_Read(void) {
unsigned char data[3];
long result = 0;
// 1. CS拉低,启动转换
MCP3551_CS = 0;
// 2. 等待转换完成(RDY引脚变低)
// 典型转换时间约72.73ms
while(MCP3551_RDY == 1);
// 3. 读取24位数据(MSB first)
SPI_Exchange(0x00); // 读取高8位
data[0] = SPI_Exchange(0x00);
data[1] = SPI_Exchange(0x00);
data[2] = SPI_Exchange(0x00);
// 4. CS拉高,结束读取
MCP3551_CS = 1;
// 5. 合成24位数据
result = ((long)data[0] << 16) | (data[1] << 8) | data[2];
// 6. 检查溢出位
if(result & 0x800000) { // OVL=1,输入低于-VREF
// 处理低温出
}
if(result & 0x400000) { // OVH=1,输入高于VREF
// 处理高温出
}
// 7. 提取22位数据(bit21-bit0)
result = result & 0x3FFFFF; // 屏蔽OVH和OVL
// 8. 符号扩展(bit21为符号位)
if(result & 0x200000) {
result |= 0xFFC00000; // 扩展为32位有符号数
}
return result;
}
计算实际电压:
22位模式下,LSB = VREF / 2^22
实际电压 = result × VREF / 2^22
例如,VREF=4.096V时,LSB≈0.976μV——这意味着你能分辨到微伏级别的信号变化。
五、选型建议
追求设计简洁、PCB面积小、精度要求适中(0.1%~0.5%) 用 MCP3421。内
置基准和PGA,外围只需一个上拉电阻和退耦电容
追求极限精度(0.01%~0.05%)、需要外部精密基准 用 MCP3551
如果成本敏感且精度要求不高(<1%) 直接用PIC16F1947的片内10位
ADC
六、设计要点
1. 电源与参考电压
MCP3421使用内部基准,只需保证VDD干净(加0.1μF+(10-22)μF电容)
MCP3551需要外部精密基准,推荐REF50xx系列(如REF5040提供4.096V)
2. 输入保护
4-20mA输入端加TVS管(SMBJ6.5CA)或稳压管
取样电阻两端并联0.1μF陶瓷电容滤除高频噪声
3. I2C/SPI上拉电阻
MCP3421的SCL/SDA需要上拉电阻(4.7-10kΩ)
SPI总线不需要上拉(推挽输出)
4. PCB布局
ADC尽量靠近取样电阻,模拟走线尽量短
数字地和模拟地单点连接
取样电阻使用0.1%精度、25ppm温漂的金属膜电阻
4-20mA转1-5V加高精度ADC,是工业模拟量采集的经典方案。MCP3421和MCP3551两款芯片,基本覆盖了从“通用高精度”到“极限计量”的不同需求层次。
后续干货不断,咱们一起在单片机的世界里,共同进步。
更多推荐


所有评论(0)