
1. 为什么是 UART 串口 ADC 加 PIC18F这不是偶然1.1 工业现场里 SPI 的处境你应该深有体会之前帮朋友调试一个 HVAC 水系统的温度采集板现场反馈数据老是跳。板子上用的是常规 SPI 接口的 24 位 ADCMCU 和 ADC 之间就一根 PCB 走线长度不到 5 厘米按理说不会有什么问题。但现场旁边就是变频水泵走线一靠近功率驱动部分转换结果就明显抖动。后来换了带隔离的改法成本直接上去一截。工业现场和干净的实验室环境完全是两回事。SPI 接口看起来很快但它的时钟线、数据线、片选线对走线长度和干扰都比较敏感距离一拉长就要考虑信号完整性真要加隔离至少得隔离四条线光耦也好、数字隔离器也好成本和时间都翻倍。UART 就不一样了点对点两根线TX、RX天生就是为远一点、简单一点设计的。再加上 UART 本身有起始位、停止位做帧同步哪怕中间有毛刺干扰只要波特率误差在容限内数据基本不会错。ADS122U04IPWR 的思路很有意思它把 24 位 Δ-Σ ADC 和 UART 通信接口做在一起。在仪表行业干久了你就知道高精度 ADC 带串口这种组合很少见。常规高精度 ADC 几乎全是 SPI 或者 I2C串口版本的选项并不多。ADS122U04 的出现让模拟前端 MCU之间的连接直接从四线降成两线隔离也只需要两个通道。这一条放在工业或者 HVAC 现场价值比多几个采样率选项实在得多。1.2 PIC18F96J65 在这个方案里扮演什么角色PIC18F96J65 属于 Microchip 的 PIC18F 增强型系列。你可能更熟悉 PIC18F4620 或者 PIC18F27K42这一颗的定位和它们类似属于老牌、成熟、供货稳定的 8 位 MCU 家族。做温控项目选 PIC18F图的就是它的工程生态——编译器成熟、下载调试器便宜、参考代码多、工程师上手门槛低。很多做暖通自控、工业仪表的公司产品线里几十年如一日用着 PIC18F 系列这不是情怀是维护成本和供应链稳定性的现实考虑。在这套方案里PIC18F96J65 要干的事很聚焦通过 UART 和 ADS122U04 通信把转换结果读出来再做温度换算、滤波、越限判断最后通过另一路串口或者 RS-485 把数据送上位机。它不需要碰模拟信号那是 ADC 的本职工作也不需要算复杂的浮点多项式更重的换算可以根据工程需求放到上位机或者干脆用查表法解决。有人会问PIC18F 的频率不算高跑得动吗答案是够用。ADS122U04 的采样率最高可以到 120SPS 左右实际受滤波配置影响这个量级的通信频率对任何一个 PIC18F 来说都是绰绰有余。真正费时间的是控制逻辑、报警处理、通信协议这些恰恰是 PIC18F 的老本行。1.3 两颗芯片的分工本质上就是模拟与逻辑的分工把这套电路看成一个团队就清楚了。ADS122U04 是模拟前端专家它负责把热电偶的微伏级信号、PT100 的毫伏级变化通过 PGA 放大、24 位 Δ-Σ 调制、数字滤波变成一串可靠的数字码。PIC18F96J65 则是逻辑中枢它不管信号有多微弱只管把数字码读进内存、按协议换算、再按通信协议发出去。这种分工最大的好处是各干各的、各擅所长。模拟部分由一颗专用芯片完成信号链路很清晰。而且 ADS122U04 内部集成了精密电流源、故障检测和内部温度传感功能相当于把模拟前端的外围配套也一起打包了。MCU 这边则完全不用关心模拟细节软件架构清爽很多。尤其要注意的是PIC18F96J65 和 ADS122U04 之间用 UART 连接天然具备异步隔离的潜力。你需要做电气隔离时两个 UART 信号线之间随便插一对数字隔离器或者光耦就完了不需要像 SPI 那样处理时钟同步问题。这一点在工业现场意义重大——很多温度采集板最终都要过认证隔离方案越简单PCB 改版次数越少。2. 温度传感器前端电路决定精度的往往不是 ADC 本身2.1 热电偶输入小信号放大、共模范围和冷端补偿热电偶为啥难测因为信号太小。K 型热电偶的灵敏度大约是 41μV/°C也就是说温度变化 1°C输出电压才变几十微伏。室温下测 0 到 100°C 的变化满量程也只有 4mV 左右。这要求 ADC 的前级增益必须足够大。ADS122U04 的可编程增益最高可以到 128 倍配合 24 位分辨率理论上能分辨微伏级别的电压变化这也是这类高精度 Δ-Σ ADC 的核心价值所在。信号小还有一个容易被忽略的问题共模输入范围。很多人只盯着增益忘了查 PGA 的输入范围。ADS122U04 的 PGA 输入端要求信号电压落在合理的共模范围内如果热电偶的一根线接地、另一根线上叠加了明显的共模噪声即使差分信号正确转换结果也可能出现非线性甚至完全错误。实际接法上我曾经踩过坑热电偶负端直接接 AGND结果在电机启动瞬间读数乱跳。后来改成用分压电阻把输入共模抬高到电源中间电位附近问题立刻消失。所以热电偶输入端不该简单地负极接地要留出共模偏置的余量。冷端补偿CJC也是热电偶测量绕不开的环节。ADS122U04 内部有一个温度传感器很多初学者第一反应是直接用它的读数做冷端补偿。经验上我不推荐这么干原因有两点第一芯片自身会有发热芯片温度并不等于热电偶端子处的实际温度第二热电偶接线端子在 PCB 边缘和芯片之间隔着走线、铜皮温差在冷热交替的环境下可能达到好几度这对温度精度是致命打击。稳妥的做法是在端子附近放一颗 NTC 热敏电阻或者 PT1000紧贴热电偶冷端用 ADC 的一个辅助通道去测它再结合查表做补偿。2.2 RTD 输入内置 IDAC 电流源和三线制接法RTD热电阻是 HVAC 里更常见的传感器PT100、PT1000 用得最多。RTD 的测量原理简单粗暴给电阻通一个已知电流测它两端的电压再反算电阻和温度。这里面最大的敌人是导线电阻。两颗螺丝端子之间的引线如果长了导线电阻本身就有几欧姆PT100 在 0°C 时只有 100 欧姆导线电阻带来的误差占比非常大。解决思路有三种两线制最简单但精度最差四线制最准但要多拉两根线现场成本高三线制是工业标准做法用两路相同的激励电流分别流过传感器和参考路径只要两条导线电阻相等误差就能互相抵消。ADS122U04 内部集成了两个精密 IDAC 电流源正是为三线制、四线制 RTD 测量准备的。设计时让 IDAC1 给传感器提供激励IDAC2 给参考电阻提供同样的电流再用差分输入去测传感器上的电压降导线的压降就被排除了。选参考电阻也有讲究。RTD 的测量最好做成比率式ADC 的参考电压取自同一个激励电流流过精密参考电阻产生的压降。这样即便电流源有微小的温漂和波动激励电流和参考电压同步变化最终转换结果基本不受影响。这个技巧是仪表设计里非常经典的做法能省掉很多标定的功夫。2.3 前端滤波与保护别让 TVS 管毁了你辛辛苦苦测的小信号任何一个从外面接传感器的端口都要考虑 ESD、浪涌和射频干扰。热电偶线可能长达几十米就像一根天线把变频器、电机、无线对讲机的干扰全收进来。常规做法是在输入端串 RC 低通滤波器再接 TVS 管或者瞬态抑制二极管。RC 滤波器的截止频率要结合 ADC 的数据速率来定。ADS122U04 内部有数字滤波对外部模拟 RC 的要求是能抑制高频噪声、避免混叠就行。RC 时间常数太大反而坏事它会拖慢信号建立时间在通道切换或传感器断路恢复时要等很久数据才能稳定。一般工程上取几 kΩ 电阻加 100nF 到 1μF 电容的组合兼顾滤波和响应速度。TVS 管要注意漏电流问题。普通 TVS 管在低压下也有微安级的漏电流热电偶源阻抗低还好要是接高阻传感器或者小电流激励的 RTD漏电流会在测量回路上产生不可忽视的电压。高精度、高阻场景下要么选漏电小的专用 TVS要么加大 RC 串联电阻限定漏电流路径。这种细节模拟仿真是看不出来的只有整机测试才能暴露。3. 从串口链路到固件实现ADS122U04 通信协议怎么看3.1 命令帧、数据帧和主发字节才能读数据的机制ADS122U04 的 UART 接口和我们平时用的 ASCII 串口协议不太一样。平时我们用串口通常是一来一回、一问一答。ADS122U04 则更接近 SPI 的思维方式帧同步完全靠主机。MCU 发给 ADC 的每一个字节不仅是命令还为 ADC 的数据输出提供移出时钟。换句话说你要读 ADC 的数据就得主动往串口发字节ADC 会随着你的发送过程把数据一位一位送出来。这个机制看起来绕但实际用起来很顺手因为它意味着接收缓冲区永远不会被堆满你只要按节奏问它就按节奏答。命令帧的长度是固定的一般三字节起底。第一字节是命令码第二、三字节带有地址、寄存器数据或者校验信息。具体每个命令码对应什么操作务必以官方数据手册中UART Command章节的时序为准不同批次芯片的寄存器映射也可能有差异。我的习惯是先把数据手册里给出的时序图翻译成一张状态表发送什么字节、期望接收什么字节、什么时候需要等待、什么时候算超时写驱动时对着表逐行填代码比对着英文时序文档写靠谱得多。读取转换数据时主机会先发读数据命令然后连续发送四个字节时钟具体数量视数据帧长度而定通常为状态字节加 24 位数据共 32 位。ADC 在接收到时钟字节的同时从 DOUT 引脚逐字节送出数据。MCU 端 UART 接收中断收到的内容按顺序拼装成一个 32 位的整型变量再拆出状态位和有效数据位。整个过程其实就是每发一个字节就接收一个字节逻辑上并不复杂。3.2 寄存器配置增益、通道、数据速率、参考源ADS122U04 的配置寄存器大概分为几块输入多路开关选择MUX、PGA 增益、数据速率/滤波模式、转换模式单次/连续、参考电压来源以及 IDAC 电流设置。对温度测量来说这些配置寄存器怎么填取决于前端传感器类型我把常用的搭配整理成了下面的对照表配置项热电偶K 型PT100 三线制PT1000 两线制PGA 增益32 或 64信号小8 或 164 或 8MUX 通道差分通道接热电偶两端差分通道跨 RTD差分通道跨 RTDIDAC 电流关闭250μA 或 500μA250μA参考源外部基准1.65V~2.5V外部基准电阻外部基准电阻数据速率20SPS 或更高20SPS20SPS需要说明的是上表只是工程上的起点具体位域值要以你拿到的数据手册中的寄存器位定义为准。配置寄存器通常支持写后读回验证固件初始化里建议把关键寄存器内容读回来比对防止因波特率误码导致配置写错。我碰到过一个案例就是初始化阶段偶发一位错误把 MUX 通道写歪了导致明明接的是 1 通道读到的却是 3 通道的数据排查了很久才怀疑到寄存器配置上。3.3 状态字节、故障位和数据有效判断转换数据的第一个字节是状态字节里面藏着很多调试时有用的信息。比如过载状态位、内部温度传感器状态、PGA 饱和标志等。写驱动时千万别把状态字节丢掉只取后 24 位就当温度算。正确的做法是先做状态字节检查如果发现 PGA 饱和或者输入过载就要认为本次数据无效将结果丢弃并置一个故障标志等下一个转换周期重新读取。这里还要说一个数据过期的问题。有些项目把 ADC 配置成连续转换模式MCU 这边 100ms 读一次但 ADC 实际已经转了更多的数据你读到的可能只是缓冲区里的最新值。如果 PID 控制算法要求严格的采样间隔建议使用单次转换模式每次需要数据时先发触发命令等待 DRDY 信号ADS122U04 支持通过 DOUT/DRDY 引脚指示转换完成再读数据。虽然多了等待时间但数据的时间戳是可控的控制算法不会因为数据节奏不均匀而抖动。4. 从原始码算成温度算法细节与实测校准4.1 先把数字码换算成电压值ADS122U04 是 24 位 ADC输出是二进制补码格式。换算公式并不复杂电压值 (原始码 / 2^23) × (参考电压 / PGA 增益)举例来说如果参考电压是 2.048VPGA 增益是 32原始码读到 0x4000008388608那么电压大约是 (8388608 / 8388608) × (2.048 / 32) 0.064V也就是 64mV。注意式子里分母是 2^23 而不是 2^24因为 24 位补码的满量程对应正负半个参考电压换算时要把符号位考虑进去。写代码时要把这个计算放在 float 或者足够宽的定点数环境里执行PIC18F 上如果用 8 位单片机做浮点计算会慢一些但温度采样本来就不是高速场景几百毫秒才算一次浮点性能完全够用。如果想提速可以先把参考电压/PGA增益这个系数算成常量每次换算就是一次乘法和一次移位。4.2 热电偶温度换算查表法比多项式更适合 MCU从电压反推热电偶温度正经做法是用 NIST 多项式。K 型热电偶的多项式系数一长串从 -200°C 到 1370°C 分成多段每段系数都不同。在 PC 上跑这没问题但塞进 PIC18F 里代码空间和浮点计算量都不太好看而且系数表本身也容易抄错。工程实践中我更推荐分段查表法在程序里内置一张电压-温度对照表从 -200°C 到 1300°C 每隔 10°C 一个点运行时先用线性插值求出精度达到 0.1°C 的温度值。查表法的好处是逻辑透明、依赖少而且表格可以用脚本从 NIST 数据自动生成不会有人工抄写的误差。热电偶的完整测温流程是读取 ADC 原始码换算成热电偶回路的总电压 V_total。读取冷端温度 T_cj来自板载 NTC 或 PT1000。查表得到 T_cj 对应的热电偶电势 E_cj。计算热端电势 E_hot V_total E_cj。用 E_hot 查表反查热端温度 T_hot这就是最终被测温度。很多人漏掉的就是第 3、4 步。如果环境温度变化不大你可能感觉不出来但 HVAC 现场一年四季温差几十度不加冷端补偿的读数偏差会大到完全不可用。4.3 RTD 的 Callendar-Van Dusen 换算和线性化PT100 的温度-电阻关系用 Callendar-Van Dusen 方程描述正温段比较简单R(T) R0 × [1 A×T B×T²]其中 R0 是 0°C 时的标称阻值PT100 就是 100ΩA、B 是常数。反推温度就是解这个一元二次方程代码里用求根公式就能搞定。工程实现时我通常会加上一个简单的迭代修正或者直接分段线性化——0°C 到 100°C 之间 PT100 平均灵敏度约 0.385Ω/°C100°C 以下用线性逼近就能做到 0.2°C 以内很多 HVAC 项目完全够用。如果做的是高精度工业测温那么 CVD 方程的 C 系数负温段和一个小的自热修正都得加进去。自热修正是很多项目的隐性误差来源IDAC 激励电流流过 RTD 时本身会产生焦耳热电流越大自热越明显。250μA 激励在 100Ω 的 PT100 上产生约 6.25mW 功率这个量级对普通工业 RTD 影响不大但如果你把激励电流设到 1mA自热误差就可能超过 0.1°C。所以激励电流选择要结合 RTD 的热响应特性和精度要求来权衡。5. 真实项目里那些与你较劲的问题供电、隔离与排查链路5.1 供电和地线布局比传感器本身更影响精度24 位 ADC 的分辨率很高但也意味着它对电源噪声和地电位差更敏感。ADS122U04 通常有独立的模拟电源和数字电源引脚原理图上建议分成 AVDD 和 DVDD 两路供电每路都有各自的去耦电容且电容要尽量靠近芯片引脚摆放。数字地和模拟地在 ADC 芯片附近单点汇合不要让数字地电流流过模拟地回路。参考电压引脚的去耦更关键。参考电压是整个转换的尺子它稍微抖一下转换结果就跟着系统性偏移。如果是外部基准比如 REF5025 这类精密基准基准输出到 ADC 参考引脚的走线尽量短、加宽旁边放至少 10μF 的钽电容和 0.1μF 陶瓷电容并联去耦。我见过不少板子传感器和 ADC 都选得很好就是基准去耦电容放得太随意结果实测精度只有理论值的一半。电源本身如果需要从 24V 工业电源取电建议先用 DC-DC 降到 5V 左右再经 LDO 得到模拟电源。DC-DC 的开关噪声是模拟电路的常见干扰源LDO 的电源抑制比能挡掉一大部分但关键还是要让 DC-DC 的走线远离模拟信号区域。5.2 采样速率、分辨率与 50/60Hz 抑制的取舍ADS122U04 的数据速率配置和数字滤波模式会影响有效分辨率。滤波带宽越窄抑制工频干扰的能力越强但响应越慢。HVAC 这种 60 秒积累一次数据的应用用 20SPS 甚至更低速率完全没问题50/60Hz 工频干扰会被内置 SINC 滤波器吃掉。但如果你要做的不是 HVAC 而是电机保护或者快速温控20SPS 可能不够用这时候就得把速率提到 500SPS 以上代价是噪声指标变差、有效位数下降。目标应用推荐数据速率滤波器模式权衡说明HVAC 房间温度20SPSSINC3 50/60Hz 抑制精度优先响应慢可接受冷冻水/热水温度20~40SPSSINC3兼顾精度和报警响应工业过程控制100~500SPSSINC3 快速滤波牺牲部分分辨率换速度快速温度巡检≥1000SPS不推荐分辨率损失严重慎用这个取舍没有标准答案完全取决于现场温度变化有多快。我的经验是先确定系统允许的温度响应滞后时间再反推最低采样率最后在这个采样率下查数据手册的有效分辨率表看能不能满足精度指标。三个参数能闭环方案才算成立。5.3 现场排障链路从症状定位到抓帧验证真到了现场温度数据不对通常表现为三种症状乱跳、漂移、固定值。乱跳优先怀疑干扰和接线。用示波器看 ADC 输入前端重点查传感器线是不是和动力线走了同一个线槽屏蔽层是不是只在单端接地UART 通信线有没有靠近电源走线。这时候可以先把 PGA 增益调低一档如果乱跳现象明显减轻基本可以判定是前级噪声过大而不是通信问题。漂移优先怀疑冷端补偿和基准。用手摸一下板子上的冷端测温点看读数会不会跟着手心温度变化再用万用表实测基准电压看它是否稳定。我遇到过一种情况基准电压随着板温上升而下降读数持续漂移最后发现是基准芯片旁边的散热过孔把热传导到了基准的敏感引脚。固定值不动优先怀疑通信链路和数据有效位。把 MCU 发出去的配置命令原样抓出来和 ADC 实际收到的内容对比再用读寄存器命令逐字节读回配置确认芯片确实按你的预期工作了。UART 波特率误差在高波特率下是隐形杀手超过 3% 的误差就可能造成整帧错位这种问题最隐蔽也最值得在排查一开始就排除。这三大类问题排查完还有一招很实用把 ADC 输入短接成内部的二分之一电源电压伪差分看读值是否稳定在被测电源的 2.048V 附近。这个自检能区分问题在前级传感器电路还是在 ADC/软件链路能帮你快速缩小排查范围。我自己做这种项目的习惯是PCB 还在画的时候就把上位机的串口解析脚本写好等板子回来一上电就能立刻看到寄存器读回的原始波形和数据值。少做一步验证就可能多花一周在现场对着示波器猜问题。