做工业和HVAC的控温、测温,跑不掉的硬件组合里,ADS122U04IPWR配dsPIC33FJ256GP710A这套方案,可以说既省心又够深。ADS122U04IPWR是TI的24位Δ-Σ ADC,自带UART接口和两个匹配IDAC电流源,天生适合把PT100/PT1000电阻信号拉直成温度值;dsPIC33FJ256GP710A则负责系统控制、数据解析和后续的风机、阀门、加热器联动。这篇文章把整套东西从选型、硬件、固件到调试踩坑一次讲透,适合正在做HVAC控制器、工业变送器、设备监测的工程师参考,也适合刚从SPI转UART接口ADC的入门者做个对照。
1. 项目到底要解决什么问题
1.1 工业与HVAC测温场景的真实痛点
先别急着谈芯片,得把场景说清楚。工业现场测温,典型对象是压缩机排气温度、冷却液温度、轴承温度,量程可能从-40℃到150℃甚至更高,现场有变频器、继电器、接触器,电磁环境乱得一塌糊涂。HVAC这边稍微温和一点,风管温度、冷冻水进出水温、回风温度这些被测点,精度要求往往只有±0.5℃甚至±1℃,但胜在点多、线长、常年连续运行。
这两类场景的共同点是:传感器用PT100或者PT1000居多,信号幅度很小,PT100在0℃时只有100Ω,温度变化1℃对应的电阻变化不到0.4Ω。如果用MCU自带的12位ADC直接采,哪怕满量程5V,一个LSB也有1.2mV,对应到电阻上想分辨0.1℃非常吃力。更别说MCU ADC的参考电压一般就是电源,电源本身有纹波,参考一抖,结果全是噪声。
所以这类系统需要一个外置高分辨率ADC,而且最好是集成激励源的ADC,否则还得自己搭恒流源。ADS122U04IPWR就是冲着这个需求来的:24位分辨率、集成两个匹配IDAC、可编程PGA、内部温度传感器,连50Hz/60Hz工频抑制都考虑进去了。这些特性组合起来,做RTD测温几乎就是标准答案。
1.2 为什么选UART接口的ADS122U04,而不是SPI版本
ADS122U04这个型号,你第一眼会注意到它和常见的ADS1220长得很像,引脚管脚也有点类似,但关键区别是接口从SPI换成了UART。有人可能觉得UART慢、不好弄,但从系统层面看,UART在工业设备里反而是最稳的通信方式之一。
我选UART接口有几个很实际的理由。第一,dsPIC33FJ256GP710A作为主控,本身要挂人机界面、RS485通信、PWM输出,SPI资源往往已经被Flash、外部RAM或者其他传感器占满,UART倒是经常有富余。第二,UART对时序的要求比SPI宽松,SPI的SCK和CS必须严丝合缝,而UART只要波特率对准、帧格式对,中间随便插什么操作都不容易断链。第三,ADS122U04支持一种演示模式,上电后不需要写任何配置寄存器,自己就开始转换并通过UART把数据发出来,这对开发阶段验证硬件通路极其方便。
当然,UART接口也有代价,最明显的是数据吞吐量不如SPI,但对温度测量这种每秒几十个点的需求来说完全够用。而且ADS122U04真正的价值在于它把模拟前端做得很完整:多路复用器、PGA、IDAC、基准电压缓冲器都集成进去了,主控只需要通过UART收数,算温度,干控制。
1.3 整机数据流:传感器如何一步步变成控制量
完整系统的信号链是这样的:PT100/PT1000探头接入ADS122U04的模拟输入,芯片内部的IDAC电流源提供激励电流,测量电压经过PGA放大和Δ-Σ调制,最后由数字滤波器输出24位转换结果,通过UART发送给dsPIC33FJ。dsPIC33FJ拿到原始码之后,先做帧同步、校验、24位补码转有符号数,然后结合基准电阻RREF的阻值算出当前RTD电阻,再经过查表或多项式拟合得到温度值,最后用这个温度值去跑PID、去控制压缩机和风机、或者送给RS485/Modbus总线上给楼宇控制器。
这套架构的妙处在于,从传感器到温度值的每一环都是确定性的,没有模拟量经过长距离传输被干扰的环节。ADC靠近传感器信号源,数字信号再往外传,抗干扰能力天然就强。后面所有章节都是围绕这条信号链展开的,硬件设计保证信号质量,固件保证精度和可靠性。
2. 硬件设计与核心电路拆解
2.1 RTD探头接入与比例式测量原理
有人第一次看ADS122U04的数据手册,容易误以为它就是个普通ADC,接上传感器、读数据、完事。实际它的正确打开方式是比例式测量,就是让同一个IDAC电流既流过RTD,又流过基准电阻RREF,然后把RREF上的电压当作ADC的参考电压。
为什么非要这样绕一圈?因为IDAC电流源本身有温漂,假如你用独立基准电压,那么激励电流随温度变化一点,RTD上的电压就会跟着变,而且这个误差会直接折算成温度误差。比例式测量把电流源这个变量消掉了,因为RTD电压和参考电压都是同一个电流产生的,两个电压的比值只取决于电阻阻值的比值,与电流大小无关。这就像拿两把尺子同时量东西,尺子本身长一点短一点不影响比值。
具体到电路接法,ADS122U04内置两个匹配的IDAC,典型三点连接是把IDAC1接到RTD的一端,IDAC2接到RTD另一侧的引线上,同时在靠近ADC参考输入的位置串入精密电阻RREF。匹配电流源的好处在于,两条引线上的压降可以互相抵消,三线制RTD引线电阻的影响就被压缩到极低水平。当然,对两线制探头或者要求更高的四线制场景,引脚接法稍有差异,但核心思路不变。
RREF的选择是有讲究的,不能随手拿个电阻就上。选RREF前你要先算:量程上限对应的RTD电阻Rmax,激励电流I,则满量程信号电压Vmax=I×Rmax;同时RREF上的电压就是参考电压VREF=I×RREF。PGA增益G决定了ADC的满量程输入范围是VREF/G,我通常按Vmax落在满量程70%~90%来反推RREF。
以PT100测0~150℃为例,这一段的电阻从100Ω到157Ω左右,我习惯用I=250μA、RREF=1.5kΩ、PGA=8。这样VREF=0.375V,ADC满量程约46.9mV,RTD在150℃时的压降约39.3mV,刚好是满量程的84%,既不削顶,又充分利用了ADC的动态范围。如果测PT1000或者更宽量程,参数要重新算,RREF一般选1.5kΩ到8.2kΩ这个区间。
2.2 电源、参考电阻与去耦布局
ADS122U04的模拟电源AVDD和数字电源DVDD是分开的,这在24位ADC上是常规操作,但很多人还是会踩坑:两个电源倒是分开了,却在PCB上用了同一片LDO输出,中间连一个0Ω电阻就算隔离。我在实际项目里是拿两路独立LDO,一路给AVDD,一路给DVDD,模拟电源单独走星形接地,数字部分的地电流绝不允许回流经过模拟地。
DVDD这个点很有说法,很多评估板直接把DVDD接在AVDD上,能用但噪声不好压。我后来发现把DVDD单独供电有个额外好处:UART的电平匹配更方便。dsPIC33FJ的I/O是3.3V,DVDD也给3.3V,两边电平就完全对齐,不用加电平转换。
RREF这个电阻才是精度关键,它直接决定参考电压,也就直接决定测量比例。我自己做产品时选的是0.1%精度、温漂小于10ppm的精密电阻,如果预算有限,至少也要0.1%。你算一笔账就明白:RREF有1%的误差,温度测量就会带进约2.5℃左右的偏差,这个误差还随温度漂移,软件校准都不好校。
去耦同样不能省。ADS122U04每个电源脚都要有0.1μF陶瓷电容,靠近引脚放;模拟输入和IDAC输出之间还要放RC低通滤波器,我常用100Ω和1μF组合,截止频率约1.6kHz,既能滤掉高频干扰,又不会把慢变的温度信号压没。所有的电容都要用X7R或C0G材质,X5R和Y5V电容在直流偏置下容量会大幅缩水,这是很容易被忽视的点。
2.3 PCB走线与抗干扰的实战经验
PCB布局这块,我给的第一个建议是模拟信号线和UART数字线彻底分开。ADS122U04的UART引脚在demo模式下以固定速率往外吐数据,线上的信号跳变如果耦合到模拟输入,你会在转换结果里看到规律的毛刺。我最早一块板子把UART_TX线贴着AIN0走,结果噪声底比后来重排走线的版本差了将近一倍。
第二个建议是给模拟输入加防护。工业现场的长线缆会耦合各种共模干扰和浪涌,即使是测温这种低速信号,我也习惯在每个模拟输入端对地并联一个100pF电容和一颗低漏电的TVS管。注意TVS的结电容不能太大,否则会把PGA输入带宽压下来。
第三个建议涉及传感器线缆。如果探头离主控板超过一米,强烈建议用屏蔽双绞线,屏蔽层单端接地,而且只接在探头侧,避免形成接地环路。我曾经为了图省事把屏蔽层两端都接地,结果在雷雨天被感应出来的环路电流害惨了,整板读数漂了好几度。
关于接地,不要搞什么模拟地数字地分割成两半的激进操作。现在高分辨率ADC都支持所有地连成一片完整地平面,只要保证数字电流不穿过模拟敏感区域就行。地面分割反而会导致回流路径变大,形成更大的环路面积,更容易拾取干扰。
3. 固件实现:从UART帧解析到稳定温度输出
3.1 ADS122U04初始化与demo模式的实际体验
ADS122U04 datasheet里专门讲了一种简化UART配置,叫demo模式。这个模式下芯片上电就开始转换,连寄存器都不用配置,用起来就像开一盏灯那么简单。我开发初期就是靠这个模式验证硬件通路,几分钟就能在示波器上看到UART波形,省去了配置寄存器的调试时间。
但demo模式也有它的局限:默认配置不一定适合你的传感器类型和激励电流。假如你打算精调PGA增益、IDAC电流、数据率、滤波模式,就必须走完整寄存器配置流程。寄存器配置通过UART下发命令完成,之前我踩过一次,命令帧一看就懂,但容易漏看寄存器里某几位对全局的影响。比如数据率寄存器改了,不仅转换速度变了,内部数字滤波器的陷波频率也跟着变,后面工频干扰的抑制效果全看这一步。
不管用哪种模式,有一点必须确认——波特率。ADS122U04这类UART型ADC的波特率是按数据手册约定值工作的,上电后不会自动协商。我第一次调板子时没仔细看手册,以为默认是115200,结果示波器一看波形乱码,后来把逻辑分析仪直接挂在TX线上,量了实际位宽才搞清楚。所以我的建议是别猜波特率,数据手册说多少就设多少,实在不行先用逻辑分析仪看波形数脉宽。
3.2 dsPIC33FJ256GP710A端UART驱动与帧同步
dsPIC33FJ256GP710A的UART模块配置其实不算复杂,但是有几个细节值得注意:一是传输字长要配成8位、无校验、1个停止位,二是波特率寄存器BRG要根据你确认过的波特率反算,三是接收中断要开足够高的优先级,因为温度数据帧是连续到达的,中断稍微被其他任务堵一下就可能丢字节。
我用的是中断加环形缓冲区的标准做法,UART1接收中断把每个字节压入环形缓冲,主循环里再抽帧。环形缓冲的好处是中断处理时间极短,不阻塞PWM和通信任务。实际写下来大概这样:
typedef struct { uint8_t buf[64]; uint8_t head; uint8_t tail; } ring_t; volatile ring_t rx_ring; void __attribute__((interrupt, no_auto_psv)) _U1RXInterrupt(void) { while (IFS0bits.U1RXIF) { rx_ring.buf[rx_ring.head] = U1RXREG; rx_ring.head = (rx_ring.head + 1) % 64; IFS0bits.U1RXIF = 0; } }帧同步是这里最值得花心思的地方。UART本身没有像SPI那样的片选信号,你自己要知道哪几个字节属于一帧。ADS122U04每帧有一个状态字节作为第一个字节,里面带数据就绪标志和故障标志,我就拿状态字节的固定标志位来做帧头。主循环每次从环形缓冲区取字节,先找状态字节特征,找到后连续取够帧长,再跑一遍CRC或者帧长校验,通过了才算完整帧。
帧同步里我栽过的跟头是:只凭固定标志位找帧头,偶尔会发生错一位的情况。后来我在状态字节里同时检查两个已知固定的位,并增加CRC校验,就再没出现过解析错位的现象。
3.3 24位数据解析、电阻计算与温度转换
拿到完整帧之后,原始码解析并不复杂,ADS122U04输出的是24位二进制补码。假设帧缓存f里f[1]是高字节、f[2]是中字节、f[3]是低字节,解析成有符号数就是:
int32_t ads_raw_decode(uint8_t *f) { int32_t raw = ((int32_t)f[1] << 16) | ((int32_t)f[2] << 8) | f[3]; if (raw & 0x800000) { raw -= 0x1000000; } return raw; }接下来从原始码换算电阻。比例式测量下,当输入电压等于参考电压时,输出码接近满量程2^23-1,所以RTD电阻为:
float rtd_resistance(int32_t raw, float rref) { return (float)raw * rref / 8388608.0f; }这里有个隐藏前提:你的PGA增益和参考电压已经被上面讲的硬件设计固定住了,码值比例只与RREF相关,所以固件里不需要再管PGA设置。这个特性让程序通用性特别强,换不同量程的探头时,只需要改RREF和后面的温度拟合表。
电阻转温度,我强烈建议用查表加线性插值,而不是硬套一个高次多项式。PT100的电阻-温度曲线在0℃以下是二次关系,0℃以上接近线性但仍有弯曲,用一个三次多项式想要覆盖-40~150℃全量程,数值计算量不小,而且容易在边界产生振荡。查表法只需要存一个每隔5℃或10℃的电阻点表,插值计算量极小,精度还能做到0.05℃以内。
HVAC场景如果只需要显示和控制,线性近似也能凑合,但工业场合我建议老老实实查表。插值代码就几行,查找到相邻的电阻点后线性内插,温度值就出来了。如果后续还要做PID,最好在固件里再跑一级滑动平均,把探头本身的热噪声滤干净,控制输出才不会来回抖。
4. 实测中踩过的坑:噪声、漂移与通信异常
4.1 工频干扰看起来小,实际很闹心
ADS122U04内部数字滤波器对工频有一定的抑制能力,但这个抑制能力是依赖于数据率的。你把数据率设成某个值,滤波器频率响应上就会有对应的陷波点,只有当陷波点正好落在50Hz或60Hz上,工频抑制效果才成立。很多人不看手册的滤波器响应曲线,随手选了一个看起来很快的数据率,结果50Hz噪声全都混进来了。
我在HVAC控制器项目上第一次带电调试时,发现温度读数始终在0.3℃左右周期性摆动,摆动周期正好是20ms,一看就是50Hz工频串扰。后来我把数据率档位调低,让内部滤波器陷波点覆盖50Hz,硬件上的RC低通也把截止频率进一步压低,波形才稳定下来。
软件层面还有一个补救办法,就是输出做均值滤波。温度信号本身变化很慢,对最近16次或32次有效转换取平均,既不会损失实时性,又能把残余的周期性噪声磨掉。要注意均值滤波的窗口大小必须包含完整的工频周期,如果每次转换间隔是50ms,那就取至少20个点,否则平均效果会打折扣。
4.2 数据偶尔跳变,先怀疑数字串扰而不是ADC
有段时间我的读数大部分时候都非常稳定,但每隔几十秒会出现一个明显偏离真实值的跳点。一开始我怀疑是传感器线缆接触不良,排查了很久才发现罪魁祸首是板上另一路UART在高速发送Modbus数据时,数字总线上的电流突变通过公共地阻抗耦合进了模拟输入。
这种偶发跳变是最难查的,因为它不是持续性问题。我的排查思路是先做隔离实验:断开和ADC通信的主控程序,手动给UART发送连续已知序列,同时观察读数;如果读数还很干净,说明问题不在ADC采样链,而在其他外设的干扰。逐步挂起不同外设,很快就能定位到干扰源。
定位之后处理方式也简单,把ADC的模拟地引脚单独的过孔直接打到主地平面,别和数字连接器共用一个回流路径,再给模拟电源脚加一个10μF和0.1μF的并联电容组,跳变就消失了。说穿了就是一句话:高分辨率ADC要把它当成模拟前级来供地和去耦,别当成普通数字芯片随便接。
4.3 UART断帧和乱码,八成是波特率或帧同步问题
UART通信偶发断帧,大家可能都觉得是干扰,但我在实测中发现,最常见的原因反而是波特率没有精确匹配。ADS122U04的波特率由内部振荡器决定,dsPIC33FJ的UART波特率由系统时钟分频得到,两边只要有一点偏差,在连续大量数据传输时就可能丢位。
排查方法是先跑一个长时间连续采集,比如让模块跑一到两个小时,同时在主机侧记录CRC错误次数。CRC错误次数随温度变化明显增多,说明振荡器温漂在作怪,这时候要么把波特率容忍度放宽,要么在固件里每隔一段时间做一次波特率重同步。如果用的是内部FRC振荡器,温漂相对大一些,我的做法是DS P33FJ的UART开启自动波特率检测功能,以接收到的数据边沿实时校准,效果很好。
帧同步错位又是一个不同的问题。状态字节的某些位在转换过程中状态不同,如果你只凭其中一个位做帧头识别,很可能把数据字节误判为状态字节。我最后采用的做法是双条件:检查状态字节的固定标志位,同时检查CRC字节,只有两者同时成立才确认是完整帧。这个组合验证之后,我再没有遇到解析错乱的情况。
4.4 温度漂移的校准方法
温度漂移和绝对精度是两回事。绝对精度靠RREF精度和传感器本身保证,但系统里总有放大器失调、引线电阻残余、焊点热电动势这些因素,它们会在整个温区里造成一个可预测的偏差,校准就是把这个偏差抹掉。
我在产线上用的最简单的两点校准:一个标准冰点0℃,一个恒温槽设到100℃,分别记录ADC计算的电阻值R0和R100。然后按线性模型校正,实际电阻R_corr = a×R_meas + b,其中a和b由两个校准点解出来。这个做法覆盖工业温区足够用,精度能做到±0.2℃以内。
如果你没有恒温槽,也可以用精密电阻箱代替传感器,分别给100Ω和138.5Ω的模拟阻值,这样校准过程和探头的类型无关,更灵活。产线的校准数据我会存在dsPIC33FJ的数据Flash里,每台设备单独存一份,后续维护换板时可以直接导出比对。
5. 从开发板到量产,这几个细节决定成败
5.1 长线缆、浪涌和ESD防护不能省
实验室里用短飞线连探头,怎么玩都行;一到实际现场,传感器线缆可能要走两米甚至十米,沿途还可能和动力电缆一起走线槽。这时候只剩屏蔽和防护了。我在ADC输入端加的TVS管和串阻,就是为了扛IEC 61000-4-2级别的静电放电,实际测试下来比裸板好太多。
同时,HVAC控制器一般要过浪涌测试,模拟输入端口最好设计成可插拔的端子,板子上预留了抗浪涌器件的位置。如果不预留,EMC整改时想加都加不上,只能重新画板。这是很多工程师容易忽略的成本点。
5.2 自检与故障上报,工业现场刚需
ADS122U04的状态字节里带了传感器开路和短路的检测标志,这个一定要用起来。HVAC风机盘管系统里,温度探头常年工作在震动和潮湿环境中,线缆断裂是很常见的故障。我做的固件在每帧数据里都会检查状态位,一旦发现开路或故障,立刻记录故障码,并把输出置成安全值,而不是继续拿错误的温度去跑控制。
还有一点是关于看门狗的。dsPIC33FJ256GP710A运行控制系统后,主循环一定要喂狗,但没有必要每轮循环都喂,我是在完成一次完整的采集、计算、输出控制后才喂一次。这样万一UART卡死或者算法跑飞,看门狗能可靠复位,故障不会演变成持续的错误输出。
5.3 后续扩展:多点测温与现场总线集成
这套方案还有一个很自然的方向:多路温度采集。ADS122U04本身有多路模拟输入,你可以把多个RTD接到多路复用器上轮询,前提是在固件里处理好稳定的余毒时间——每次切换通道后要丢弃前几帧数据,等模拟前级稳定。我试过四路PT100轮询,效果稳定,但代价是单点刷新率降下来了,HVAC场景够用。
如果点数还要更多,则可以每路ADC配一个dsPIC33FJ做从机,通过RS485总线把温度值上报给中央控制器。这种分布式测温架构在大型楼宇里很常见,每个控制箱负责一片区域的温度采集和控制,总线的数据量和可靠性的平衡也很好。
最后再分享一个小经验:ADS122U04IPWR这类高分辨率ADC的模拟输入,上电瞬间一定要等到电源稳定后再读,否则第一次转换结果大概率是异常的。我在固件里做了延迟等待和首帧丢弃,设备上电后的第一个有效温度值就非常干净。这套方案我自己从原理图到量产跑了两轮,整体稳定性确实对得起这组芯片的搭配。