这几年的项目里,用 ADS122U04IPWR 这颗带 UART 接口的 24 位 ADC 搭配 PIC18F46K22 单片机做工业和 HVAC 温度测量,是我个人觉得比较顺手的组合。这个标题看着像是一行选型记录,但真把它从原理图变成能稳定出数的样机,中间有不少细节值得聊。无论你是刚接触 RTD 和热电偶测量,还是已经在做暖通控制器但苦于模拟前端噪声,这篇文章都适合你。我会把硬件连接、寄存器配置、驱动代码、标定经验这些实操层面的东西,以及踩过的坑,尽量按实际开发顺序讲清楚。
1. 项目整体设计与硬件选型思路
1.1 为什么选 UART 型 ADC,而不是常规 SPI 型
先说选型逻辑。很多工程师一提到高精度 ADC,下意识就会选带 SPI 接口的型号,因为这确实是主流。但你在做分布式温度采集时,SPI 有两个让人头疼的地方:一是时钟线、片选线、数据线加起来至少四根线,现场走线会比较麻烦;二是 SPI 时序对从机距离和信号完整性比较敏感,线一长就容易丢数据或者粘波。
ADS122U04IPWR 的特殊价值在于它把 SPI 换成了 UART,一根发送、一根接收,接法和串口一模一样。对于 PIC18F46K22 这类带硬件 EUSART 的 MCU 来说,驱动起来特别省事,波特率设好,发命令、收数据就行,不用像 SPI 那样自己模拟片选时序,也不用担心主从时钟相位错位的问题。而且 UART 天然适合做隔离,未来如果要在工业现场加数字隔离器,串口侧隔离实现起来也比 SPI 简单很多。
当然,UART 型 ADC 不是没有代价,比如它的寄存器配置是需要按字节操作、时序有固定帧格式,不能像 SPI 那样随意拉时序。但对于温度测量这个场景,采样率本来就不高,单次转换、读结果、再计算,这个节奏和串口通信很配。
1.2 为什么 PIC18F46K22 足够胜任
有人可能会问:都 202x 年了,还选 8 位单片机?我的回答是:温度测量这个项目的瓶颈从来不是 MCU 的算力,而是模拟前端的稳定性和算法上的标定精度。
PIC18F46K22 在这类项目里的优势主要有几点:
- 片内集成两个 EUSART,其中一个专门给 ADS122U04 用,另一个留给 Modbus 或调试串口,互不干扰。
- 内部振荡器经过校准后精度足够跑 UART,省掉一个外部晶振,成本低、BOM 简单。
- 工作电压范围宽,5V 供电时可以直接和 ADS122U04 的 I/O 兼容,不需要额外的电平转换。
- 工业级温度范围,在 HVAC 控制柜里长期运行没什么压力。
从软件架构上讲,8 位机上用状态机轮询 UART 中断、管理转换命令、做滑动滤波,整套逻辑非常清晰。非要上 Cortex-M 反而有点浪费,而且 5V 系统的外设接口兼容性还得重新设计。
1.3 系统架构与信号流向
这套系统的信号链路大致如下:
- 温度传感器(PT100/PT1000 或热电偶)就近接入 ADS122U04。
- ADS122U04 内部 PGA 做小信号放大,24 位 delta-sigma ADC 完成数字化,通过 UART 把转换结果发给 MCU。
- MCU 负责发送转换命令、读取 24 位数据、执行线性化算法和标定补偿,再输出给显示、继电器控制或者 Modbus 通信模块。
把模拟前端独立到 ADC 这颗芯片上,而不是用 MCU 内部 ADC,最大的好处是噪声隔离。MCU 内部往往有数字开关噪声,直接采样几百微伏的 RTD 信号很难保证稳定。外置高精度 ADC 可以离传感器更近,信号还没到 MCU 就已经被转成数字量,抗干扰能力完全不一样。
1.4 适合的应用场景
这套方案最典型的应用有两块:工业过程监测和 HVAC 系统。
工业场景里常见的有电机轴承温度、冷却水温度、管道介质温度。这些场合传感器距离控制器常常有几十米,信号线会经过变频器、继电器等强干扰源,对 ADC 的动态范围和稳定性要求高。
HVAC 场景则包括回风温度、送风温度、盘管进出水温度、室外温度等。这些地方对绝对精度的要求通常在 ±0.5°C 以内,但对长期稳定性和批量一致性要求很高,毕竟暖通控制器是 7x24 小时运行的,而且现场维护条件差。ADS122U04 内部有可编程激励电流源和精密基准,可以把 RTD 接成比例测量,长期漂移能做到很小,恰好匹配这类需求。
2. 传感器接入与测量原理拆解
2.1 为什么用比例测量来消除电流源漂移
温度测量里最常见的传感器就是铂电阻,PT100 在 0°C 时阻值 100Ω,大约每升高 1°C 阻值增加 0.385Ω。这个变化量非常小,如果只靠 ADC 测“绝对电压”,那电流源哪怕漂一点点,换算出来的温度就会偏很多。
ADS122U04 有内置可编程电流源 IDAC,可以给 RTD 供电。关键点在于,我们可以用同一个电流源同时驱动一个精密参考电阻 RREF,然后把 RREF 两端的电压作为 ADC 的参考电压,RTD 两端的电压作为输入信号。这样最终转换结果只取决于 RTD 和 RREF 的阻值比,电流源本身的温漂、老化、电压波动全都被抵消了。
这个原理和数字万用表测电阻用的比例法是一个思路。只要 RREF 选得好,系统精度主要被 RREF 的精度和温漂决定,而不是 ADC 的绝对参考电压。
2.2 两线、三线、四线制 RTD 的误差分析
RTD 接线方式直接决定测量误差,现场很容易忽略。
两线制最省线,但问题很明显:导线电阻直接串联进 RTD,比如 10 米线缆,铜导线电阻可能有 1~2Ω,换算成温度就是好几度。所以两线制只能用在短线、低精度要求的场合。
三线制是工业现场的主流方案。做法是让 IDAC 电流从一根线进去,从 RTD 出来后再分两条路回到测量端,利用多一根线的对称性,把导线压降从差分测量结果中抵消掉。只要两根线阻值一致,误差就能压到很小。
四线制最精确,用一对线给 RTD 供电流,另一对线专门测电压,电压测量回路几乎没有电流流过,导线电阻带来的误差基本为零。实验室和计量设备常用,但现场布线成本高。
HVAC 项目里我一般推荐三线制,精度足够,施工成本也合理。唯一要注意的是现场接线时两根引线尽量用同一段电缆里的双绞线,保证阻值对称和抗干扰能力。
2.3 热电偶接入与冷端补偿
热电偶的输出是毫伏级别的热电势,而且它测的是“温差”,必须知道冷端温度才能算热端真实温度。ADS122U04 内部集成了片内温度传感器,可以直接测量芯片附近温度,这个温度通常可以当作冷端参考温度。把热电偶的冷端尽量贴近 ADC 的引脚区域,用内部温度传感器读数做补偿,就能把误差控制在可接受范围。
如果对冷端精度要求比较高,也可以外接一个 PT1000 紧贴冷端位置,用另一路 ADC 通道专门测量冷端温度,效果更好。只是这样要多占一个通道,还要多一个传感器。
2.4 信号链路的增益与数据率选择
热电偶信号通常只有几十毫伏,RTD 信号经过电流源转换后也大概是几十到几百毫伏。这就需要 PGA 做前置放大。ADS122U04 的 PGA 增益有多个档位,选增益时要注意:增益高了,小信号分辨率高,但噪声也会被放大;增益低了,信号可能填不满 ADC 的量程,分辨率浪费。
数据率也要和噪声做平衡。delta-sigma ADC 的数据率越低,内部数字滤波器抽样的平均值越多,噪声越小。温度测量本身是慢变信号,我一般选 20SPS 或 50SPS,实时性完全够用,噪声又能压到很低。如果做快速响应温度计,可以提到 200SPS,但要做好读数波动的心理准备。
3. 硬件连接和 PIC18F46K22 驱动实现
3.1 引脚分配与供电去耦
以 HVAC 控制板为例,我常用的引脚分配如下:
| PIC18F46K22 引脚 | 功能方向 | 连接目标 | 说明 |
|---|---|---|---|
| RC6/TX1 | 输出 | ADS122U04 的串口接收端 | 发送命令 |
| RC7/RX1 | 输入 | ADS122U04 的串口发送端 | 接收数据 |
| RA0 | 输出 | 片选或复位控制(可选) | 根据实际芯片行为决定 |
| VDD/VSS | - | 5V 供电 | 需要稳定的电源轨 |
| AN0 | 输入 | 可选:冷端参考测量 | 如果用外部冷端补偿 |
ADS122U04 的电源去耦要特别注意,因为它是混合信号芯片,模拟电源和数字电源虽然内部有管理,但外部该加的去耦电容一个都不能省。我习惯在每个电源引脚附近放一个 10uF 钽电容加一个 0.1uF 陶瓷电容,而且尽量靠近引脚。参考电阻 RREF 要用低温漂的金属膜电阻,精度 0.1%,温漂 25ppm 以内,否则它会成为整个系统精度天花板。
UART 连接比较直接,TX、RX 交叉互联,共地。如果 MCU 是 5V、ADC 也支持 5V,电平兼容没有问题。如果两者供电电压不同,就需要加电平转换或串阻分压,别图省事直接硬接。
3.2 XC8 环境下的 UART 初始化
PIC18F46K22 用 Microchip 的 XC8 编译器开发。UART1 初始化的核心代码大致如下,以 9600 波特率、8 位数据、无校验、1 停止位为例:
#define _XTAL_FREQ 16000000UL void uart1_init(void) { TRISC6 = 0; // TX1 -> RC6 输出 TRISC7 = 1; // RX1 <- RC7 输入 TXSTA1bits.TXEN = 1; // 使能发送 RCSTA1bits.SPEN = 1; // 使能串口 BAUDCON1bits.BRG16 = 1; SPBRG1 = ((_XTAL_FREQ / 9600UL) / 16UL) - 1; // 如果波特率误差偏大,微调 BRG16 和 SPBRGH1 }UART 波特率误差要注意,PIC 的 UART 硬件如果 BRG 值计算误差超过 2%,长帧通信或者连续多字节数据时容易出错。最好在代码里顺手算一遍实际波特率,偏差超过 1% 就换晶振频率或降低波特率。
3.3 ADS122U04 的寄存器配置顺序
ADS122U04 的配置寄存器需要按照数据手册的帧格式写入,命令一般是复位、写寄存器、启动转换、读数据这几类。建议上电后第一件事就是发一次复位命令,把芯片内部状态清干净,然后再配置寄存器。顺序很重要,因为某些寄存器位在写的时候有依赖关系。
一个典型的单次转换配置流程:
// 发送单字节复位命令 void ads122u_reset(void) { uart1_send_byte(0x06); __delay_ms(2); } // 写配置寄存器,reg_addr 为寄存器地址,data 为配置值 void ads122u_write_reg(uint8_t reg_addr, uint8_t data) { uart1_send_byte(0x40 | (reg_addr & 0x0F)); uart1_send_byte(0x00); // 高字节地址位(根据手册定义) uart1_send_byte(data); } void ads122u_init(void) { ads122u_reset(); // 配置输入多路复用器,例如 AIN0/AIN1 作为差分输入 ads122u_write_reg(0x00, 0x10); // 配置 PGA = 8,数据率 = 20SPS ads122u_write_reg(0x01, 0x08); // 使能内部参考电压并启用参考电阻输入 ads122u_write_reg(0x02, 0x40); // 设置 IDAC 电流为 500uA 并输出到 AIN0 ads122u_write_reg(0x03, 0x10); }上面代码里的配置数值是示例,实际必须以官方数据手册的位定义为准,因为不同版本的寄存器编码方式可能有差异。但你只要把“复位 -> 写寄存器 -> 启动转换 -> 读数据”这个顺序理解了,换寄存器值就只是查手册的事。
3.4 启动转换和读取 24 位结果
单次转换模式下,MCU 先发启动命令,等待 DRDY 信号或者固定延时,然后读取 24 位数据。ADS122U04 在 UART 模式下发送请求后,会返回转换结果,读取字节数要和 24 位对齐。
核心代码框架如下:
void ads122u_start(void) { uart1_send_byte(0x08); // 启动单次转换 } int32_t ads122u_read_data(void) { int32_t raw = 0; raw |= (int32_t)uart1_receive_byte() << 16; raw |= (int32_t)uart1_receive_byte() << 8; raw |= (int32_t)uart1_receive_byte(); // 如果 24 位数据用补码表示,负数时扩展符号位 if (raw & 0x800000) { raw |= ~0x7FFFFF; } return raw; }读取数据后要判断数据是否有效,比如检查溢出位或者 DRDY 状态。我见过很多人直接拿头三字节开始算温度,结果数据其实还是上一次转换的旧值。稳妥做法是每次转换完成后再读,数据返回后再用新的值更新结果,避免异步错位。
3.5 温度换算与标定流程
对于 RTD 比例测量,最简单的换算公式是:
float rtd_resistance(int32_t raw_code, float rref) { float ratio = (float)raw_code / 0x800000UL; // 双极性满量程归一化 return rref * ratio; }拿到 RTD 阻值后,再用铂电阻分度表或 Callendar-Van Dusen 多项式换算成温度。工程上我建议用查表加线性插值,这比在 8 位单片机上跑复杂的浮点多格式快很多,而且在 0~100°C 范围内插值精度完全够。
标定流程不要省。虽然 ADS122U04 内部基准已经很不错,RREF 也选高精度,但批量生产时还是建议做两点校准:用精密电阻箱分别模拟 0°C 和 100°C 对应的阻值,读出原始码,然后算出增益误差和偏置误差,写进 EEPROM 存储,运行时做线性修正。
顺带一提,软件滤波也别过度。滑动平均窗口取 8~16 次就够了,窗口太大不但延时大,而且会对真实温度变化反应迟钝。HVAC 里温度本来就变化慢,16 点滑动平均很合适,但如果做工业报警联锁,窗口要适当缩短。
4. 常见问题与排查技巧
4.1 读数跳字大,噪声降不下来
这是最常遇到的问题。如果你发现转换结果在 ±几 LSB 甚至几十 LSB 之间跳,先别急着怀疑芯片,按顺序排查:
- 供电纹波。用示波器看 AVDD 引脚,如果高频噪声明显,加大去耦电容,必要时在电源入口加磁珠或 LDO。
- 参考电阻两端噪声。RREF 两端是 ADC 的参考电压,它上面的噪声会直接反映到转换结果上。周围如果有数字信号线高速翻转,尽量拉开距离。
- PGA 增益和数据率的配合。增益高加数据率也高时,噪声肯定大。把数据率降到 20SPS,噪声通常会有明显改善。
- 接线是否绞合。RTD 两根引线必须双绞,否则磁场耦合会让共模噪声变成差模噪声。
4.2 UART 通信偶尔丢字节,数据错位
UART 通信不稳定,最常见原因是波特率误差。PIC18F46K22 内部振荡器虽然校准过,但温度变化后可能会有偏移。如果你发现热机后通信频繁出错,多半是振荡器漂移导致的波特率偏差。
解决办法有几个:
- 降波特率,比如从 9600 降到 4800,容错时间窗变宽。
- 改用外部晶振,稳定性更好。
- 在 UART 线上加 RC 滤波,或者用带光耦隔离的方案。
另外,如果 ADC 和 MCU 之间的地线回路比较大,UART 电平在瞬态噪声下容易误判。工业现场布线时,ADC 侧地线和 MCU 侧地线要尽量短,最好单点接地。
4.3 换了三线制 RTD 后,温度还是偏
三线制要真正起作用,必须保证两根引线电阻对称。我在现场见过很多次,工人把三线制传感器接成三根不同长度的线,或者用不同线径的线续接,这等于没做三线补偿。
还有一个容易忽略的点:IDAC 电流档位要选合适。如果电流太小,信号幅度不足;电流太大,RTD 自身发热会造成自热误差。PT100 我常用 500uA~1mA,PT1000 用 250uA~500uA,这样自热影响可以控制在 0.1°C 以内。
4.4 冷端补偿怎么调都差一两度
热电偶冷端补偿不准,多数情况是冷端温度传感器和热电偶的冷端不在同一个温度点上。ADS122U04 内部温度传感器反映的是芯片内部温度,如果你把热电偶连接器贴在 PCB 板上,但芯片发热明显,内部传感器读到的温度和连接器实际冷端温度就会有偏差。
解决办法有几个思路:让热电偶冷端尽量靠近芯片的引线区域,同时在 PCB 上做等温区设计,减少热梯度;或者干脆用外置 PT1000 贴在端子排上直接测量冷端温度,再代入热电偶多项式计算。后者在工程上更可靠,尤其是环境温度变化大的场合。
4.5 切换通道后读数要等多久
如果系统配置了多个通道,比如同时测回风温度和盘管水温,每次切换 MUX 后不能立刻读数据。ADC 内部滤波器和 PGA 需要建立时间,通道切换后至少要等几个转换周期。很多人设计多通道扫描时,切完通道马上启动转换,结果前几次读数都是上一通道的残余值。
我习惯的做法是:通道切换后先丢弃当前通道前 2~3 次转换结果,再开始正常采样。这样牺牲一点点响应时间,换来的是数据可靠性。
5. 工程落地经验与后续扩展方向
5.1 从样机到量产,供电和 EMC 是重头戏
实验室里跑得好好的板子,一到现场就飘,多半是供电和 EMC 的问题。温度采集板在工业现场通常和接触器、变频器、水泵电机装在一个柜子里,干扰环境非常恶劣。
我的建议:
- 电源入口加 TVS 管和共模电感,防浪涌和共模干扰。
- ADC 模拟部分供电单独走 LDO,不要和 MCU 数字供电共用一路开关电源。
- 所有传感器线都用屏蔽线,屏蔽层单端接地,避免形成地环路。
- PCB 上模拟地和数字地单点连接,不要让数字电流流过模拟地平面。
另外,批量标定一定要有流程。每个通道的增益误差和偏置都要测,不能只校准一个通道就批量套用。ADS122U04 有多个输入通道,每个通道的开关导通电阻虽然很小,但并不是完全一致,批量生产时通道之间的校准值要分开存。
5.2 扩展方向:从单机采集到总线组网
这套系统再往上发展,自然就是组网。PIC18F46K22 还有一路多余的 UART,可以直接挂 Modbus RTU,把温度数据上报给 PLC 或楼宇自控系统。ADS122U04 负责模拟采集,MCU 负责协议栈,各干各的活,架构非常清晰。
如果现场干扰特别大,考虑在 UART 和 MCU 之间加数字隔离器,把模拟侧和数字侧完全隔开。隔离后系统的共模抑制能力会提升很多,但要注意隔离电源的噪声,不要因为隔离反而引入了更大的电源纹波。
5.3 关于成本的一点看法
很多人一看到 24 位 ADC 就觉得贵。但实际上,对于工控和暖通产品来说,PCB 面积、调试时间、售后维护成本往往比几块钱的芯片差价更值钱。ADS122U04 这种把激励源、基准、温度传感器、UART 全部集成在一起的方案,省掉了外围一堆分立元件,整板物料成本和布板难度反而更低。
手头正在做相关项目的朋友,我个人建议是先把比例测量的电阻网络搭好,用精密电阻箱熟悉读数规律,再上热电偶和冷端补偿这些复杂功能。温度测量这行没有玄学,所有异常都能在“噪声、参考、接线、校准”这四个维度里找到解释。把这几个环节的功夫下足了,剩下的就是把数据算准、把产品做稳。