去年做一套工业组合式空调机组的温控改造现场要求把冷冻水供回水温度、新风温度、回风温度、表冷器盘管温度全部采回来一共七八个点而且传感器到控制柜的走线最短也有十几米。原来那套方案是NTC热敏电阻加运放放大再走0-10V模拟量进PLC结果夏天一开变频器显示温度直接跳两三度根本没法做PID。后来换了ADS122U04IPWR加TM4C129XKCZAD的组合一条UART线把四路高精度温度全部收进来再用TM4C129处理换算、滤波和Modbus上报稳定得让我有点意外。这篇文章把整套方案从芯片选型、传感器接入、寄存器配置、固件实现到现场校准和踩坑记录完整写出来。内容更适合正在做工业温度采集模块、HVAC楼宇自控或数据采集网关的软硬件工程师或者准备用高精度ADC替换传统模拟链路的同学参考。1. 从“运放万用表”到“串口ADC”这套组合解决的三个实际问题1.1 工业现场多点测温的困境工业暖通场景下的温度测量难点从来不在“测不准”三个字而在“一直测不准”和“多个点一起不准”。传统的模拟链路通常是传感器信号经过长线传输到控制柜再进隔离变送器和模拟量输入模块。只要现场有大功率变频器、接触器或开关电源这些模拟小信号就会叠加共模干扰和差模噪声。NTC和热电偶本身输出阻抗匹配不好长线还容易产生天线效应采集结果跟着负载电流一起波动。但改用数字输出传感器或ADC之后最大的变化就是把模拟信号到数字信号的转换尽量往前移靠近传感器端。ADS122U04IPWR这种带UART接口的24位ADC刚好可以把前端放大、滤波和模数转换都做了输出的就是数字量抗干扰能力和传输距离都比传统模拟方案强得多。1.2 ADS122U04IPWR 的定位带UART的24位精密ADCADS122U04IPWR 是TI推出的一款24位、4通道、Δ-Σ架构ADC和常见的SPI接口ADC最大的区别是它自带UART接口。这一点在工业现场特别实用因为UART可以很方便地转成RS-485长距离传输和多设备组网都很成熟相比SPI的短距离片选方式布线灵活性和抗干扰能力都更好。芯片内部集成了可编程增益放大器PGA增益从1倍到128倍可选还带两个可编程激励电流源IDAC可以直接驱动RTD热电阻。此外还有内部温度传感器、电压基准、系统监视器和CRC校验功能。一组24位ADC配合4通道输入选择器用模拟多路开关的方式就能在几类温度传感器之间切换不需要额外布置一片多路复用器。开发板级别的设计里一片ADS122U04加几个电阻电容就能搭出完整的多路温度采集前端。也有朋友问我既然TM4C129XKCZAD自带ADC为什么还要外挂一片ADS122U04答案很简单普通MCU内置ADC一般只有12位精度INL、温漂和噪声都达不到工业级温度测量的要求。HVAC要控制温差在正负0.5℃以内12位ADC配合传感器很难稳定完成。ADS122U04的24位核心让温度分辨率能轻松做到0.001℃级别虽然实际系统精度受传感器和校准限制但至少硬件上限不会被ADC卡住。1.3 TM4C129XKCZAD 管整个系统更看重协议栈与外设TM4C129XKCZAD 属于TI Tiva C系列Cortex-M4F内核主频120MHz带浮点单元。对于温度采集这种计算量不大的任务CPU性能完全够用。真正让我选它的是两点一个是内置以太网MAC和PHY可以直接做网络上报HVAC项目里接到楼宇自控网络非常方便另一个是多路UART外设一路接ADS122U04一路做调试打印还能再留一路给RS-485走Modbus RTU接口完全不冲突。TM4C129XKCZAD的硬件UART带FIFO还能触发中断配合DMA可以做到比较高效的数据接收。在ADS122U04连续转换模式下数据会以固定的时间间隔到达UART用FIFO加中断驱动MCU不用一直空转等待可以腾出CPU时间去跑控制逻辑和通信协议。这套组合的实际价值是MCU只负责“管理”和“上报”前端测量真正的高精度工作全部交给独立ADC完成数字隔离也更容易做。整个系统的模拟部分集中在一片芯片上PCB布局和抗干扰设计都简单很多。2. 温度传感器接入RTD、热电偶、热敏电阻的电路与配置ADS122U04IPWR支持多种类型的温度传感器不同传感器对应不同的输入MUX配置、PGA增益和激励电流源设置。这也是我在HVAC现场最喜欢它的原因一个板子兼容四种传感器只要改配置和接线端子就行。2.1 三线/四线PT100的激励电流与比例测量工业和HVAC里最常用的是PT100铂电阻0℃对应100Ω温度系数大约0.385Ω/℃。测量PT100最标准的方法是用恒流源激励然后测电阻两端电压再用比例法消除电流源的误差。ADS122U04内置IDAC电流源可以设置10μA到1.5mA等不同档位。对PT100我习惯把IDAC1设置为1mA激励电流从IDAC1引脚输出经过PT100后回到AIN0或AIN1同时用同一路电流在外部精密基准电阻上产生参考电压实现比例测量。这样即使电流源有温漂ADC的码值和参考电压同步变化计算结果不受影响。接线方式上四线制效果最好两根线给RTD供电两根线单独测电压线电阻完全不进入测量回路。但HVAC现场大量已经是三线制PT100三线制的接法同样支持关键是让两根引线的电阻分别落在激励回路和检测回路的同一臂上通过差分测量抵消线电阻影响。ADS122U04的差分输入可以直接接AIN0和AIN1MUX配置为AIN0-AIN1差分对即可。PGA增益的设置要结合传感器输出电压和ADC参考电压来算。PT100在0℃时100Ω1mA激励产生100mV电压在100℃时约138.5Ω产生138.5mV。如果把外部参考电压设为2.048VPGA16时有效输入范围大约是±2.048V/16±128mV0℃到100℃的差分电压刚好落在这个范围内。想留更多裕量可以用PGA8分辨率仍然很高。2.2 热电偶的冷端补偿思路K型热电偶是测温范围和性价比比较均衡的选择工业风管温度、高温冷水机组排气温度都会用到。热电偶的输出信号很小K型大约40μV/℃所以必须把PGA放到64倍甚至128倍。ADS122U04在PGA128时配合2.048V参考电压理论分辨率非常高足够分辨0.01℃级别的热电偶电压变化。热电偶本身测的是测量端和冷端之间的温差冷端必须做补偿。ADS122U04内部集成温度传感器可以直接读取芯片附近的结温作为冷端参考。但更稳妥的做法是在热电偶接线端子附近贴一个PT100或高精度NTC采集端子的实际温度再在固件里做冷端补偿。因为ADC内部温度传感器反映的是芯片温度和接线端子之间会有热阻误差特别是机箱内有发热元件时这个误差可能达到1℃以上。我把热电偶的正极接AIN0负极接AIN1同时在AIN0到AIN1之间并联一个100nF滤波电容再在每一根线上串联一个1kΩ电阻。这个RC滤波能滤掉高频干扰不会明显影响低频温度信号。配置寄存器时要打开输入偏置电阻功能给热电偶提供一个对地或对AVDD的直流偏置路径否则浮空的热电偶会把共模电压拉到不可控的范围。2.3 热敏电阻和0-10V/4-20mA变送器输入HVAC里还有很多NTC 10k热敏电阻比如壁挂式温控器、风管温度传感器。NTC的阻值随温度变化是非线性的但测量方法比RTD简单用固定参考电阻和NTC组成分压电路再测量分压点的电压。ADS122U04的IDAC电流源同样可以直接激励NTC但要注意NTC在低温时阻值会很大如果激励电流太大电压可能超过ADC输入范围一般用100μA或250μA比较合适。对于4-20mA电流环变送器温度已经被变送器转换成电流信号ADC只需要测量电流在采样电阻上的压降。常用250Ω精密电阻20mA时压降5V超过ADS122U04的输入范围所以要把采样电阻减小到100Ω20mA时2V再用PGA1配合2.048V参考电压测量。这个方法在工业现场非常实用因为很多风管温湿度传感器的信号输出都是4-20mAADC通道可以统一兼容硬件上只需要在端子上并一个采样电阻。3. UART链路与ADS122U04寄存器配置比特率、CRC和连续转换ADS122U04和TM4C129XKCZAD之间走的是UART这要求两边在比特率、帧格式、校验和通信时序上严格按照手册配合。我把这一层的配置和调试过程完整拆开讲。3.1 硬件连接TM4C129的UART外设接法TM4C129XKCZAD的UART模块引脚是CMOS电平3.3V和ADS122U04的电源域一致可以直连。需要特别注意TX和RX是交叉连接的MCU的TX接ADC的RXMCU的RX接ADC的TX两头共地。板子上的电平和ESD保护也要处理。ADS122U04的UART引脚虽然是数字接口但引到端子后可能受到外部静电或瞬态干扰。我在UART线靠近接口的地方各串了100Ω电阻并加TVS管到地。如果应用要求更远的传输距离我会在TM4C129和ADC之间加一片支持3.3V侧电平的RS-485收发器把UART信号转成差分信号实测在100米双绞线上仍然能稳定通信。ADC的UART波特率支持多档具体用多少取决于系统时钟和噪声环境。我的经验是9600bps最稳定适合布线复杂的工业柜但数据量不能让电路切换频率。11200bps或更高速率需要把时钟源配准否则长期运行偶尔会出帧错误。TM4C129的UART波特率生成寄存器也要做同样的计算确保两边误差小于2%。3.2 寄存器配置流程从复位到启动ADS122U04的UART协议核心是读写寄存器和启动转换。上电后我先做一次软件复位等10ms让内部基准和PGA稳定然后依次写配置寄存器。Config0寄存器负责输入MUX和PGA设置。比如测量PT100时寄存器值包含AIN0-AIN1差分、PGA16、PGA旁路关闭。Config1寄存器设置转换模式和输出速率HVAC应用我选择连续转换模式输出速率20SPS或50SPS开启50Hz/60Hz工频抑制滤波器。Config2寄存器设置IDAC电流源大小和输出引脚测量PT100时设为1mA并输出到AIN0。Config3寄存器选择内部温度传感器是否启用、是否需要烧毁检测。通用的启动流程可以归纳成这几步上电后等待电源稳定发送复位命令。配置UART帧格式、比特率、使能CRC。依次写Config0到Config3建议每写一个寄存器后读回验证。启动连续转换等待数据准备好。读取转换结果检查CRC和溢出标志。如果切换传感器类型先停止转换重新写Config寄存器再启动。读回验证这一步特别重要。我遇到过一次写Config2后ADC完全没有激励电流输出后来用读回命令发现写入值和读回值不一致查出来是I2C地址? 准确说是UART命令帧的地址位错了。所以每次写寄存器后都读一遍能省非常多调试时间。3.3 数据格式与CRC校验的实际处理ADS122U04转换结果是24位二进制补码读取后要放在一个有符号32位变量里先判断符号位再除以8388608归一化。有的工程师直接把24位数据塞进uint32_t结果负数全部变成很大的正数后面算温度就全错了。数据帧末尾有CRC校验字段这个不能省。工业现场的UART长线上偶发一位错误很正常如果没有CRC偶尔会出现一个远离真实值的跳点。我固件里对每一帧都做CRC8校验校验不过直接丢弃这一帧不把它送进滤波队列。这样做之后大量毛刺都在通信层就被过滤掉不会污染后面的温度滤波和控制逻辑。CRC计算可以用查表法占用大概256字节Flash非常适合TM4C129XKCZAD这种Flash充足的MCU。不要试图在中断里逐位计算CRC那样会拖慢中断响应。把UART数据先收进DMA缓冲区收完一整帧再统一校验CPU占用率非常低。4. TM4C129XKCZAD固件设计状态机、缓冲区和温度换算硬件链路正常工作之后固件架构就决定了整个系统的稳定性和可维护性。我没有把ADS122U04的驱动直接写在主循环里而是拆成三个层次UART硬件抽象层、ADC协议层、传感器应用层。4.1 驱动层拆成三块避免以后改传感器时重写代码UART硬件抽象层只做一件事提供字节发送和整帧接收回调。这一层直接操作TM4C129XKCZAD的UART寄存器把收到的字节放进环形缓冲区同时做奇偶校验和帧超时判断。应用层完全不用关心UART细节。ADS122U04协议层负责构造命令帧、解析响应帧、校验CRC、维护当前寄存器配置。对外提供类似ads122u04_read_single()和ads122u04_start_continuous()这样的接口。传感器类型变化时只需要改协议层里的配置参数应用层代码一行都不用动。传感器应用层处理的是“前一个温度是什么、下一个温度是什么、要不要做平滑滤波”。这层可以放自己的平均滤波器或一阶低通滤波也可以在这里做温度单位换算。我习惯把滤波放在寄存器码值层面因为此时信号还是线性电压比例关系滤波更物理如果先把码值换算成温度再滤波非线性传感器会引入额外误差。4.2 原始码值到工程单位的换算比例测量RTD时温度换算分两步。第一步把ADC码值换算成电阻值。如果外部参考电阻Rref和RTD共用同一个IDAC激励那么RTD电阻值 Rref × (code_rtd / code_ref)这里code_rtd是RTD通道读数code_ref是参考电阻通道读数。内部参考电压和IDAC温漂都会被约掉这是最稳定的比例测量方式。第二步把电阻值换算成温度。PT100在0到100℃范围内可以用线性近似但要做更高精度建议用IEC 60751的多项式查表或者用查表加线性插值。MCU有浮点单元直接算多项式也不慢。我实测用分段线性插值表表里每10℃一个点插值计算出的温度误差小于0.05℃固件Flash只占1KB左右。热电偶的换算稍微复杂一点。先把24位码值换算成电压然后用标准热电偶分度表做温度查找。冷端温度要先换算成对应的毫伏值加到测量电压上再查表得到真实温度。这整个过程里最容易出错的是冷端电压和测量电压的单位要一致否则结果可能差几十度。4.3 多通道扫描时序与实时性ADS122U04是单ADC四通道输入本质上通过输入MUX切换来测量多个传感器。每切换一次通道内部输入滤波器和PGA都需要建立时间如果立即读取会混入上一个通道的残余信号。我的做法是在切换通道后丢掉前两三次转换结果从第四次开始取数。以20SPS采样率计算四通道一轮下来大约需要0.8秒对HVAC这种惯性很大的温度控制场景完全够用。实时性要求高的场景我会把“切换通道”和“读取结果”做成两个独立状态。空闲时设置好下一通道并启动转换收到数据中断后把结果存入对应通道的环形缓冲区再设置再下一通道。这样MCU不会在等待ADC转换期间死等控制周期也不会被通道数拖累。TM4C129XKCZAD的DMA功能值得利用。连续转换模式下ADC每隔一段时间输出一帧数据如果全部靠UART中断接收CPU会被频繁打断。我配置了UART的DMA接收每收满一帧触发一次完成中断在中断里只做CRC校验和内存拷贝整体CPU占用不到5%。5. 工业HVAC场景的校准与误差预算别让软件精度浪费硬件精度硬件电路和固件都跑通之后最影响最终测量精度的就是校准和误差分配。很多工程师设计时只算ADC分辨率忽略了传感器误差和零点偏置最后整机精度还不如一个水银温度计。5.1 零点和满量程校准省去复杂计算公式ADS122U04虽然有24位精度但输入前端和PGA难免存在失调电压外部基准电阻也有容差。所以每台设备出厂前都要做两点校准。我用高精度电阻箱模拟PT100在0℃和100℃时的阻值分别记录ADC码值然后计算增益系数和偏移量存到TM4C129XKCZAD的Flash里。如果现场没有电阻箱可以用高精度的100Ω和138.51Ω精密电阻代替误差也能做到很小。校准的流程大概是在0℃校准点接入精密电阻等待读数稳定记录码值offset。在100℃校准点接入精密电阻记录码值gain。用两点式直线方程算出换算系数。把系数写入Flash并在下次上电时加载。校准之后系统零点和增益都被修正到一个很理想的状态。不过要注意校准温度和实际工作温度接近效果最好因为PGA增益随温度的变化不会被两点校准完全消除。误差要求高的场合可以在不同温度点做三点校准插值使用。5.2 冷端温度校准与传感器匹配热电偶通道的冷端校准要单独处理。如果用ADS122U04内部温度传感器做冷端要提前标定芯片温度和端子温度之间的偏差。我在恒温箱里设置几个温度点读取内部温度传感器值和端子附近PT100的实测值做成一个校正表。这样在0到70℃环境范围内冷端补偿误差可以控制到0.3℃左右。如果是RTD通道传感器本身的精度也不能忽略。普通PT100 B级精度是±0.3℃0℃但加上AD转换误差和接线端子接触电阻整体误差会进一步变大。对高精度HVAC计量建议选A级PT100并且在端子上用冷压端子压接不允许直接拧螺丝因为长期震动会导致接触电阻漂移。5.3 误差项的叠加估算我把一套典型系统的误差预算列出来方便你做选型参考。假设是A级PT100四线制外部基准电阻0.1%ADS122U04内部基准温漂10ppm/℃校准后残余增益误差0.01%环境温度变化范围20℃误差来源典型误差范围说明PT100 A级电阻精度±0.15℃传感器自身误差基准电阻容差±0.05℃比例测量已消除大部分ADC INL和增益误差±0.03℃校准后剩余激励电流温漂±0.02℃比例测量后影响很小量化噪声±0.001℃24位下可以忽略冷端误差RTD无此项-仅热电偶相关总计典型值±0.25℃满足HVAC控制要求这个误差估算的意义在于如果传感器本身误差是±0.3℃硬件电路做得再好系统测试精度也不可能优于±0.3℃。所以选传感器时一定要看等级参数不能只看分辨率。6. 实测中踩过的坑EMC、供电噪声和调试技巧再好的芯片如果供电和布局不合理也发挥不出性能。这一部分记录我在调试和现场试运行过程中遇到的几个问题都是常规文档里不容易注意到的细节。6.1 开关电源纹波造成的转换跳动第一次打样时我用24V开关电源经过DC-DC降到5V再经LDO降到3.3V给整板供电。ADC单独由LDO供电但DRDY引脚和UART线上还是能测到100mV级别的小脉冲噪声。表现为温度读数在0.1℃范围内来回跳不是一直偏而是随机跳动。排查过程比较曲折。先怀疑是软件滤波不够把滤波窗口加长到10秒现象有所缓解但没根除。后来用示波器对比AVDD引脚和UART数据线发现每次UART发送命令时AVDD上都会出现一个尖峰。原因是ADC的数字IO和模拟电路共用了一个3.3V电源域数字开关噪声通过电源耦合进模拟前端。解决方法是把ADS122U04的AVDD和DVDD分别用两个LDO供电中间用磁珠隔开模拟地和数字地单点连接。更进一步我把UART线换成双绞线并在ADC侧增加RC滤波。改动后同样位置测下来转换结果非常平稳长期运行没有再现跳动。如果在预算允许的情况下也可以给ADS122U04配一颗专用基准源比如REF5025之类把REF引脚的输入噪声压到个位数微伏级别。对于HVAC这种0.5℃精度的应用内部基准已经够用但发烧级追求可以用外部基准。6.2 地址冲突和多设备总线调度当系统里同时挂多片ADS122U04时UART总线调度就会复杂起来。ADS122U04支持通过命令设置设备地址上电默认地址是某个值。我在一次多板测试中因为两片ADC都忘了修改地址导致MCU发一条指令后两片同时响应接收缓冲区数据全部乱掉。解决方法是上电时只让一片ADC的通信线使能其他片保持高阻或断电然后逐一对每片写入独立地址之后才允许共同挂到总线上。这相当于一个“上电分配地址”的流程。我把这个流程做进了生产测试程序后续现场更换ADC板卡时也用同样的方式分配地址彻底告别冲突问题。单片ADC应用的情况下地址冲突不会出现但要注意UART帧的应答超时。如果ADC正在忙转换没有及时应答MCU要设置超时重试。我一般把UART超时定为50ms超过就丢弃并重新发送同步命令。6.3 调试利器监听UART报文调试这个系统最有效的方法不是盯着温度数值看而是把ADS122U04和TM4C129之间的UART报文全部抓出来。我用TM4C129的另一个UART作为调试口把ADC收到的每一帧原始数据打印出来同时打印解析后的码值、CRC状态和温度值。有了这组日志可以很清楚地判断温度异常是通信链路问题还是换算问题。比如码值变化正常但温度不对那大概率是换算公式或查表边界错误如果码值本身就跳那就要回头查供电、接地和传感器接线。这个习惯帮我节省了很多瞎猜时间。另外ADS122U04的DRDY信号很好用。调试时把它接到TM4C129的一个GPIO上并在GPIO中断里翻转一个调试引脚用示波器同时观察DRDY和UART数据帧的时间关系可以确认数据是否在转换完成后才被读取。如果数据在ADC还没转换完成时就启动读取读回来的是上一通道旧值这一个问题能造成很多莫名其妙的现场故障。最后再分享一个经验ADS122U04的寄存器配置和CRC校验一旦写好就不要频繁改动。把配置表固化下来只开放传感器类型和通道数两个参数。现场调试越简单量产一致性越好。