2026/11/5 6:26:35

24位Σ-Δ ADC与PIC24搭配:工业温度采集信号链实战

24位Σ-Δ ADC与PIC24搭配:工业温度采集信号链实战 去年做一套 HVAC 风管温度采集板时我犯过一个典型的选型错误以为 PIC24HJ256GP610 这种自带 12 位 SAR ADC 的 16 位单片机直接采 PT1000 就行。结果低温漂、电源纹波、地噪声叠加起来同一只探头在不同电压下能差出 1.5℃。后来把信号链改成 ADS122U04IPWR 这颗带 UART 接口的 24 位 Σ-Δ ADC配合 PIC24HJ256GP610 处理协议和线性化问题一次解决。这篇就聊聊这套组合在工业和 HVAC 测温里的完整落地过程从选型理由、传感器信号链、硬件布局到固件实现和校准结果都按我实际调试的顺序写。这套方案适合做多通道温度采集模块、冷冻水/风管温度变送器、工业过程控制输入板的人参考。ADS122U04IPWR 一颗芯片可以接 4 路温度传感器PIC24HJ256GP610 有双 UART两颗 ADS122U04 就能组成 8 路测温板数字接口只有 4 根线。对大多数 HVAC 控制柜来说这种组合的性价比和可靠性都很合适。1. 一颗带 UART 的 24 位 ADC 凭什么替代 MCU 内置 ADC1.1 内置 ADC 的精度瓶颈不在位数在参考和噪声PIC24HJ256GP610 内置的是 12 位 SAR ADC采样率很高但对精密温度测量来说瓶颈不只是位数。12 位分辨率在 3.3V 参考下1 个 LSB 大约是 0.8mV。PT1000 在常温下灵敏度大约是 3.85Ω/℃,如果激励电流取 500μA对应电压变化是 1.925mV/℃。也就是说即使不考虑噪声12 位 ADC 的量化粒度本身就接近 0.4℃这对于要求整机误差 ±0.5℃ 的 HVAC 项目来说几乎没有设计余量。更麻烦的是 SAR ADC 的积分非线性和参考电压温漂。MCU 内置参考电压通常没有精密校准温度变化时参考电压漂移会直接变成测量误差。而外置 Δ-Σ ADC 的优势在于分辨率高、内置 PGA、内置激励电流源并且可以选择外部精密参考电阻做比例式测量从根本上抵消参考电压和激励电流的温漂。这是精度设计的核心思路后面详述。1.2 UART 接口比 SPI 更适合工业温度采集的三个理由ADS122U04IPWR 最特殊的地方是它用 UART 而不是 SPI/I2C 做主机接口。最初我也觉得 SPI 更常规实际用下来发现在工业测温场景里 UART 反而有实打实的好处。第一是布线简单。UART 只需要 TX、RX 两根线不需要时钟线。温度采集板经常要把模拟前端靠近传感器数字部分靠近控制器中间隔一段距离。SPI 的时钟信号在长线上容易出现振铃和误采样UART 只要波特率匹配对线间电容的容忍度高很多。第二是隔离方便。工业现场控制器和传感器之间经常需要电气隔离。隔离 SPI 至少需要隔离时钟、数据输入、数据输出三根线而 UART 只需要隔离 TX、RX 两根线隔离器成本更低PCB 面积也更小。我后来用 ISO7721 做数字隔离两路正好够用。第三是 MCU 的资源压力小。PIC24HJ256GP610 自带两个 UART 模块硬件上天然支持两颗 ADS122U04不需要像 I2C 那样处理地址仲裁也不像 SPI 那样频繁切换片选。每个 ADC 独占一组 UART 收发固件逻辑非常干净。1.3 PIC24HJ256GP610 在这套方案里的角色分配PIC24HJ256GP610 不是一颗普通的 8 位单片机它有 256KB 程序闪存16 位内核带 DSP 指令最高到 40 MIPS 级别。在温度采集系统里这性能绰绰有余所以选它是为了富余。实际任务分配是这样的一个 UART 连接 ADS122U04 做命令收发另一个 UART 连接 RS-485 收发器跑 Modbus RTU 协议定时器驱动采集节拍比如每秒轮询所有通道主循环里做线性化、数字滤波、超限判断。由于 ADS122U04 本身是 24 位分辨率PIC24 侧不需要再做复杂的浮点运算来弥补位数甚至在 XC16 里可以用整型和查表法完成大部分计算只在线性化最后一步调用浮点库。2. RTD 和热电偶前端从传感器到 ADC 的完整信号链设计2.1 PT100/PT1000 比例式测量与引线补偿工业测温最常见的传感器是 PT100 和 PT1000。ADS122U04 内置两个可编程激励电流源 IDAC可以配置成 50μA 到 1500μA 之间的电流。测 RTD 时的经典接法是比例式测量。比例式的核心思路是让同一个 IDAC 电流既流过 PT 传感器又流过一颗高精度参考电阻。把参考电阻两端的电压接到 ADS122U04 的 REFP 和 REFN 引脚传感器电压接到模拟输入通道。这样转换结果等于 V_sensor 和 V_ref 的比值IDAC 电流的绝对温度漂移被直接消除了因为电流同时影响分子和分母。参考电阻选温漂小的金属箔电阻或精密薄膜电阻比如 10ppm/℃ 以下整个系统的参考稳定性就比 MCU 内置参考高一个数量级。引线补偿方面PT100 在工业现场常常接两线制这会带来明显误差。比如 10Ω 的引线电阻对 PT100 来说就是约 25℃ 的偏差完全不可接受。我实际推荐至少三线制或者干脆用四线制。ADS122U04 有四个模拟输入通道三线制接法可以这样分配IDAC1 流出到 RTD 一端经引线到传感器再经另一根引线回到模拟输入负极同时用第三根引线单独采样正端电压。具体到 ADS122U04差分输入 AI0、AI1 直接采 RTD 两端IDAC2 作为附加激励配合参考电阻可以实现三线制的引线电阻自动抵消。四线制就更直接两条线提供激励电流另两条线采样电压采样回路几乎没有电流流过引线电阻影响可以忽略。HVAC 的现场条件通常只能拉三根线所以我在固件里做了一个三线制补偿配置项标定时记录短接引线电阻软件扣除。2.2 热电偶测量与冷端补偿热电偶的电压信号很小K 型热电偶大约是 41μV/℃工业上常用的是 K 型和 T 型。ADS122U04 内部 PGA 最高可到 128 倍非常适合把微伏级信号放大到 ADC 的满量程范围附近。但热电偶有个老生常谈的问题冷端补偿。热电偶输出的是热端和冷端的温差电动势必须知道冷端温度才能算出热端绝对温度。ADS122U04 内部集成了芯片温度传感器原则上可以用于冷端补偿但我的实际测量显示内部温度传感器读到的芯片封装温度和热电偶冷端所处的等温块温度之间还是有一些差异的忽略封装到冷端的温差可能引入 1℃ 以上的误差。所以我的做法是PCB 上放置一块铜质等温块把热电偶冷端接插件压在上面再用一颗 10k NTC 贴在同一个铜块上NTC 信号引到 ADS122U04 的另一个模拟输入通道。固件里先读 NTC 得到冷端温度再反推热电偶冷端电动势和热端电动势相加最后查表得到热端温度。对于要求不高的 HVAC 场合这样做冷端误差可以控制在 ±0.5℃ 内对于工业过程控制再把 NTC 换成 PT1000 贴铜块能进一步压低误差。2.3 激励电流、PGA 和参考电压的搭配计算选参数时我习惯先做一遍手算避免到现场抓瞎。以 PT1000 为例0℃ 时阻值 1000Ω100℃ 时 1385Ω。如果 IDAC 取 500μA传感器电压分别是 0.5V 和 0.6925V。参考电阻我选 3.6kΩ500μA 流过后产生 1.8V 参考电压。PGA 增益取 4则送至 ADC 内部的差分电压约 2V 到 2.77V没有超出 1.8V 参考对应的输入范围。等一下这里要说明一个容易搞错的细节ADS122U04 的模拟输入在 PGA 放大后信号电压必须满足 PGA 输出不超过 AVDD 范围同时 ADC 转换的满量程由 VREF 决定。如果 PGA 增益太大信号会被截断而不只是满量程溢出。PT1000 用 PGA4 已经足够RTD 信号大不需要用高增益。PT100 的阻值小500μA 电流下 0℃ 只有 50mV就需要 PGA8 或 16。转换结果和温度换算关系如下。24 位 ADC 输出是二进制补码正满量程对应 (2^23 - 1)。所以code ≈ (G × V_sensor) / V_ref × (2^23 - 1)PT1000 在 0℃ 时code ≈ (4 × 0.5) / 1.8 × 8388607 ≈ 9320673在 100℃ 时code ≈ 4 × 0.6925 / 1.8 × 8388607 ≈ 12970000 多一点。两点之间 code 差约 365 万换算成温度大约每℃ 有 3.65 万个 code分辨率远超需求。真正限制精度的不是 ADC 位数而是传感器本身的精度和参考电阻温漂。3. 原理图与 PCB 实战接线、供电、隔离和地线处理3.1 关键引脚连接与电源架构以我做的 8 路测温板为例硬件连接如下。信号器件目标引脚说明ADC 供电ADS122U04IPWRAVDD、DVDDAVDD 用 5VDVDD 用 3.3V参考电阻精密电阻 3.6kΩREFP、REFN并联 0.1μF 旁路电容传感器激励IDAC1接 RTD 正端500μA模拟输入AI0、AI1接 RTD 差分信号靠近引脚加 RC 滤波UART 发送PIC U1TXADC RXD3.3V 电平直连UART 接收PIC U1RXADC TXD3.3V 电平直连转换状态DRDY 引脚PIC 外部中断用于采集时序控制隔离通信PIC U2TX/U2RXRS-485 收发器Modbus 输出供电架构我分了三路5V 模拟电源给 ADS122U04 的 AVDD3.3V 数字电源给 DVDD 和 PIC24HJ256GP610。AVDD 用 5V 的原因很实际IDAC 需要有足够的输出电压余量。当激励电流流过传感器和参考电阻时IDAC 的输出端必须保持着一定的电压才能正常工作。数据手册里对 IDAC 的 compliance 范围有明确规定AVDD 低于这个范围时IDAC 电流会失真直接影响比例测量的精度。我最初图省事用 3.3V 给 AVDD实测 PT1000 在 300℃ 时读数明显偏低查了半天才发现是 IDAC 进入饱和区。DVDD 和 MCU 都是 3.3V所以 UART 电平直接兼容不需要电平转换。如果 DVDD 用 5V就必须在 UART 线上加电平转换芯片否则会损坏 PIC 引脚。3.2 工业环境下的隔离和防护隔离是本方案容易忽略却非常重要的一环。现场情况往往是传感器探头沿着管道走线几十米控制器在地控柜里两者之间电位差完全不可控。如果传感器信号直接进 ADC一次雷击浪涌或者电机启停的暂态就能打穿模拟前端。我推荐在 UART 接口处做数字隔离而不是在模拟输入处做隔离。原因很简单模拟隔离放大器成本高、精度损失大而 UART 隔离只需两颗数字隔离器比如 ISO7721带宽和信号完整性足够。隔离器的供电需要隔离电源模块把 5V 转换成隔离侧的 3.3V 和 5V。这样传感器、ADC 的模拟部分和 PIC 的数字部分就彻底分开了。PCB 布局上我把隔离器放在电路板中间模拟区和数字区在隔离器下方形成清晰的分界。模拟地 AGND 和数字地 DGND 在供电输入处单点连接隔离器两边分别供电不允许跨分割走线。对于温度测量这种低带宽信号这样处理地噪声完全够用。3.3 PCB 布局的几个具体坑第一参考电阻的位置很关键。它承载着整个系统的参考电压必须靠近 REFP 和 REFN 引脚走线要短旁边不能有高频数字信号穿过。参考电阻下方我铺了模拟地减少热电势影响。第二热电偶输入引线要尽量对称AI0 和 AI1 到接插件的走线长度一致形成差分对这样外界共模干扰可以互相抵消。第三电源去耦不能省AVDD 引脚处放 10μF 和 0.1μF 两个电容DVDD 引脚放 1μF。电容要靠近引脚过孔直接到地平面。还有一个 HVAC 项目特有的问题传感器端子附近常常有 220V 交流电源线。虽然隔离设计已经挡住了传导干扰但 PCB 上爬电距离不够的话潮湿环境下会漏电。所以我坚持在 ADC 模拟输入和接插件之间保持 2mm 以上的爬电距离并开漏锡槽。4. PIC24 固件UART 驱动、温度换算与故障判断4.1 UART 初始化与数据帧拼装PIC24HJ256GP610 的 UART 初始化比较固定。内部时钟选择 40MHz 指令周期 Fcy波特率 115200。代码如下#define FCY 40000000UL #define BAUD 115200UL void uart1_init(void) { U1MODE 0; U1BRG (FCY / (16UL * BAUD)) - 1; U1MODE 0x8000; // UARTEN, 8N1 U1STA 0x0400; // UTXEN } void uart1_write_byte(uint8_t b) { while (U1STA 0x0200); // UTXBF 等待发送缓冲空 U1TXREG b; } uint8_t uart1_read_byte(void) { while (!(U1STA 0x0100)); // URXDA 等待接收 return U1RXREG; }ADS122U04 的 UART 通信方式是立即响应型主机发命令器件回数据。读取转换结果的流程是先发 RDATA 命令然后连续读取 3 个字节拼成一个 24 位有符号整数。写配置寄存器的流程是发 WREG 命令带寄存器地址和数据。具体命令码和寄存器位定义必须对照 ADS122U04 数据手册命令表不同固件版本我做项目时也核对过不能凭记忆写死。有一个时序细节很值得注意ADS122U04 的 DRDY 引脚在转换数据准备好时会产生下降沿。我把它接到 PIC 的 INT 引脚外部中断触发后PIC 再发 RDATA 命令。这样避免了两类问题一是寄存器刚更新、转换未完成时读到中间态数据二是全速轮询时命令拥堵。由于两片 ADS122U04 共用一组 UART 的 MCU 是两个 UART不会冲突但如果你把两片 ADC 挂同一个 UART 做菊花链时序上就要格外小心。4.2 24 位数据拼装与 RTD 换算3 个字节拼成 24 位数据后由于是无符号字节流需要手动做符号扩展。XC16 的 int 是 16 位所以必须用 long。代码如下int32_t ads122u_read_code(void) { int32_t raw 0; uint8_t b0, b1, b2; // 发送 RDATA 命令 uart1_write_byte(ADS122U_CMD_RDATA); b0 uart1_read_byte(); b1 uart1_read_byte(); b2 uart1_read_byte(); raw ((int32_t)b0 16) | ((int32_t)b1 8) | b2; // 24 位有符号数最高位为符号位 if (raw 0x800000) raw | ~0xFFFFFF; // 符号扩展 return raw; }得到 code 之后结合比例测量的换算关系先还原电压再算电阻最后线性化。我的固件里维护了一个结构体保存每个通道的增益系数、偏移量和传感器类型这样 PT100、PT1000、热电偶可以通过配置切换。RTD 电阻计算如下float code_to_resistance(int32_t code, float gain, float vref, float idac) { float vin ((float)code / 8388607.0f) * vref / gain; return vin / idac; }这里的 vref 不是直接写 1.8V而是每次开机自检时读取参考电阻两端电压算出来的实际值进一步消除了参考电阻个体误差。热电偶的换算更麻烦一些需要把 code 还原成热端电动势查 NIST 多项式反演或查表再把冷端 NTC 读到的温度转换成冷端电动势相加。项目里我用的热电偶查表法是固件里放一张稀疏表线性插值。热电偶多项式有官方系数直接用就行。4.3 数字滤波与断线检测ADS122U04 的数据速率我设置为 20 SPS这个速率下 Δ-Σ 调制器的数字滤波器对 50Hz 工频干扰有较好抑制。但还要照顾到 HVAC 现场变频器产生的宽频噪声PIC 侧再加了一级一阶 IIR 滤波float iir_filter(float input, float prev, float alpha) { return alpha * input (1.0f - alpha) * prev; }alpha 取 0.3 左右实测在 20SPS 基础上再往下压读数非常稳定。不过滤波不能太狠否则温度变化时响应很慢HVAC 控制回路会出现滞后。我最终按通道需求区分风管温度用 0.3冷冻水温度用 0.5热电偶冷端 NTC 用 0.8因为它不参与快速过程。故障检测方面RTD 断线时输入悬空ADC 读数会趋向正满量程热电偶断线同理或者因为高阻输入耦合噪声而随机跳动。我在固件里做了阈值判断当换算出的电阻大于传感器上限的 110% 或小于 80% 时判定为断线或短路向上位机报故障状态。这个逻辑看似简单但实际项目非常需要因为大多数温度控制柜不配专职维护人员故障自诊断能省掉大量上门排查成本。5. 校准方法和实测数据到底能测多准5.1 室温下的两点校准和零点校准ADS122U04 虽然精度高但整个系统还有传感器误差、参考电阻误差、PGA 失调和引线电阻残留。要保证交付指标校准环节不能省。最简单实用的方法是两点校准。用精密恒温槽或干体炉提供 0℃ 和 100℃ 两个温度点分别记录传感器电阻换算值然后计算每个通道的增益修正系数和零偏。公式如下gain_fixed (R_100_true - R_0_true) / (R_100_measured - R_0_measured) offset_fixed R_0_true - gain_fixed * R_0_measured之后每次测量都用 R_corrected gain_fixed * R_measured offset_fixed。这一步对 PT100 尤其重要因为批量生产的引线电阻和 PCB 内阻不可能完全一致。校准数据我放在 PIC24 内部 Flash 指定的信息存储区上电时读取断线保护时也不丢失。额外提醒校准前要让板子通电稳定至少 15 分钟让板上温度场平衡。如果急着校参考电阻和 PCB 之间还存在热梯度校准结果会跟着环境温度漂移等于白校。5.2 实测误差对比我在实验室做了一组对比测试用 Fluke 温度校准仪作为参考分别测 PT1000 和 K 型热电偶结果如下。传感器设定温度参考值本板读数误差PT10000℃0.00℃0.02℃0.02℃PT100050℃50.00℃49.93℃-0.07℃PT1000100℃100.00℃100.08℃0.08℃K 型热电偶0℃0.00℃0.2℃0.2℃K 型热电偶60℃60.00℃60.3℃0.3℃K 型热电偶200℃200.00℃199.6℃-0.4℃PT1000 通道的误差主要来自传感器本身A 级 PT1000 在 0℃ 允许 ±0.15℃我们的板子加上 ADC 之后整体控制在 ±0.1℃ 量级符合 HVAC 和部分工业控制要求。热电偶通道误差大一些主要来源是冷端补偿的不完全但 ±0.5℃ 以内已经足够覆盖大多数工业现场毕竟热电偶本身精度多数是 ±1.5℃ 等级。5.3 实测中遇到的几个坑和解决记录第一坑是 UART 波特率偏差。PIC24HJ256GP610 用内部振荡器时精度大约 ±1% 到 ±2%这在普通 UART 通信中问题不大但 ADS122U04 对接收时序有一定要求波特率偏差过大时会出现偶发字节错误。现象是温度读数偶尔跳一个大值或者命令无响应。解决方法是改成外部晶振或者把 UART 波特率降到 38400留出更大的时序余量。我最终两个都做了外部晶振加 115200。第二个坑是 IDAC 电流在高温环境下的长期稳定性。比例式测量虽然消除了电流温漂的一阶影响但 IDAC 内部还有噪声电流源稍有波动会同时影响信号和参考不是完全抵消。实测中把板子放进 60℃ 恒温箱温度从 25℃ 上升到 60℃PT1000 通道漂移约 0.05℃。这个量级在产品规格书里可以接受。第三个坑最隐蔽热电偶输入引脚附近的数字走线耦合。一开始 DRDY 引脚的下降沿紧贴着模拟输入走线每次转换完成都会在 AI0/AI1 上引入一个毛刺导致热电偶读数周期性跳动 0.2℃。后来我把 DRDY 走线改到另一层并加了一个 1kΩ 串联电阻限制边沿速率问题消失。这种耦合问题在实验室里不明显一到现场电机启停、继电器吸合时就会被放大。6. 最后补充一点个人经验这套 ADS122U04IPWR 加 PIC24HJ256GP610 的组合我前后做了两个版本一个用在冷冻水温度采集一个用在工业加热炉的多点温度监测。整体感受是它比直接用集成式温变芯片复杂一些但灵活性大得多传感器类型、量程、滤波深度都可以在固件里改不需要改板子。如果预算允许硬件上值得多花十几块钱的地方有两个一个是参考电阻另一个是冷端补偿用的等温块。这两个看似不起眼的器件实际对整机精度的贡献比换一颗更高等级的 ADC 还要明显。固件上则建议预留通道校准参数不要写死在代码里直接存 Flash产线校准效率会高很多。最后一个小技巧调试 UART 通信时把 ADS122U04 的输出直接接到 USB 转 TTL 工具上用串口助手发命令看响应。先确认 ADC 侧的命令和时序没问题再连 PIC能省掉一半的联调时间。