先交代一个背景:我手头有几条空调机组和工业冷水机的温度测点,过去一直用模拟量采集卡加PT100变送器,一路一路接,接线麻烦不说,抗干扰和标定都是问题。后来把方案整体切换到“ADS122U04IPWR + dsPIC33EP512MU814”的组合,用UART总线和内置恒流源直接对PT100/PT1000高精度测温,整机稳定性和调试效率都上了一个台阶。这篇就把这个组合从选型、原理、硬件、固件到调试做个完整记录。
这篇内容适合正在做工业温度采集、HVAC楼宇控制、冷水机组、AHU机组、恒温箱等产品的人参考。不管是用24位ADC替换模拟量输出传感器,还是想把多点温度采集整合进自己的控制器MCU,这套思路都能直接用。
1. 这个组合到底解决什么问题
1.1 为什么是ADS122U04而不是ADS1220/SPI方案
行业内一提到高精度测温ADC,很多人第一反应是ADS1220或者ADS124S08这等SPI接口芯片。ADS122U04实际上是ADS1220的UART版本,型号里的“U”代表UART接口。选它而不是SPI版本,不是性能差异,而是系统的通信架构完全不同。
过去用SPI接口ADC,每路传感器就得专门拉一组SCLK、MISO、MOSI、CS,这在主控板上就是4根线的开销。路数一多,PCB布线、GPIO分配、隔离成本都会膨胀。ADS122U04走UART,意味着它可以挂在RS-485总线、板级UART总线甚至无线透传链路上,单总线最多挂16片(硬件地址4位),每片支持两路差分输入、三路单端输入。一套系统里想测12路温度,只需要一根双绞线从主控串出来,霍尔地址拨码设好,板上规模立刻小下来。
另外一点很现实:工业设备里主控芯片通常本身就有UART资源,而且很多传感器节点和主控之间本来就要走长线。长距离用SPI非常容易受地电位差和干扰影响,而UART转RS-485是成熟得不能再成熟的工业通讯方式,隔离也容易做。ADS122U04的UART波特率最高可以到1Mbps,测温这类数据量很小的场景,9600或115200完全够用,低波特率反而带来更好的抗干扰能力。
1.2 dsPIC33EP512MU814在这个项目中的位置
很多工程师看到“dsPIC33EP512MU814”会问,温度采集而已,有必要上这么高规格的数字信号控制器吗?512KB Flash、64KB RAM、70 MIPS主频,看起来是大材小用。但请注意项目背景:这是工业和HVAC应用,不是实验室桌面测量。
工业温度采集从不会是孤立的。测完温度还要做PID调节、压缩机启停逻辑、电子膨胀阀控制、风机调速、报警阈值判断、历史数据记录和上位机通讯。这些任务放在8位单片机上也勉强能跑,但一旦温度采样要做40Hz/60Hz工频陷波、传感器非线性补偿、多点平均值滤波、PID运算,8位机就力不从心了。
dsPIC33EP512MU814真正强的地方是它自带DSP内核指令集,可以在一次指令周期内完成乘加运算。做PID和滤波时,它可以直接用DSP指令,用汇编或C语言写定点算法,效率非常自然。512KB Flash还能给OTA升级、多语言菜单、参数备份留出足够空间,不会被塞满。
从系统架构上看,这套组合的另一层意义是:ADC负责模拟前端,MCU负责协议处理和控制算法,两个芯片各干各的,职责边界清晰。ADS122U04通过UART把数字温度值直接送进dsPIC33,模拟信号在进入MCU之前已经是数字域的东西了,整个链路的抗干扰能力和一致性都显著强于传统的NTC + 模拟调理方案。
2. 温度测量的核心原理与关键技术
2.1 RTD测温的四个坑:引线电阻、自热、非线性、激励一致性
测PT100/PT1000这类电阻温度探测器(RTD),原理上就是用已知电流给传感器激励,然后测传感器两端的电压,再根据电阻-温度关系反推温度。这话说起来简单,工程上四个坑躲不掉。
第一个是引线电阻。PT100在0℃时只有100Ω,每升高1℃只增加约0.385Ω。如果传感器和测量板之间拉了两米线,铜线电阻一看就是0.1Ω到0.5Ω量级,这相当于0.3℃到1.3℃的误差,根本没法接受。这也是为什么工业现场要么用三线制,要么用四线制,直接两线制只有在导线很短很粗或者做粗测时才敢用。
第二个是自热效应。给RTD通1mA电流,在传感器上产生的功耗是1mW,放在静止空气里测室温,自热误差可能到0.1℃以上。放在流动液体里会好很多。所以激励电流的选择必须权衡:电流太小,有效信号幅度低,ADC的分辨率优势发挥不出来;电流太大,传感器自己把自己加热了。
第三个是非线性。PT100的电阻-温度关系并不是一条直线,尤其是超过200℃后,二次项和三次项的影响越来越明显。不考虑非线性,在400℃时误差能达到好几度。标准处理方法是查表或者用Callendar-Van Dusen方程拟合。
第四个是激励一致性。如果激励电流源不稳定、基准电压和激励电流不同源,温度系数会成倍放大。比如激励电流变化了10ppm,对应到最后温度读数可能不止10ppm的误差,因为电压信号里同时包含了激励波动造成的“信号变化”和“基准漂移”,两个误差叠在一起。
2.2 ADS122U04如何用“比例测量”帮你绕开这些坑
ADS122U04有个传统ADC没有的设计:内部集成两个可编程激励电流源IDAC1和IDAC2,以及一个用于比例测量的内部基准。内部基准可以配置为使用外部基准输入引脚,也可以直接使用内部2.048V基准。重点在于比例测量模式。
比例测测量思路是这样的:让同一个激励电流同时流过传感器RTD和参考电阻Rref,然后分别测RTD上的电压和Rref上的电压,两者相除。因为流过两个电阻的电流是同一个,电流源的波动会被约掉;基准电压的漂移也会被约掉,因为转换结果本质上是一个电压比。这就像拿同一把尺子量两段物体,尺子长一点短一点,测出来的比例关系不变。
具体在ADS122U04里怎么工作:IDAC电流从IDAC1引脚流出,经过RTD,再经过参考电阻Rref到GND,返回。ADC的模拟输入分别接RTD两端,同时参考电压输入REFP和REFN直接跨接在Rref两端。这样ADC输出码值直接就是RTD电阻与Rref电阻的比值乘上满量程,公式如下:
ADC_Ratio = (V_RTD / V_Rref) = R_RTD / R_Rref
24位ADC的输出码值约等于 (R_RTD / R_Rref) × 8388607。只要Rref精度够高、温漂够小,比例测量模式下整个测量链路几乎不受激励电流源和内部基准漂移影响。实际工程中Rref选0.1%精度、25ppm温漂的金属膜电阻,就能保证整机全温度范围内的测量一致性。
四线制接法下,激励电流走独立的电流线,测量线不承载电流,引线电阻上的压降不会被测量到,误差进一步归零。三线制则靠测量线中的电流平衡抵消引线电阻,代价是需要两个IDAC分别从两端注入相等电流。ADS122U04有两个IDAC,天然就是为三线制和四线制设计的。
2.3 传感器选型与参数计算:从PT100到PT1000
PT100经典,但功耗和引线电阻问题比较敏感。PT1000的好处是自身阻值高10倍,同样温度下信号电压也高10倍,引线电阻造成的误差相对小一个数量级,自热功耗在同样电流下只有PT100的1/10。HVAC应用里风管温度、回水温度这些低温和温差测量场景,我通常直接推荐PT1000,因为激励电流可以小到0.25mA或0.5mA,长线上信号衰减影响很小。
ADS122U04的IDAC电流范围是0mA到1.5mA,可编程幅度分档:0.25mA、0.5mA、0.75mA、1mA、1.5mA。做一下计算最直观:
用PT1000,激励电流选0.25mA,0℃时传感器压降是0.25V。加上PGA增益,比如8倍,输入ADC的满量程信号是2V。但如果内部基准选择2.048V,那对于PT1000在0℃到150℃范围内电阻变化约390Ω,电压变化0.0975V,放大8倍后0.78V,仍然占用满量程的38%,分辨率完全够用。如果测温范围是-50℃到+150℃,可以缩小到0℃到150℃的预期区间,利用PGA和基准的配合,把信号尽量放满。
选PT100时,激励电流通常选0.5mA或1mA,0℃时压降0.05V或0.1V,必须开PGA增益到16或32,信号才够大。PT1000的优势在这个环节就体现出来了:相同信号幅度需求下,PT1000允许更小的激励电流,自热更低,PGA增益也不用开那么高,噪声表现更好。
3. 硬件电路设计与PCB实操细节
3.1 最小系统原理图拆解:从传感器端到MCU端
ADS122U04系统的原理图核心可以分成四块:RTD传感器接入、参考电阻与激励路径、数字接口与控制引脚、电源和去耦。
传感器接入部分,如果是三线制PT100,接线方式为:从IDAC1引脚引出激励电流,经过RTD,再从另一端经过参考电阻Rref回到GND;同时ADS122U04的两个模拟输入引脚AIN0和AIN1,分别接在RTD的两端。两个IDAC都要用,第二个IDAC从测量线另一侧注入一个相等电流,用于抵消线阻压降。四线制更简单,IDAC电流线和传感线完全分开,AIN0/AIN1上几乎没有电流流过。
参考电阻Rref的取值和满量程设计直接相关。测量PT100,Rref选820Ω或1kΩ比较合适;测量PT1000,Rref选2kΩ或2.05kΩ。Rref两端一定要跨接到REFP和REFN引脚上。这个电阻我强烈建议选金属箔电阻或低温漂薄膜电阻,温度系数25ppm以下是基本要求,5ppm更好。不少人在这里图便宜用了普通贴片电阻,结果低温时测量曲线整体偏移,怎么标定都拉不回来。
控制引脚上,ASEL0到ASEL3是地址选择,改写地址后就能在同一条UART总线上区分多个芯片。DRDY是数据准备好引脚,接到MCU的外部中断输入,每次转换完成就拉低一次。RESET引脚用一个普通的RC复位电路即可,如果MCU有GPIO,也可以直接由GPIO控制做硬复位。
电源去耦方面,AVDD和DVDD分开走,每路用0.1uF加10uF组合。ADS122U04的数字部分功耗很低,重点是模拟电源的干净度。如果板上有开关电源,模拟电源必须单独用LDO,确保纹波低于10mV。很多温度漂移问题根源不是传感器,而是供电纹波被调制到了模拟信号上。
3.2 UART总线上的多点测温网络
ADS122U04的UART协议比较特殊,它支持多设备寻址。通信流程大致是:主机发送一个地址字节并带有读/写标志,然后发送命令字节和附加数据字节,从机根据地址字节里的设备地址判断是否响应。实测下来,这套协议在单机模式下很简单,但多机模式下必须严格遵守时序,尤其是命令帧之间的间隔。
多机接线有两种典型方式。板级短距离,直接TTL电平共用TX/RX总线,多个ADC的TX引脚用开漏方式或通过二极管隔离并联。长距离工业现场,则把UART信号转RS-485,每个ADS122U04节点附近放一个RS-485收发器。推荐使用带自动方向切换的RS-485芯片,比如MAX13487这类,省去MCU控制DE引脚的时序麻烦。
地址分配用硬件拨码开关最可靠,ASEL0~ASEL3四根线的编码组合,正好对应16个地址。拨码开关的IO口加上拉电阻,分别接到芯片的ASEL引脚。上电时芯片锁存地址,运行中不能更改。
UART帧格式的参数设置:波特率9600或19200,8数据位,无校验,1停止位。ADS122U04内部的命令帧包含了起始字节、命令类型、通道选择、数据。要注意的是,ADS122U04的UART时钟来自内部RC振荡器,总体误差在±2%以内。因此建议不要跑超过115200的波特率,否则片间时钟误差累积会导致错帧。
3.3 PCB布线的几处强迫症细节
第一处是参考电阻Rref的位置。Rref必须紧贴ADS122U04的REFP和REFN引脚,距离尽量控制在5mm以内,路径上不要有其他走线穿过。因为Rref两端的电压就是整个比例测量的基准,任何铜箔阻抗串进参考路径,都会变成参考误差。
第二处是模拟输入走线和RTD传感线。AIN输入是高阻输入,走线尽量短;如果必须走长线,用屏蔽线或者差分对走线,并且在芯片输入端加RC滤波。ADS122U04自带一个可编程的输入滤波器,但外部RC仍然有用,尤其是在强电磁干扰环境。典型值:2.2kΩ串阻加10nF电容,截止频率大约7kHz,对工频和射频干扰都有衰减。注意这个RC会引入很小的时间常数和衰减,但在测温场景里影响可以忽略。
第三处是模拟地和数字地。ADS122U04这类小封装ADC,我一般用单点接地策略:整个板子的模拟地和数字地在ADC的GND引脚附近单点相连,不要把模拟地信号和数字地信号混杂。UART信号线走线避开模拟输入区域,不要在参考电阻正上方走过。
第四处是ESD保护。工业现场传感器线缆经常从外面接入,雷击浪涌和静电不可避免。传感器端子和信号线必须加TVS管,参考地和保护地之间用电容和压敏电阻隔离。ADS122U04的输入引脚耐压有限,坏一个芯片虽然成本不高,但现场售后代价太高,输入端先保护再进芯片是必须的。
4. 固件实现:从UART时序到稳定读数
4.1 配置寄存器到底写了什么
ADS122U04的寄存器配置和ADS1220基本一致,有四到五个配置寄存器,这里说最关键的两个。
第一个是配置寄存器0,主要设置输入多路复用器MUX选择、PGA增益和供电模式。测量单路RTD时,MUX位配置为AIN0和AIN1作为差分输入对,PGA增益根据传感器类型设置。PT1000用PGA=4或8,PT100用PGA=16或32。每次配置完之后,建议读回校验一下,确认写入生效。
第二个是配置寄存器1,包含转换模式、数据速率、滤波器模式和传感器检测电流源。连续转换模式适合温度实时监控,单次转换模式适合低功耗电池应用。数据速率选择20SPS配合50Hz/60Hz工频抑制,这个后面详细说。
之所以强调“读回校验”,是因为UART协议相比SPI更容易出现地址错误或者帧错位。主控写入后马上读回,不一致就重新配置,可以避免一个非常隐蔽的bug:寄存器根本没写进去,芯片还在用默认配置跑,测温结果完全不对。
写一个完整的寄存器初始化代码(基于dsPIC33EP系列,C语言),逻辑大概是:
void ads122u04_init(void) { uint8_t tx_buf[5]; uint8_t rx_buf[5]; // 等待芯片内部上电复位完成 delay_us(10); // 复位到默认状态 adc_write_cmd(CMD_RESET); delay_ms(50); // 配置寄存器0: 差分输入AIN0/AIN1, PGA=8, 正常工作 tx_buf[0] = 0x40 | ADC_ADDR; // 写配置寄存器0 tx_buf[1] = 0x10; // AIN0/AIN1差分, PGA=8, 正常模式 uart_send_packet(tx_buf, 2); delay_us(100); // 配置寄存器1: 连续转换, 20SPS, 内部参考, 常规滤波 tx_buf[0] = 0x40 | ADC_ADDR | 0x01; tx_buf[1] = 0x20; // 20SPS, 连续转换模式 uart_send_packet(tx_buf, 2); delay_us(100); // 配置寄存器2: 使能IDAC1, 0.5mA, 从PIN1输出 tx_buf[0] = 0x40 | ADC_ADDR | 0x02; tx_buf[1] = 0x31; // IDAC1使能, 0.5mA, 输出到AIN1 uart_send_packet(tx_buf, 2); delay_us(100); }寄存器值的具体位定义要以数据手册最新版本为准,芯片批次不同可能会有细节差异。这个代码是框架,不是直接抄完就能跑的。
4.2 一次完整的数据读取流程
ADS122U04的单次转换读取时序是这样的:主机发送命令让芯片开始单次转换,等待DRDY引脚变低,然后主机发送读数据命令,芯片返回3字节的24位数据。
DRDY引脚在连续转换模式下会周期性拉低,这个信号可作为中断源。dsPIC33EP512MU814的外部中断输入接到DRDY后,每次中断一次,就在中断服务程序里发起UART读取。不用阻塞等待时间,也不容易丢失转换结果。
实际项目中我更常用一个带状态的机流程,避免在主循环里卡在UART发送上:
- DRDY中断触发,置位转换完成标志;
- 主循环发现标志后,构造读数据帧发送;
- 等待接收完成中断,把3字节拼成24位数据;
- 将原始码值送入温度换算模块;
- 清标志,等待下一次DRDY。
中间UART收发用FIFO缓冲。dsPIC33EP的UART模块自带4字节FIFO,配合DMA甚至不需要CPU逐个字节搬运。对这个项目,我建议直接用中断方式,CPU占用率很低,代码逻辑也简单。
读回来的数据不是温度,是原始ADC码,比例测量模式下需要自己换算。换算公式要写清楚:
float adc_code_to_temperature(int32_t raw_code, float rref) { float ratio = (float)raw_code / 8388607.0f; // 24位ADC码值比例 float rtd_ohms = ratio * rref; // 由比例算出RTD阻值 float temp_c = rtd_to_celsius_pt1000(rtd_ohms); return temp_c; }这里用float是可以接受的,dsPIC33EP有硬件浮点单元,单精度浮点运算很快。如果用定点处理,也可以把ratio放大1000倍后用int32运算,但浮点在这个主频下完全没压力。
4.3 温度换算、线性化与滤波工程实践
RTD的电阻-温度关系,标准做法是用查表法。把PT100或PT1000的分度表,按0.5℃或1℃间隔做成const数组,存到Flash里,运行时根据电阻值做线性插值。这个方案实现简单,不依赖复杂数学函数,工程上最保守也最可靠。
如果不想查表占Flash,可以用Callendar-Van Dusen方程直接计算。PT1000在0℃到850℃范围内的表达式近似为:
R(t) = R0 × (1 + A×t + B×t²)
其中A约为3.9083e-3,B约为-5.775e-7,在0℃以上这样拟合误差很小。0℃以下需要加C项,对于HVAC场景通常测不到零下很多,可以不用。
我的做法是:冷启动时先查一次小步长表,把粗值算出来,再用相邻两个分度值做线性插值,误差控制在0.05℃以内,Flash占用也小。每个传感器类型单独建一个转换函数,PT100和PT1000分开,不要让程序中同时出现“这项乘以10”这种魔法数字,后面维护的人会感谢你。
滤波部分最实用的是中值滤波再加滑动平均。温度信号是慢变信号,工频和射频干扰会叠加到原始码值上。ADS122U04的ΔΣ调制器本身对高频噪声有很强的抑制,但如果现场有大功率变频器,还是会在数据里看到毛刺。用5点中值滤波可以把偶发毛刺剔掉,再用16点滑动平均让输出变得平滑。注意滤完波之后整个通道的响应时间会变长,HVAC温控允许几秒钟的滞后,但工业快速过程就不合适。
关于数据速率和工频抑制,ADS122U04在20SPS、16.7SPS等速率下内置了50Hz/60Hz陷波。如果现场是50Hz电网干扰,就把速率设成20SPS,这样每个转换窗口正好是50ms,是工频周期的整数倍,干扰被天然消除。如果中值滤波加了但数据还是抖,先检查是不是速率没设对。
5. 调试实录:我踩过的坑和排查方法
5.1 UART通信总断开、偶尔错帧
第一次把板子连起来,发现一个诡异现象:单独测一片ADS122U04一切正常,挂了三片之后,偶尔会出现某一帧数据完全不对,有时候干脆没有应答。
分析过程是这样的:三片ADC并联在TTL总线上,正常工作时只有一个设备在驱动总线,但ADS122U04的UART发送引脚在未选中时也可能处于弱驱动状态,或者帧时序出现毛刺,就会和主机发出的数据互相干扰。解决办法,给每个ADS122U04的DOUT引脚串一个100Ω电阻再并联到总线上,相当于做隔离和抑制反射。
另外一个更隐蔽的问题是,多设备共用一个UART总线时,主机发送完整命令帧后必须等从机应答超时后才发起下一条。有些工程师在命令之间只加了很短的延时,结果从机还没处理完上一条命令,主机就开始发下一条,导致从机认为收到了错误地址字节。实测下来,单条命令和读取之间至少要留出等价于3个字节的传输时间,保险起见用1ms延时。
如果还是频频错帧,把波特率降到9600,往往问题直接消失。温度采集场景不需要高波特率,稳定比速度重要。
5.2 温度读数漂移、在0.1℃级别跳
读数漂移分两种:短期抖动和长期漂移。
短期抖动通常来自电源纹波或者传感器引线干扰。用示波器探头在AIN引脚上看毛刺,如果看到几十mV级别的交流分量,基本可以确定是干扰进入模拟前端。排除方法是输入端加RC截止频率更低一些的低通滤波,比如把电阻加大到10kΩ,电容加大到100nF。但注意RC和PGA输入阻抗的匹配,太大阻值会引入测量误差。
长期漂移最常见的原因是参考电阻Rref自身的温漂。比例测量消除的是电流源漂移,不能消除Rref本身的温度系数。Rref如果用的是25ppm/℃的普通贴片,环境温度变化10℃,参考电阻变了250ppm,这就会导致电阻读数同样偏移250ppm。对PT100来说,对应温度误差约0.06℃。我后来把所有Rref全部换成5ppm的金属箔电阻,长期稳定性立刻改善。
还有一种情况不要忽略:传感器线缆受到机械应力,接插件氧化接触电阻变大,也会表现为温度读数缓慢漂移。用热成像看板子不一定看得到,直接用手去拨弄接线端子,看读数有没有变化即可判断。
5.3 传感器开路/短路检测的正确姿势
传感器开路如果不去检测,ADC输入悬空时读数会趋向满量程或者随机值,控制逻辑可能认为当前温度极高,触发错误动作。ADS122U04内置了传感器检测电流源,用这个功能做在线诊断非常方便。
开路的典型特征是RTD阻值无穷大,比例测量比值接近满量程。短路的特征是比值接近0。固件里可以在每次正常测温前,额外做一次通电检测,通过配置寄存器临时开启检测电流源,读回来的码值如果接近满量程或者接近0,直接报警。
我更建议的是在正常模式里同时监控两次转换:正常比例转换 + 开尔文检测。两次转换之间的时间开销很小。对于HVAC系统,传感器开路报警非常重要,比如空调系统里温度传感线断了,很可能导致控制器认为回风温度极低而猛开加热,造成严重后果。必须把开路检测作为常规诊断流程,而不是偶发维护手段。
处理策略上,我通常把开路和短路作为故障状态上报,而不是当成一个具体温度值。让主控进入故障保护模式,而不是拿着一个虚假温度去做PID调节。这一点在评审和现场使用中都获得了一致认可。
另外,传感器接线端子最好留一个短接片,方便现场做回路测试。把传感器拆下来短接端子,测出来的温度如果是接近基准电阻对应的温度,说明板端链路是好的;如果还是异常,那问题就在传感器线缆本身。这种分段排查法在现场效率很高。
6. 这套方案之后还能怎么扩展
最后再聊点延伸。ADS122U04的UART特性让它天然适合做分布式温度采集,一个dsPIC33EP512MU814主控可以管理几十个温度节点。配合RS-485总线,传感器可以分布在设备的不同角落甚至不同房间,而主机只需要两根双绞线。这套架构在大型HVAC系统里,比传统的模拟量采集卡布线上优势非常明显。
如果后续要做无线版本,UART接口也可以直接接一个串口透传模块,每个节点作为一个无线传感器终端,主控用无线网关统一管理。这样系统扩充到几十个温度节点也不会乱。
在传感器校准上,如果要求整机精度优于±0.2℃,建议出厂时做两点校准,比如0℃冰点和100℃沸点。因为比例测量已经把大部分系统误差消掉了,两点校准主要是修正参考电阻的基准偏差和传感器个体差异。校准数据存到dsPIC33EP的Flash里,每台设备独立管理,维护时也可以一键标定。
我个人操作下来的体会是,真正让这个方案跑顺的,往往不是芯片本身多高端,而是把参考电阻选对、把UART时序和滤波策略做稳、把故障检测纳入常规流程。这些细节看着琐碎,但在实际项目中决定了设备到底是在实验室里表现好,还是在现场一年四季都稳定可靠。这套组合我已经连续用了两个产品项目,整体表现完全值得推荐。