24位ΔΣ ADC与ATmega644的UART测温方案:PT100热电偶NTC全解析 做温度采集有几年了经常遇到一种尴尬主控板已经定型MCU 是 8 位的 ATmega644处理器、通信、存储都够用偏偏测温精度上不去。尤其是在工业和 HVAC 这类场景里PT100、热电偶、NTC 混着来还要满足 0.1°C 级别的分辨力很多 MCU 自带 ADC 根本扛不住。我这次的折中方案是在不动主控的前提下用 TI 的 ADS122U04IPWR 这颗 24 位 ΔΣ ADC 挂到串口上把传感器信号在 ADC 附近数字化通过 UART 把数据送回 ATmega644。这篇文章就围绕这套组合把传感器怎么接、固件怎么写、现场会踩哪些坑一次说透给正在做工业采集、楼宇自控、制冷机组控制的工程师参考也适合刚接触 RTD 和热电偶的硬件朋友。1. 为什么是 24 位外挂 ADC 8 位 AVR这组搭配解决的问题1.1 工业与 HVAC 测温的真实需求不止是“测个温度”先说说工业现场的真实情况。很多朋友以为 HVAC 测温就是采集一下室温精度差不多就行但真正做机组控制和节能调优时完全不是这个量级。我改过一批恒温恒湿机组温控精度要求 ±0.3°C传感器装在送回风道里控制柜却离风道十几米远。这时候如果直接靠 MCU 内置 10 位或 12 位 ADC量化噪声、参考电压漂移、线路压降叠加起来别说 0.3°C能稳定看出 1°C 变化就不错了。这个场景里温度测量链路其实很清晰传感元件先把温度变成电阻或电压再经过信号调理和 ADC 变成数字量最后由 MCU 汇总并通过 RS-485 或者网络送出去。链路越长误差源越多所以需要在源头就把模拟信号质量处理好。工业与 HVAC 场景常见的三类传感器各有各的脾气我把它们的基本特性整理了一下传感器类型典型温度范围输出信号灵敏度适用场景成本PT100 / PT1000 热电阻-200°C 850°C电阻变化约 0.385 Ω/°C冷冻水、风管、机组轴承中等K 型热电偶-200°C 1300°C微伏级电压约 41 µV/°C烟道、压缩机排气低NTC 热敏电阻-40°C 150°C电阻变化高温区高灵敏度室温补偿、板级测温很低这三类传感器对 ADC 的要求完全不同。PT100 需要恒流激励和四线或三线制接线热电偶输出微伏级电压需要高增益 PGANTC 虽然简单但非线性严重。而 ADS122U04IPWR 这颗芯片正好把这些都收进去了所以拿它做前端MCU 的压力会小很多。1.2 ADS122U04IPWR为什么一眼看中这颗外挂 ADCADS122U04IPWR 本质是一颗低功耗、四通道、24 位 ΔΣ ADC但它跟普通 ADC 最大的不同是接口是 UART。这里有个容易被忽略的优势在有变频器、继电器、电磁阀的 HVAC 配电柜里模拟信号走长线是件很痛苦的事。变频器一启动几毫伏的传感器信号已经淹没在共模噪声里。而 ADS122U04IPWR 把模拟转换直接放在传感器侧的采集板卡上通过 UART 把数字结果送到主控这就等于把模拟链路缩短到了厘米级抗干扰能力完全不一样。这颗芯片内部集成的资源也很关键。它自带两路匹配的电流源专门用来激励 RTD不需要额外设计恒流源电路内部 PGA 增益最高可以到 128热电偶那点微伏级信号也能直接处理还内置了温度传感器配合外部热电偶做冷端补偿。分辨率 24 位数据速率最高 2 kSPS工业级温度范围这些指标对 HVAC 应用来说是绰绰有余的。后缀里还有信息I 代表工业级温度范围PW 是 TSSOP-16 封装R 是卷带包装。选型时我比较看重 IPWR 的卷带封装贴片线可以直接吸放产线效率高而且工业级温度范围意味着芯片放在没有空调的配电柜里也不至于热死机。采购上注意一点这类料常见的渠道主要是代理商或者正规分销商别只看单价要盯着供货周期和最小起订量工业项目最怕中途断料。1.3 为什么还守着 ATmega644 不放很多人问我既然要上高精度 ADC为什么不干脆换一颗带硬核高精度采集的 ARM 或者专用 SoC。道理很简单换主控意味着整块 PCB 重画、bootloader 重移植、现场运行的老代码全部重测而且控制逻辑、通信协议、历史标定数据都要跟着迁这个工程量远大于“在侧边加一颗 ADC”。ATmega644 本身并不落后它恰到好处。64KB 闪存、4KB SRAM、2KB EEPROM能存下整套查表校准数据和通信协议栈主频 20MHz做 Modbus RTU 从机、PID 控制都够用宽温工业级成本便宜供货稳定。最关键的是它有两个独立 USART一个专门跟 ADS122U04IPWR 通信另一个接 RS-485 总线上传数据两个通道互不干扰。如果换单串口的 MCU就得用软件模拟串口既占用定时器又容易丢数据完全没必要。所以我的结论很明确ADC 性能不够就外挂一个高精度 ADC不要轻易推翻整个主控方案。ADS122U04IPWR 负责把传感器电压变成可靠的数字量ATmega644 负责业务逻辑和通信各干各的活这也是工程里最常见的做法。2. 传感器接线与原理RTD、热电偶、热敏电阻怎么接2.1 PT100 三线制的比例式测量PT100 的温度测量最讲究因为它本身就是个电阻而电阻变化量很小。0°C 时是 100Ω100°C 时是 138.5Ω整个往大了说也就几十欧姆的差别。如果只靠一根电阻分压线缆电阻随便就串进去几欧姆温度误差直接几度。所以工业上做 PT100 现场测量用三线制或者四线制。我实际用的方案是比例式测量同时把电流源和参考电阻都用起来接线逻辑如下第一路电流源 I1 激励 PT100电流流经热电阻后在 AIN0 和 AIN1 之间产生差分电压第二路匹配的电流源 I2 流过外部精密参考电阻 RREF在 REFP 和 REFN 之间产生参考电压ADC 测量的是 AIN0-AIN1 的电压与 REFP-REFN 电压的比值而不是绝对电压。这样做的好处是电流源的绝对值不会影响最终结果。假设 I1 和 I2 都是 1mAPT100 在 0°C 时产生 100mV 电压RREF 选择 2kΩ参考电压就是 2VADC 输出码值大约是100mV / 2000mV × 2^23 ≈ 419430到了 100°CPT100 变成 138.5Ω电压变成 138.5mV码值变成138.5mV / 2000mV × 2^23 ≈ 580862差值是 161432 个码对应 100°C也就是说每个码大约对应 0.00062°C。这个分辨力做 0.1°C 的读取绰绰有余。就算电流源温度漂移I1 和 I2 的匹配性在芯片内部做得很好比例关系基本不变只有 RREF 的温漂会影响全局所以 RREF 一定要选低温漂精密电阻我一般用 25ppm/°C 以下的薄膜电阻有条件就用 5ppm 的。三线制真正要解决的问题是导线电阻。PT100 两根引线会在电流回路里引入额外电阻导致信号电压偏高。三线制的接法常把一根引线放在激励回路里另外两根引线承担检测电压再结合差分输入和匹配电流源可以在很大程度上抵消引线电阻的影响。想做到极致就上四线制但 HVAC 现场通常没有太多空间三线制加上合理的线径就够用了。还有一个容易忽略的坑是自热。1mA 电流在 200Ω 电阻上就是 0.2mW 发热量对小体积的薄膜 PT100 来说这会让读数略微偏高。低功耗场合可以把激励电流降到 250µA 或 500µA但代价是 ADC 输入信号变弱对噪声更敏感。我一般常态用 500µA这是四五线制 RTD 采集里比较平衡的选择。2.2 热电偶低电压信号与冷端补偿热电偶跟 RTD 完全不同它输出的是电压而且是微伏级的电压。K 型热电偶灵敏度大约 41µV/°C即便测 1000°C 高温总电压也只有 40 多毫伏。这样的小信号必须经过 PGA 放大才能被 ADC 合理利用。ADS122U04IPWR 的 PGA 增益最高 128我常用增益 32因为 32 倍放大后 50mV 输入变成 1.6V可以落入 2.048V 参考电压的最佳利用区间。使用热电偶时冷端补偿是最大的误差来源。热电偶测出来的是热端和冷端的温度差不是绝对温度。想得到真正的热端温度必须知道冷端温度并且在软件里加补偿。ADS122U04IPWR 内置了温度传感器可以直接读芯片附近的环境温度理论上可以做冷端补偿。但实际现场里有个典型问题采集板放在电控柜里芯片自身发热明显板内温度和传感器端子处的冷端温度可能差三五度如果直接拿芯片内部温度做补偿偏差会很大。我在工程里的做法是冷端位置放一个外部 NTC 或 PT100紧贴着热电偶的接线端子再用这颗外部传感器测到的温度做补偿。校准点选在室温附近例如 25°C 时 K 型热电偶的参考电压大约是 1mV 左右如果补偿误差 1°C对应 41µV 的电压误差所以冷端补偿做准了整套系统才能谈高精度。2.3 NTC 热敏电阻的接入NTC 接线最省事但也不能随便接。常用 10kΩ NTCB 值 3950分压电阻也选 10kΩ电源用 3.3V只要把分压点接到 ADC 的单端输入就能读到随温度变化的电压。它的优点是灵敏度很高在 25°C 附近温度每变化 1°C电阻会变化几百欧姆比 PT100 敏感得多做恒定室温传感很合适。缺点是线性度差。从 -20°C 到 100°C电阻值跨越几个数量级直接用线性公式会出错。固件里应对办法是查表把温度-电阻关系做成 1°C 间隔的表查表后做线性插值。也可以用公式计算T 1 / ( ln(R / R0) / B 1 / T0 ) - 273.15其中 R0 是 25°C 时的 10kΩT0 是 298.15K。公式在 -10°C 到 80°C 范围内已经足够准。NTC 本身发热极小但为了保险最好只在采样瞬间给分压电路供电采样完就关掉避免长时间激励引起自热漂移。3. 固件实现ATmega644 与 ADS122U04 的 UART 通信3.1 硬件连线、波特率与数据帧ADS122U04IPWR 的 UART 接口让我省了不少事它不需要 SPI 的时钟线也不需要精确的片选时序只要把 MCU 的 TX 接到芯片的 DINDOUT 接到 MCU 的 RXDRDY 接到一个普通 GPIO 就可以。如果两边电压域不一致可能需要加电平转换但在 3.3V 系统里可以直接连。我习惯把 DRDY 接到 ATmega644 的外部中断脚平时靠查询也行。DRDY 变低代表一次转换完成数据准备好。用查询方式写代码最简单但对实时性要求高的场合外部中断更稳妥尤其是有多路采集任务时省得像轮询一样傻等。波特率我一般设 9600工业现场的长线传输下这个速率比较稳。ADS122U04IPWR 的 UART 是自定时恢复式的对主机波特率精度要求比普通 UART 严格所以要用精确的晶振或者稳定的内部时钟源别用 RC 振荡器跑高速串口否则偶尔会出乱码。协议上就是标准的 8-N-1 数据帧主机发命令从机回数据。3.2 初始化、配置命令与读码流程ATmega644 的 USART0 初始化很简单算波特率寄存器值时要注意公式是 UBRR F_CPU / (16 × BAUD) - 1。下面的代码骨架是我常用的一套ADS122U04 的配置寄存器映射和命令字节格式具体请以你手头器件的数据手册为准但整体命令风格就是“写寄存器”和“读转换结果”两大步。/* 文件名 ads122u04_drv.c基于 ATmega644 */ #define ADS_BAUD 9600UL #define ADS_DRDY_PINR PINB #define ADS_DRDY_BIT PB1 void uart0_init(void) { UBRR0L (uint8_t)((F_CPU / (16UL * ADS_BAUD)) - 1); UCSR0B (1 RXEN0) | (1 TXEN0); UCSR0C (1 UCSZ01) | (1 UCSZ00); /* 8N1 */ } uint8_t uart0_rx(void) { while (!(UCSR0A (1 RXC0))) ; return UDR0; } void uart0_tx(uint8_t d) { while (!(UCSR0A (1 UDRE0))) ; UDR0 d; } /* 写配置寄存器命令字节通常由写命令标志和寄存器地址构成 */ void ads122u04_write_reg(uint8_t reg_addr, uint8_t val) { uart0_tx(0x40 | (reg_addr 1)); /* 具体编码见手册 */ uart0_tx(val); _delay_ms(1); /* 等命令执行完 */ } uint32_t ads122u04_read_code(void) { uint8_t b[3]; /* 等待DRDY拉低单次转换完成 */ while (ADS_DRDY_PINR (1 ADS_DRDY_BIT)) ; /* 如果是主机读模式这里先发读命令自动发送模式则直接收3字节 */ b[0] uart0_rx(); b[1] uart0_rx(); b[2] uart0_rx(); return ((uint32_t)b[0] 16) | ((uint32_t)b[1] 8) | b[2]; }配置寄存器时我不建议凭记忆硬填位值因为 ADS122U04 和 ADS1220 系列寄存器地址在不同批次手册里描述方式稍有出入厂商文档最准。需要确认的配置项主要有这几个输入多路复用选择、PGA 增益、数据速率、电流源大小和输出引脚、参考电压来源、内部温度传感器是否开启。以 PT100 为例我会这样组织配置/* 伪代码式的配置结构实际应转换为寄存器位域 */ ads_config_t cfg { .mux ADS_MUX_AIN0_AIN1, /* 差分输入 */ .pga ADS_PGA_8, /* 增益8配合RTD小信号 */ .drate ADS_DR_20SPS, /* 20次/秒滤波效果更好 */ .idac ADS_IDAC_500uA, /* 500uA激励 */ .idac_to ADS_IDAC_AIN2, /* 电流源从AIN2流出 */ .vref ADS_VREF_EXT_RREF, /* 外部RREF参考电压 */ }; ads122u04_apply_config(cfg);20SPS 的数据速率在大多数 HVAC 场景里完全够用而且 ΔΣ ADC 在低速率下数字滤波更强有效分辨率更高。不要一上来就追求 2kSPS那会引入更多噪声温度这类缓变量根本不需要那么快。3.3 转换为温度值比例关系、查表和滤波读回来的 24 位码值本身不是温度要经过换算。对 PT100 的比例式接法关系非常简单RTD电阻 (ADC码值 / 2^23) × (RREF / PGA增益)换算成代码就是double r_pt100 ((double)code / 8388608.0) * 2000.0 / 8.0;算出的电阻值再查 PT100 分度表就能得到 0.1°C 精度的温度。分度表我不建议在代码里存太细1°C 间隔的整数表配合线性插值就够查表时间远小于一次 ADC 转换时间MCU 完全转得过来。读回来的原始值免不了有随机噪声尤其是环境温度稳定时你会看到末位码值跳来跳去。处理办法是滑动平均或一阶低通滤波。一阶低通最简单/* 一阶低通alpha0.2 对0.5Hz信号合适 */ filtered filtered alpha * (sample - filtered);alpha 越小越平滑但响应也越慢。空调风管温度本身变化就慢alpha 取 0.1 到 0.3 问题不大。需要注意的是一开始要把 filtered 初始化成第一次采样值否则启动阶段会有很长的爬坡过程。4. HVAC 现场实测噪声、漂移与通信异常排查4.1 读数跳动的排查先查电源和参考别急着怪 ADC现场调第一版时我最常遇到的现象是温度读数在稳定环境下每秒跳 0.3°C 左右看着就让人头大。很多人第一反应是 ADC 性能不行其实 24 位 ΔΣ ADC 的量化能力强得很跳动多半是外围电路喂给它的信号脏了。我的排查顺序是先看电源。ADS122U04IPWR 的 AVDD 和 DVDD 必须分开滤波最好用 LDO 供电别直接拿 DC-DC 的输出怼否则开关噪声会窜进模拟部分。每个电源引脚旁边放 0.1µF 陶瓷电容再并联 10µF 钽电容或者多层陶瓷电容这在数据手册里有明确建议。参考电压引脚上的电容也至关重要如果用的是外部 RREF一定要在 REFP 和 REFN 之间放一个低 ESR 电容把参考电压上的高频毛刺滤掉。然后是传感器线缆。风道里的 PT100 线缆如果和变频器输出线捆在一起走线槽变频器一启动感应噪声直接灌进来。解决办法是改用屏蔽双绞线屏蔽层单端接地并且布线时和动力线保持至少 30cm 的距离。我在现场做过对比把线缆移开 30cm 并把屏蔽层接好之后读数跳动从 0.3°C 降到了 0.05°C 以内效果立竿见影。4.2 冷端补偿漂移的真相热电偶冷端补偿是现场最容易翻车的点因为问题非常隐蔽。有一段时间我发现某台机组的 K 型热电偶温度白天偏正、晚上偏负而且偏差幅度跟机组负荷强相关。检查了热电偶本身没有问题后来才想到是采集板放在电控柜的发热元件旁边板温变化和传感器接线端子的实际温度差十几度而冷端补偿还在用 ADC 内部温度传感器的读数。这个问题的本质是冷端温度测量点和实际冷端位置不在同一个热质量块上。要解决最靠谱的办法是让冷端基准点物理上靠近传感器端子并且在电气上用一块均温铜块或者铝块把热电偶端子、补偿 NTC 和大地热容连在一起让它们温度一致。软件上再对补偿传感器做一次两点标定。如果条件受限至少也要选热容量大、离发热器件远的安装位置。4.3 UART 偶发乱码接线、波特率和地电位差UART 通信偶尔会冒出来 FF 或者 00 这类僵值测量结果直接跳成最大值或最小值。我排查过几次最常见的三个原因分别是线接错、波特率偏差和地电位差。线接错好办示波器一挂看波形就知道。波特率偏差的问题则比较隐蔽ATmega644 用内部 RC 时钟时如果没做校准误差可能在 1% 到 3% 之间串口长时间传输会积累位错误。我的建议是尽量用外部晶振或者先把内部振荡器校准到 1% 以内。地电位差是工业现场的大坑。控制柜里的 MCU 和传感器采集板如果接在不同的接地点两个地之间可能有几十毫伏甚至几百毫伏的电位差导致 UART 的收发电平飘移轻则偶尔乱码重则完全不通。解决手段是掉到 9600 波特率这样每个 bit 的时间窗口足够大容错能力自然高如果距离超过一两米最好在 UART 线上加隔离可以用数字隔离器或者直接把采集板做成独立的 RS-485 从站整个链路走差分信号。实际改造中我经常采用后一种做法因为 RS-485 同时解决了抗干扰和长距离传输两个问题。5. 工程化落地布局、校准与扩展思路5.1 PCB 布局与保护细节决定稳定性ADS122U04IPWR 这种高精度 ADC 对布局比较敏感但也不需要把模拟和数字完全掰成两个板子。几个关键点做到位效果就很稳。模拟地和数字地最好在芯片下方单点相连不要在其他地方乱铺回路。模拟电源和数字电源的走线分开并在芯片引脚处就近放滤波电容。输入信号线尽量短而粗给传感器端子留出的走线避免和数字信号线平行。RTD 的参考电阻 RREF 要放在远离发热元件的位置最好和 RTD 激励电流路径对称减小温度梯度引起的误差。输入保护也不能省。HVAC 现场传感器线缆可能和 220V 动力线在同一个桥架里一旦绝缘损坏高压窜进来会把芯片打坏。我的做法是在 ADC 输入引脚前加串联电阻限流再加 TVS 管或者钳位二极管到电源轨。这样即使受到感应冲击大多数情况下只是二极管导通芯片能保住。5.2 两点校准比单纯换更高精度器件更划算绝对精度不是靠堆硬件实现的出厂标定同样重要。ADS122U04IPWR 芯片本身的增益误差和偏移误差在手册里都有指标但实际 PCB 上的电阻、接线、焊接都会引入额外误差。所以每一块采集板在出厂前都应该做两点校准。校准时用精密电阻箱接在传感器端子上分别模拟两个已知温度点比如 0°C 对应的 100Ω 和 100°C 对应的 138.5Ω读出 ADC 输出后计算出增益系数 K 和偏移量 B把这两个参数写进 ATmega644 的 EEPROM。正常工作时用校准后的线性公式做修正。这个方法对 PT100 和热敏电阻都适用做完之后整条测量链路的误差就能从“器件手册标称值”压缩到“电阻箱精度量级”比盲目追求更高规格 ADC 有效得多。5.3 扩展多通道采集与 RS-485 从站如果现场不只一路温度ADS122U04IPWR 本身有四个输入通道可以接成两路差分或者四路单端直接满足小规模采集。要是通道数量更多可以再加模拟多路开关或者简单粗暴一点一块 ATmega644 搞定六到八个通道然后多块采集板挂到 RS-485 总线上由中央控制器统一读取。我在 HVAC 项目里一般把 ATmega644 配置成 Modbus RTU 从站ADC 采集到的温度写入保持寄存器上位机组态软件通过 03 功能码直接读取。这样既保持了采样同步性又让系统扩展变得简单现场要加温度点了接一块新板设置好站号上位机配几个寄存器就行不用改主程序。隔离方面RS-485 收发器前加数字隔离器电源用隔离 DC-DC整套系统在现场的可靠性会高一个台阶。温度测量在工业和 HVAC 领域看起来是个基础功能但真要做到稳定、精准、可维护牵涉到传感器接线、ADC 配置、固件算法和现场布线的方方面面。对我来说这套 ADS122U04IPWR 加 ATmega644 的组合最值得推荐的地方是它用一颗外挂 ADC 解决了主控性能瓶颈同时保留了原有固件体系的稳定性。你在做类似项目时与其纠结要不要换主控不如先想想能不能用一颗合适的 ADC 把问题在源头解决掉。最后分享一个个人习惯每个通道的标定参数、线缆长度、传感器类型我都会写在一个配置文件里存进 EEPROM现场换传感器时直接通过串口命令重新校准省了很多售后维护的功夫。这个思路用到你的项目里应该能少跑几趟现场。