ADS122U04+UART独立ADC与PIC18F47K42温控仪表设计踩坑复盘

发布时间:2026/11/4 6:01:47
ADS122U04+UART独立ADC与PIC18F47K42温控仪表设计踩坑复盘

用 ADS122U04 与 PIC18F47K42 做温控仪表,踩坑后的经验复盘

做工业温度测量和 HVAC 控制的老伙计应该都有感受:一个温度采集板,传感器从 PT100、PT1000 到 K 型热电偶都有,精度要求从 ±1℃ 到 ±0.1℃ 不等,控制器还要跟触摸屏、网关、变频器通信。市面上温控模块一大把,但要么贵,要么扩通道不方便。我去年帮朋友公司做了一套机房空调的温湿度采集板,核心就用了 ADS122U04IPWR 这颗带 UART 接口的 24 位 ADC,搭配 Microchip 的 PIC18F47K42TQFP。这套组合做下来,最大的体会是:模拟采集和数字控制分开干活,现场调试反而省心。ADC 管传感器信号,MCU 管逻辑和通信,中间就一根 UART 线,代码简单,抗干扰也好做。

那这篇博文就把设计思路、硬件电路、固件流程、校准方法,以及我实测中遇到的各种坑,一次性整理出来。想抄作业的可以直接参考,想评估方案是否可行的也能从中找到判断依据。

1. 方案选型背后的逻辑:为什么要用"独立 ADC + MCU"的组合

1.1 项目需求拆解:工业与 HVAC 场景到底在为难谁

先看应用场景。HVAC 设备里的温度测量点,常见的有回风温度、出风温度、盘管温度、室外环境温度,传感器基本是 NTC 热敏电阻或者 PT1000 RTD。工业现场则更“凶”一点:环境温度 -40℃ 到 85℃,电柜里变频器在边上,电机启停带来的电磁干扰很重,传感器线可能拉出去十几米,这时候 NTC 就顶不住了,至少是 PT100/PT1000,热电偶也很常见。

两类场景对精度和稳定性的要求差别不小。HVAC 的控制回路通常允许 ±0.5℃ 的偏差,毕竟空调末端本来就有滞后;工业温度监测则经常要求 ±0.2℃ 以内,并且要能连续工作几个月不漂。这些要求直接决定了 ADC 的位数、基准源和滤波策略。

ADS122U04 在很多地方刚好卡在“够用且好用”的区间:24 位 Δ-Σ ADC,内置可编程增益放大器、两个恒流源、内部基准、内部故障检测。这些外围模块如果全用分立器件搭,一块板子的成本瞬间上去,而且 PCB 面积至少增加 30%。

1.2 选 ADS122U04 而不是 SPI 接口 ADC 的理由

ADS122U04 最吸引我的是它带 UART 接口。以前用 SPI 接口的 ADC(比如 ADS1220、ADS124S08),MCU 这边要处理 SCK、MOSI、MISO、CS、DRDY 至少 5 根线,还得用中断或者轮询去伺候 DRDY。如果传感器板和控制板分离,SPI 线拉长了之后时序就容易出问题,经常是“跑着跑着读错一个字节”。

UART 就不一样了。两根线(TX、RX)走板间连接,甚至让 ADC 挂在一根已有的 Modbus 485 总线上都行。ADS122U04 支持多片并联,每一片可以用地址位区分,一个 PIC18F47K42 的 UART 外设可以同时带 4~8 片 ADC,每个 ADC 管 4 路模拟输入,相当于一个 MCU 就能扩展出 16~32 路温度采集通道。这个玩法在中央空调冷站和大型配电柜的多点测温项目里真是救了大命。

接口简化之外,ADS122U04 的模拟前端也集成得很全:

  • 4 个外部模拟输入(IN0~IN3),可以配成 2 路差分或 3 路单端;
  • 内置 PGA 增益 1~128,低幅值信号可以直接放大,省去外部仪表放大器;
  • 两个可编程电流源 IDAC1/IDAC2,50μA 到 1.5mA 多档设置,适合直接驱动 RTD;
  • 内部 2.048V 基准,也支持外部基准;
  • 20 SPS 到 2000 SPS 的数据速率可调;
  • 内部温度传感器可用于热电偶冷端补偿。

这个配置列表意味着什么?意味着传感器激励、信号放大、模数转换、数字输出,一条链路全齐了。对于做 HVAC 控制器的团队来说,开发工作量大大减少;对于做工业仪表的工程师来说,需要关注的模拟细节也都在这颗芯片的框架内,可控性好。

1.3 PIC18F47K42 凭什么当这个系统的控制器

PIC18F47K42 是 Microchip 新架构的中端 8 位机,48 引脚 TQFP 封装。我在项目里选它有几个实际原因:

第一是供电和电平兼容性好。工业板卡供电普遍是 24V DC 转 5V,PIC18F 系列支持 2.3V 到 5.5V 供电,5V 电源下可直接和 ADS122U04 的 UART 电平对接,不需要电平转换芯片。

第二是外设资源对这套应用来说足够而且省电流。PIC18F47K42 带 64MHz 内部振荡器、64KB Flash、4KB RAM,还有一个叫 CLC(可配置逻辑单元)的外设。我之前用 CLC 做了一个窗口比较器,当 ADC 读到的温度越界时,直接硬件输出一个翻转信号去控制风扇继电器,不占 CPU。这个功能在 HVAC 控制里很好用。

第三是抗干扰和工作温度范围。TQFP 封装在 PCB 上比 QFN 好走线,自身工作范围 -40℃ 到 125℃,在电柜里长时间运行很稳。

第四是调试工具链成熟。MPLAB X IDE + MCC 代码生成器,图形化配置 UART、Timer、引脚,一天就能把工程框架搭好。对于我这种经常一个人干全套的工程师来说,节省的时间很可观。

1.4 系统整体架构:一条链路说清楚信号流

搭建起来是这样:

传感器 -> RTD/热电偶 -> 滤波 RC -> ADS122U04 模拟输入 -> 内部 PGA 放大 -> 24 位 Δ-Σ 转换 -> UART 数据帧 -> PIC18F47K42 接收和解析 -> 线性化查表 -> 滤波和刻度转换 -> 显示或者 RS485 上传。

这套架构的关键在于把“模拟精度”和“数字处理”的职责划分清楚。模拟部分由 ADS122U04 完成,所有模拟信号的处理都在芯片内部短路径上完成,减少外部干扰注入;数字部分由 PIC18F47K42 完成,它不直接碰模拟,只吃 UART 传来的干净的原始数据。这样一来,即便 MCU 跑着通信协议、刷新 LCD、处理按键,也不会因为数字开关噪声污染温度数据。这是我实际测试体会很深的一点:独立的 ADC 隔离了高频数字噪声,省掉了软件滤波里很大一部分工作量。

2. 硬件电路设计:电源、基准、传感器接线和输入保护

2.1 电源设计:模拟电源和数字电源怎么处理

ADS122U04 的 AVDD 和 DVDD 可以分开供电。官方允许 AVDD 和 DVDD 分别接不同的电源,也可以共用一个电源,但共用的前提是电源足够干净。我实际画板时用的是种折中方案:

系统 5V 先过一颗 LDO 降到 3.3V,给 DVDD 和 MCU 供电;然后 3.3V 再通过 π 型滤波器进入 AVDD。这个 π 型滤波器由 10Ω 电阻加两个 10μF 钽电容组成,能把数字电源的纹波压掉一截。因为 ADS122U04 的 Δ-Σ 调制器对 AVDD 上的小干扰很敏感,开关电源的直接 5V 接 AVDD 的话,输出数据里能明显看到几百 Hz 的毛刺,这是我在第一版板上切切实实踩过的。

对应地,PCB 布局上,模拟地和数字地采用单点连接,在 ADC 芯片下方的焊盘处汇合。这样既避免了地环路拾取噪声,又保证了回流路径短。

2.2 基准电压:内部基准还是外部基准,要分场景

ADS122U04 默认使用内部 2.048V 基准,好处是接法简单,芯片自己完成,适合精度要求不高的 HVAC 场景。如果整机批量生产,内部基准也能少买一颗器件。

但做工业级产品,我更倾向于用外部基准,比如 REF5025 或者 REF3125 这类低温漂基准。原因不是内部基准不够好,而是内部基准的温漂系数往往在 ±20~50 ppm/℃,相比外部基准能做到的 ±2~5 ppm/℃,在冬夏温差 40~60℃ 的机柜里,可能产生 0.1~0.2℃ 的额外误差。对喊出“全温度范围精度 ±0.2℃”的工业仪表来说,这点误差得从源头上压掉。

外部基准的连接很简单:REF5025 输出 2.5V 接到 REFP 引脚,REFN 接模拟地。注意基准输出到 REFP 之间也要加一个小电容滤波,我习惯用 0.1μF 陶瓷电容并联 10μF 钽电容。基准下方不要走数字信号线,这是模拟布线的基本功。

2.3 RTD 三线制接法:恒流源激励与引线电阻补偿

PT100 和 PT1000 是 HVAC 和工业测温的主力。这两种传感器本质上都是电阻,ADC 不是直接测电阻,而是靠恒流源流过电阻产生电压,再用 ADC 测量这个电压。这个过程里最大的敌人是引线电阻。

如果用两线制,激励电流流过传感器之后还要从同一根线回来,ADC 测到的电压里包含了线电阻的压降,误差可能是几欧姆到十几欧姆,放在 PT100 上相当于好几度的误差,完全不可接受。四线制最准,但现场要拉四根线,成本高。

所以实际项目中选择三线制。ADS122U04 的两个 IDAC 在这里派上关键用场:

PT100 三线接法 IDAC1 ---- 红线1 ---- RTD ---- 红线2 ---- IDAC2 | 红线3 ---- INN 测量点 INP 连接在红线1与RTD的节点

接法逻辑是:IDAC1 的电流流过 RTD 之后,从 INN 这根线返回;而 IDAC2 提供一个相同的电流,电流方向与 IDAC1 相反,拉着 INN 点的电位与红线3 上的压降形成抵消。两个 IDAC 电流相等的情况下,引线电阻上的压降被全部抵消,ADC 测到的就是 RTD 本体两端的电压。实现的细节取决于配置寄存器的 MUX 和电流方向设置,官方数据手册里有典型电路,但原理就是上面说的“双电流源补偿”。

选恒流源大小时要综合考虑。电流越大,信号电压越大,信噪比越好,但 RTD 自己会发热,造成自热误差。我一般选 500μA 或 1mA。PT100 在 0℃ 时是 100Ω,1mA 电流产生 0.1V 电压,自热功率只有 0.1mW,在空气中热阻约 120℃/W 的情况下,自热温升约 0.012℃,完全可以忽略。如果是紧密贴附在导热良好的金属表面,自热温升更小。

测量 PT1000 时我喜欢把电流降到 250μA,因为 PT1000 阻值大,信号本身够大,减小电流可以把自热和功耗一起压下来。

2.4 热电偶的测量与冷端补偿

工业 HVAC 里面如果测冷冻水管道表面温度、压缩机的排气温度,热电偶比 RTD 更耐高温、响应更快。热电偶输出的是微伏级的电压,K 型热电偶约 41μV/℃,所以 PGA 增益要拉到 64 或 128 倍。

热电偶测量有一件绕不开的事:冷端补偿。ADS122U04 内部集成温度传感器,用于测量芯片附近的环境温度。热电偶被测量端的电压是相对冷端电压而言的,要得到真正的绝对值,必须把冷端温度对应的热电势加上去。

我的做法是让 ADS122U04 用内部温度传感器周期性地采集一次冷端温度,MCU 每 5 秒读一次温度传感器的原始码,换算成摄氏度,再用查表法或多项式计算对应热电势,最后加到热电偶电压增量上。这样省掉了一个外部 NTC 电路,冷端温度跟随性好,不需要校准传感器位置。

唯一要注意的是,ADS122U04 芯片自身的发热会影响内部温度传感器读数。因此冷端补偿的“冷端”实际上指的是热电偶连接端子所在的电路板区域,而不是芯片本身。所以布线时尽量让热电偶冷端焊盘靠近芯片,让芯片能感受到端子区域温度,同时让 ADC 的功耗尽量稳定在连续转换模式,避免芯片温度阶跃变化。这个细节我在实际测试中做过对比,芯片温度变化 1℃,补偿误差大约对应 1℃ 的热电偶误差,所以务必重视。

2.5 模拟输入滤波与输入保护

模拟输入前端我习惯加两级保护。第一级是串联限流电阻,阻值选 1kΩ;第二级是 TVS 管加对地电容,限制浪涌电压。ADS122U04 的最大输入电压范围是 AVDD+0.3V,工业现场如果传感器线被碰触到 220V,或者电机启动时产生浪涌,不加保护的话,ADC 大概率直接烧毁。

RC 滤波的参数要仔细算。常见的做法是输入串 10kΩ 电阻、并联 0.1μF 电容,截止频率约 160Hz,对 50Hz 工频干扰抑制效果很好。但要注意,RC 低通滤波会拉长信号建立时间。ADS122U04 输入阻抗在 PGA 使能后比较低,等效输入阻抗约几百 kΩ,如果串的电阻太大,RTD 上用恒流源激励产生的电压就会被分压,造成测量增益误差。计算下来,10kΩ 的串阻对 500μA 恒流源来说会额外产生 5mV 压降,对 0.1V 量级的信号影响约 5%。因此,RTD 测量串阻不应超过 1kΩ,热电偶测量串阻可以稍微大一点,因为 PGA 输入偏置电流非常小。

如果既想要滤波又怕分压误差,可以用一个被称作“滤波器并联在 PGA 输出端”的方案:在 ADC 模拟输入引脚和地之间直接接电容,不给信号路径串电阻。这个方案的滤波效果也不错,但因为不衰减信号,所以串阻放大误差不存在。实测下来,RC 串阻 1kΩ 加 0.1μF 电容的组合在多数场景下够用,除非有强干扰源,才需要上更重的滤波器。

3. 固件实现:UART 通信协议、配置流程和温度换算

3.1 ADS122U04 的 UART 通信帧格式

ADS122U04 的 UART 接口支持标准的 8 位无校验、1 停止位模式,波特率默认 9600,也可以通过命令配置到最高 115200。它支持 ADDR 引脚多机寻址,这在我前面提到的大通道扩展场景里非常实用。

通信的命令字节结构如下:

  • NOP:0x00
  • RDATA:0x10(读取转换结果)
  • RREG:0x20 + 寄存器地址(读寄存器)
  • WREG:0x40 + 寄存器地址(写寄存器)
  • START:0x08(启动转换)
  • STOP:0x04(停止转换)

写入配置寄存器时,命令后面跟数据字节。比如写 CR0 寄存器,发送 0x40,然后发送 CR0 的值即可。

实际开发中,我发现 UART 通信一个很重要的细节:命令发送之后必须等待应答完成,ADS122U04 会在处理命令后的 16 个时钟周期内返回一个状态字节。不同的命令返回的状态字节含义不同,但即使是发了 NOP,它也会返回一个字节,这个字节可以用来做帧同步——如果 MCU 收不到应答或者应答异常,就说明 UART 波特率对不上或者硬件连接出问题。我调试时最喜欢先发 NOP,看是否有应答,用这个方法快速定位链路故障。

3.2 配置寄存器和初始化流程

ADS122U04 有 4 个配置寄存器:CR0 到 CR3。关键配置项如下:

寄存器配置内容典型值(PT100 三线)
CR0PGA 增益、运行模式PGA=32,连续转换
CR1数据速率、滤波器模式20 SPS,50/60Hz 抑制
CR2输入 MUX、IDAC 配置差分输入,IDAC 500μA
CR3基准选择、IDAC 方向外部基准/内部,电流方向设置

初始化流程在代码里是这样实现的:

// 伪代码:ADC 初始化 void ADS122U04_Init(void) { // 1. 复位 ADC UART_SendByte(0x06); // 复位命令,等待 t > 80ms delay_ms(100); // 2. 写配置寄存器 uint8_t cfg[4]; cfg[0] = 0x00; // CR0: PGA=1,测试后再根据输入调整 cfg[1] = 0x20; // CR1: 数据速率 20 SPS + 50/60Hz 同时抑制 cfg[2] = 0x08; // CR2: AINP=IN0, AINN=IN1,IDAC 500μA cfg[3] = 0x20; // CR3: 使用外部基准 SendCommand(0x40, cfg, 4); delay_ms(5); // 3. 启动转换 SendCommand(0x08); // START }

这里的 CR1 配置 0x20 对应数据速率为 20 SPS 并且同时打开 50Hz 和 60Hz 工频抑制。为什么选 20 SPS?因为 Δ-Σ ADC 的工频抑制是靠采样速率和滤波器同步实现的,20 SPS 时积分周期正好对齐 50Hz 和 60Hz 的整数倍,在工业现场能直接滤掉一大半工频干扰。代价就是转换结果更新慢——每 50ms 出来一个新数据。对 HVAC 这种温度本来变化很慢的系统,20 SPS 完全够用,还顺便降低了一点噪声。

如果是做动态响应要求高的电机保护类设备,可以提高到 60 SPS 或 200 SPS,但这时候要在代码里加数字滤波来压噪声了。

3.3 读取转换结果与数据格式转换

ADS122U04 的转换结果是 24 位二进制补码,格式上跟 ADS1220 一样。MCU 读回来三个字节,需要拼成有符号数:

int32_t ads_read_raw(void) { uint8_t b[3]; SendCommand(0x10); // RDATA for (int i = 0; i < 3; i++) { b[i] = UART_ReadByte(); } int32_t raw = (b[0] << 16) | (b[1] << 8) | b[2]; if (raw & 0x800000) { raw |= 0xFF000000; // 符号扩展 } return raw; }

原始码转电压的公式是:

电压 = 原始码 × (2 × VREF) / (增益 × 2^23)

这里注意 24 位补码的满量程是 ±2^23,而 ADS122U04 的输入满量程是 ±VREF。加上极性,计算公式里面的 2×VREF 就是一次满量程的跨度。我习惯把 24 位整型先转成 float 再做除法,因为定点数在增益和基准源都是小数时处理起来麻烦,单片机主频 64MHz 跑这些浮点也不吃力。

PT100 阻值计算:R = V / IDAC。IDAC 设成 500μA,那么 100Ω 对应电压是 0.05V。用 PGA=32 放大之后是 1.6V,接近 2.048V 满量程的 78%,动态范围利用得比较充分。

温度换算我用查表加线性插值。PT100 的温度-电阻表国标里有标准数据,我把 -50℃ 到 200℃ 范围的阻值按 1℃ 间隔存成查找表,查表后线性插值。800 个点的表在 PIC18F47K42 的 64KB Flash 里只占不到 2KB,代码简单,查表速度比算 Callendar-Van Dusen 多项式快得多,还很直观。对精度要求不高的场合,用一阶公式近似也行,但查表的通用性更强,换传感器类型时只需要换表。

热电偶就麻烦一点,K 型热电偶 0~1000℃ 的温度-电压关系要用 9 次多项式,自己算太折磨,直接查表加插值最省事。多项式系数网上有公开数据,做成 200 个点的表,实测整个温度区间误差小于 0.1℃。

3.4 MCU 端的滤波算法:为什么先移动平均再一阶滤波

ADC 原始数据送到 MCU 后,我一般做两步滤波。第一步是移动平均,用于去掉转换周期内的高频毛刺。ADS122U04 在 20 SPS 下输出一个数据,我取最近 4 次结果平均,对应 200ms 响应时间,对温度控制来说还是很快的。

第二步是一阶低通,或者叫指数滑动平均,公式是:

output_new = output_old + K × (input - output_old)

K 取 0.1~0.3。这个滤波的作用是让显示和控制输出平滑。特别是空调温控面板要显示温度时,如果不滤波,最后一位数字会不停跳动,显得很不专业。实际调下来,K=0.2 时显示稳定且跟手,不会出现温度已经降了 1℃ 显示还在慢慢爬的情况。

注意一个细节:做温度控制时,滤波时间常数不要太长。我做过一个失败的板子,滤波参数调得太激进,结果温控实际超调了 2℃,用户投诉温度忽冷忽热。后来把滤波器响应时间缩短到 500ms 以内才解决。控制回路的滤波是双刃剑,滤得越狠,响应越迟钝。

3.5 低功耗与轮询策略

HVAC 设备的控制面板常常有节能认证要求,整板功耗要控制得很低。PIC18F47K42 的低功耗表现不错,但既然用了独立 ADC,就有一个天然优势:可以在采样间隙让 MCU 休眠,ADC 自己持续转换,转换完成后通过 DRDY 状态由 UART 或 GPIO 通知 MCU。

我在代码里的做法是设置 ADS122U04 为连续转换模式,MCU 用定时器每 500ms 唤醒一次,读取最近一次的转换结果,然后立即回去睡觉。UART 唤醒用接收中断,只有上位机请求数据时才把 MCU 从休眠中唤醒。实测这套流程下来,整个系统平均电流不到 3mA,在 24V 电源下有它不多没它不少,但做电池供电的便携测温仪时这个电量就非常有意义。

3.6 多片 ADC 级联与 Modbus 对接

如果系统要测几十路温度,一片 ADS122U04 不够,可以在 UART 总线上挂多片。每片 ADC 的 ADDR 引脚设置不同地址(GND、VDD 或悬空对应不同地址),MCU 在命令字节前添加地址字节,ADC 根据地址判断是否响应。

我的实际项目里用 4 片 ADS122U04 挂在一条 UART 线上,16 路 PT100 输入,MCU 每 200ms 轮询一轮,每片读取耗时约 15ms,总耗时 60ms,余量非常充足。之后再用 RS485 把整理好的温度值以 Modbus 寄存器的方式上传到上位机或直接接到楼宇自控(BAS)系统。这个架构在机房空调项目里一次通过,上位机调试没遇到任何卡壳。

4. 校准、精度验证与典型问题排查

4.1 两点校准:把系统误差一次压到最低

再好的 ADC 也有增益误差和偏置误差,再好的基准也有初始精度偏差。如果我对单板精度要求 ±0.2℃ 以上,就必须做系统级两点校准。

校准步骤我总结为“短路零位 + 标准电阻满位”两步:

  • 偏置校准:把 ADC 输入短接,读一个原始码,记作 offset。这个值反映了 PGA 的输入失调电压和基准偏置,通常在几十到几百个 LSB。
  • 增益校准:接一个精密电阻(比如 100.00Ω 的 0.01% 电阻),读原始码,算增益系数 gain = 实际阻值 × IDAC / (电压值 - offset)。把 gain 存到 Flash 的校准区。

之后每次测量都按修正公式算:R_real = (raw - offset) / gain。

这个方法在产线上执行很快,每个通道手工校准大约 10 秒。代价是产线需要一个精密电阻盒和一个短接端子。我见过有些小厂舍不得买标准电阻,结果整批板子一致性差,温度显示互相差 0.5℃,客户来验收直接退货。这笔投资无论如何不能省。

校准后,系统误差主要取决于外部基准的温漂和 RTD 自热。用 REF5025 时,实测在 -20℃ 到 50℃ 环境温度范围内,PT100 测量偏差能控制在 ±0.1℃ 以内。

4.2 硬件忍痛踩坑:电源纹波和接地是如何让我白忙一周的

我在做第二版电路时,想当然地把开关电源 24V 转 5V 的数字 5V 直接引到了 ADS122U04 的 AVDD 上,结果发现所有通道的读数都在 ±2 LSB 到 ±5 LSB 之间抖动,且抖动频率恰好与 PWM 风扇控制频率相关。一开始我还怀疑是滤波程序写得不够好,花了好几天改程序,加滤波,效果都有限。

后来用示波器测得 AVDD 上的纹波高达 80mVpp,才明白问题出在电源上。改回 LDO + π 滤波之后,ADC 输出毛刺大幅度下降,4 LSB 的抖动直接掉到 ±0.5 LSB 以内。这事的教训很深:模数混合电路,电源的优先级永远排在第一位。没有干净的电源,再好的 ADC 也白搭。

另外一个容易忽略的问题是数字地和模拟地在 PCB 上的连接。如果两边的地平面被切得很碎,高频回流会绕过 ADC 芯片,形成一个大地环路,噪声照样进到模拟信号里。我后来统一规则:模拟电路区域上方禁止走数字时钟线,地平面在 ADC 正下方用一颗 0Ω 电阻连起来。

4.3 电路板上的 UART 电平匹配:为什么连不上

ADS122U04 的 UART 引脚耐压是 5V,而 PIC18F47K42 在 5V 供电时 IO 也是 5V。直接连是没问题的。但如果 MCU 用 3.3V 供电,而 ADC 的 DVDD 也用 3.3V,接法也自然。

真正坑的是有些无线模块、传感器板本身是 5V 单片机,但板上 ADC 却是 3.3V,或者反过来。我帮人排查过一例:MCU 是 5V,ADC 是 3.3V,直接把两个 UART 线对接,结果 ADC 的 TX 引脚被高电平灌入烧了。正确的做法是加电平转换,比如用 74LVC1T45,或者在 MCU 的 RX 线上串联 1kΩ 限流电阻并加 3.3V 钳位二极管。这里没有一开始就检查数据手册的电平规格,也是我早期犯过的错误。

4.4 常见问题速查表:三分钟定位故障

故障现象可能原因检查/解决
UART 无应答波特率配置错误、接线松、ADDR 地址不对先发 NOP 命令验证链路,用示波器测 TX/RX 波形
温度读数整体偏差基准电压不准、PGA 增益配置错、IDAC 电流档错校准前先对比内部基准 2.048V 是否匹配
读数抖动大电源纹波、输入滤波不足、RC 串阻过大示波器测 AVDD;检查输入是否受工频干扰
温度一小时漂 0.3℃RTD 自热、基准温漂、板上发热源降低 IDAC 电流;检查基准芯片周围温度;加散热/通风
热电偶冷端补偿不准芯片温度没有稳定、冷端传感器位置不合适连续开机至少 10 分钟再校准;让冷端接头贴板
数据偶尔单字节错UART 波特率偏差、晶振公差检查 MCU 内部振荡器校准;改用外部晶振或提高 ADC 波特率容错
多片 ADC 抢总线ADDR 地址冲突、命令帧无地址位重新配置地址;确认每一片 ADC 地址码唯一

4.5 EMC 现场排查:变频器和继电器造成的诡异干扰

现场最头疼的问题往往不是单板测试能复现的。有次在工厂配电室调试,控制柜里变频器一启动,温度读数就往下跳 3℃ 再回弹,继电器吸合时也会跳一下。排查思路最后锁定在两点:

第一是传感器线没有用屏蔽双绞线,且屏蔽层在两端都接了地。地环路电流在屏蔽层上流动,直接耦合进了信号线。改成屏蔽层只在控制板侧单端接地之后,效果立竿见影。

第二是继电器线圈没有续流二极管。关断瞬间的浪涌直接从电源线跑进 ADC 的参考电压引脚,导致数据突跳。加了续流二极管和 RC 吸收网络后,问题彻底消失。

这两个问题都属于“书上学不到现场必有”的典型。做工业品的朋友切记,EMC 设计不能等到试机时才开始。

5. 从 Prototype 到量产:固件健壮性和产测建议

5.1 固件健壮性的三个细节

温度采集系统一旦到了客户手上,遇到的情况比实验室复杂得多。我从量产角度总结三个必须固件处理的细节:

第一,UART 通信异常后的自动恢复。ADS122U04 如果收到半截命令,后续字节解析会出错。我在 MCU 端做了一个超时机制:连续 3 次命令无应答时,重新初始化 ADC,发复位命令。有了这个机制,现场即使出现一次偶发干扰,系统也能在几百毫秒内自动恢复,不至于让整套设备温度数据卡死。

第二,数据边界判断。温度传感器断线、短路是常见故障,ADS122U04 内置了输入开路检测,我可以定期开启这个检测,把开路/短路状态通过 Modbus 的状态寄存器上报给上位机。这样维护人员到现场一看就知道是哪一路探头出问题,不用逐根线排查。

第三,Flash 写保护。校准参数放在数据 EEPROM 区,写入前必须校验,校验失败不要覆盖旧值。我有一次调试程序 bug,把整个校准区刷成了 0,导致所有板子温度偏移好几十度。从此之后,任何写 EEPROM 的操作我之前都会先备份旧数据。

5.2 产线测试方案:怎么确保每一块板子的 ADC 都是好的

产线上如果只是手工上电看温度显示,很容易漏出次品。我设计过一套简单有效的测试流程:

  • 上电后 MCU 自动执行一次内部自检,读取 ID 寄存器确认 ADC 正常;
  • 测试治具通过继电器切换到“短路输入”,MCU 读回的原始码如果小于 ±10 LSB,判定偏置正常;
  • 再切换到“精密电阻输入”,读回阻值偏差如果大于 ±0.1%,判定增益异常;
  • 全部通过后,把校准参数写入 Flash,并打印一张带序列号的“校准合格标签”。

这套流程全程一个按键点动,测试时间大约 8 秒/板,产线工人操作起来没压力。生产了 200 块板子之后,只有 2 块因为焊接问题(ADC 引脚虚焊)被主动检出,整体一次通过率 99%。在做这个测试方案之前,虚焊的板子会在客户现场随机抽风,售后成本远高于生产测试成本。

5.3 若想再进一步:NTC 通道与数字输出的扩展空间

虽然标题是测温度,但 ACA 系统的湿度、风阀位置、电流互感器等信号也可以走 ADC。ADS122U04 剩下一路单端输入时,完全可以把 0~10V 的风阀反馈信号简单分压后接进去,MCU 顺便做模拟量输入采集,省掉一个专用模拟量采集模块。

如果后续产品要联网,PIC18F47K42 还可以接 ESP-01S 这类低成本 Wi-Fi 模块,把温度数据直接上报到云平台。独立 ADC 的好处这时候非常明显:Wi-Fi 模块在数据发送时有大电流脉冲,这期间 PIC18F47K42 的 GPIO 会抖动,但因为温度数据由 ADC 连续转换、定时读取,MCU 不直接参与模拟采样,所以 Wi-Fi 发射造成的电源毛刺并不会污染温度数据。这是我在另一个项目里实测过的场景,可靠性和精度都保持住了。


最后分享一个我实际体会最深的细节:ADS122U04 的复位时间比很多人想象的长,数据手册要求复位后等待 80ms 以上再发配置命令。我第一次写驱动时没注意,复位后立刻发 WREG,结果配置写不进去,ADC 一直跑在默认配置上,折腾了一下午才发现是复位时序问题。从那以后,我写所有 Δ-Σ ADC 的驱动,第一件事就是查复位和上电时序,而不是一头扎进寄存器配置。

这套“ADS122U04 + PIC18F47K42”的方案,论绝对性能打不过 24 位 SPI 高速 ADC 加高端 MCU 的组合,但它赢在接口简洁、系统成本低、开发和调试门槛低。如果你的项目恰好也是几十路温度、精度 ±0.2℃、需要过 EMC、还要省着点成本,那么这个组合足够让你少加几周班。