ADS122U04与dsPIC30F4011工业温度采集方案:从硬件到固件全解析
发布时间:2026/11/5 3:14:07 锦皓数字建站

做工业温度采集这么多年有个组合我一直觉得被低估了ADS122U04IPWR加dsPIC30F4011。一个是被动式的、带UART接口的高精度24位ADC另一个是老牌DSP内核单片机很多HVAC控制器、工业变送器用它们搭配干活沉稳、便宜、好调试。今天就围绕这个组合把温度测量从硬件到固件再到校准的完整链路讲透顺带把我在实际项目中踩过的坑一并交代。1. 项目整体设计与思路拆解1.1 温度测量需求到底要解决什么问题先别急着看芯片先把场景拆开。工业现场和HVAC系统里温度量测通常有几类典型传感器PT100/PT1000铂电阻、K型/J型热电偶、NTC热敏电阻偶尔还有电流环输出的温湿度传感器。它们各有脾气铂电阻线性度好但激励电流需要稳定热电偶输出微弱电压、必须做冷端补偿NTC便宜灵敏但非线性严重、一致性差。一个通用的温度采集模块要同时兼顾这三种传感器对ADC的要求就集中到几个指标上分辨率要高24位起步才有裕量去分辨微小温差尤其是热电偶每度只有几十微伏输出。可编程增益要够PGA能把毫伏级信号放大把小信号从噪声里捞出来。要有恒流源/激励源给PT100/PT1000提供激励避免外部恒流电路引入额外误差。通信接口要简单工业板上常用UART能直接把ADC挂到MCU上接线少隔离也方便。环境耐受要好工业环境有共模干扰、电网谐波、电机启停浪涌ADC要扛得住。ADS122U04就是冲这几个需求来的四通道、24位、带PGA和双恒流源最关键的是它有UART接口而不是传统的SPI/I2C。这在长线传输和电源隔离场景下简直是救星因为UART信号可以用光耦或磁耦直接隔离SPI的同步时钟隔离起来就麻烦得多。1.2 为什么是 ADS122U04IPWR 而不是别的 ADCADS122U04是TI家的产品后缀IPWR表示TSSOP-16封装、工业级温度范围。它在ADS1220系列的基础上增加了UART接口内部集成了24位Δ-Σ ADC核心噪声低至大约4.6µVppPGA12820SPS典型值4路输入支持差分和单端混用两个可编程激励电流源电流档位从50µA到1500µA可选可编程增益放大器PGA从1到128内部2.048V基准源也可以外部输入基准内部温度传感器用来做冷端补偿或者环境温度监测数据速率从20SPS到2000SPS可选UART接口波特率可配支持CRC校验选它的核心原因不是某一项指标惊艳而是组合得当。比如你去看很多工业变送器方案为了抑制50Hz工频干扰会刻意把采样率设在20SPS或者60SPS实现ADC内置滤波器对工频及其谐波的高衰减。ADS122U04正好有20SPS档位还带同步的50/60Hz抑制。配合内置PGA和恒流源一个芯片就把模拟前端大半工作干了板面积压缩得非常厉害。1.3 dsPIC30F4011 在系统里的角色dsPIC30F4011是Microchip的16位DSP控制器30MHz内核有DSP引擎适合做PID、滤波、补偿计算。它在这个项目里的任务很简单但也不轻松用UART和ADS122U04通信发送命令、读回转换结果根据传感器类型做线性化和冷端补偿执行数字滤波均值、去极值、一阶低通根据温度结果驱动输出继电器、MOS管、4-20mA环、PWM风扇如果系统有CAN总线用它自带的CAN控制器把温度上报给上位机很多人对dsPIC30F4011不熟它其实是比PIC24更早的16位机外设丰富ADC、PWM、I2C、SPI、UART、CAN、正交编码器接口程序闪存有48KBRAM 4KB对温度采集这种中等复杂度的任务绰绰有余。而且它的UART模块带FIFO和错误检测非常适合和外部ADC做长帧通信。选它还有个现实原因很多老产品线已经在用dsPIC30F系列固件库和硬件积累成熟升级改造时不用推翻重来。2. 硬件设计细节与板级要点2.1 引脚分配与最小电路ADS122U04IPWR是TSSOP-16引脚不算密手工焊接都能搞定。关键引脚如下引脚功能连接建议AVDD模拟电源3.3V经磁珠/RC滤波后接入DVDD数字电源3.3V与AVDD分开走线AIN0-AIN3模拟输入接传感器或保护电路IEXT1/IEXT2恒流源输出接PT100等传感器REFP/REFN基准输入推荐使用外部精密基准REBP/REBN内部基准去耦接0.1uF电容TXD/RXDUART数据接MCU对应引脚RESET复位上拉至DVDD可选RCCLK时钟内部时钟可悬空或接外部晶振最小电路不要忘记给DVDD和AVDD之间加一个0欧电阻或者磁珠数字噪声不能窜到模拟供电上。AVDD引脚附近放一个10uF和0.1uF的电容组合这是老规矩但很多人只放一个0.1uF结果噪声指标打折扣。恒流源输出IEXT1和IEXT2在驱动PT100时最好从传感器的远端引回导线接到AIN输入形成比例测量。比如用IEXT1给PT100供电PT100一端接AIN0另一端接到AIN1公共端。这样激励电流的漂移不会再影响测量结果因为ADC读的是PT100两端电压和基准电压的比例基准电压又可以取自同一个激励电流流过的精密电阻做比例测量后电流变化就自动抵消了。2.2 模拟前端的设计滤波、保护和偏置ADS122U04内置了PGA但这不代表输入就可以裸奔。工业现场传感器线缆可能很长感应雷、电机启停尖峰、共模电压都可能直接打在ADC引脚上。我的做法是输入端串联电阻每路输入串1kΩ到10kΩ电阻限制异常电流。Δ-Σ ADC输入是开关电容结构串联电阻大了会影响建立时间但20SPS低速场景下影响很小我用4.7kΩ很稳。差模滤波电容在差分输入两端加一个0.1uF聚丙烯电容配合串联电阻构成低通滤波截止频率大概几百赫兹足够了。TVS保护用双向TVS管从AIN对地泄放选击穿电压略高于AVDD的型号比如5V左右。钳位电压别选太低否则正常共模信号被削掉。共模电压问题如果传感器和ADC参考地之间存在压差差分输入的共模范围会受限。建议在AIN输入加上参考地的共模电阻分压或者直接用低值电阻把AIN-端偏置到AVDD/2。热电偶场景比较特殊热电偶信号是一个直流毫伏信号而且热电偶引线可能接触外部金属管路所以输入端最好加一个射频滤波电容几百pF防止射频干扰解调进去同时用共模电感或ferrite bead处理长线上的共模噪声。2.3 电源和基准精度从这里分水岭ADS122U04内部有2.048V基准温度系数典型值约10ppm/°C这个指标对一般HVAC够了但要拿去做0.1%精度以上的工业变送器还是建议外接基准。我习惯用REF50252.5V或MAX61262.5V/2.048V这类低噪声基准给REFP/REFN供电。注意基准的接地是关键REFN必须直接连到模拟地而且从基准输出到REFP的走线要短旁边加0.1uF和10uF电容。基准电源独立甚至可以用专门的LDO供电避免数字电源纹波通过基准耦合到ADC。另外一个容易被忽略的点是AVDD和DVDD的关系。如果数字电源和模拟电源都用同一个3.3V数字噪声会通过电源窜到ADC导致有效分辨率下降。建议用一个小LDO给AVDD单独供电中间串磁珠DVDD从MCU电源域取电。实测下来电源隔离做得好噪声能低一半。2.4 PCB布局经验别让走线毁掉一颗好ADCADS122U04是低速高分辨率ADC布局要遵守模拟器件的老规矩但也不用过度迷信四层板。两层板也能做关键点单点接地模拟地和数字地在ADC下方单点连接不要大面积铺通了事。所有模拟信号回流的路径完整。传感器信号线走线AIN输入线尽量短远离数字信号尤其是UART TX/RX和PWM线。如果必须交叉走线垂直穿过。UART线与模拟输入隔离UART是数字信号速率虽然不高但边缘陡峭容易耦合。最好在ADC和MCU之间加一个小缓冲或串接33Ω电阻抑制振铃。保护地和屏蔽罩如果环境干扰极强变频器附近给模拟部分加一个屏蔽罩接地到模拟地。注意屏蔽罩要开散热孔TSSOP封装功耗不高但别闷热。我自己在HVAC控制器里做过的板子模拟部分和数字部分各占一角中间用一条地隔离带切开效果比随便铺铜好很多。3. 固件实现UART通信与温度计算3.1 建立通信链路波特率和帧格式ADS122U04支持UART但它的协议和普通串口外设不太一样。默认波特率984.6kbps没记错的话它上电后处于待机模式通信由MCU发起主机发送8位数据带偶校验还是无校验可选协议帧包含命令、数据、CRC。官方手册里有详细时序我建议一开始用TI提供的上位机软件和USB转UART调试等逻辑摸清楚了再写固件。实际项目里我博率选择38400bps或者115200bps。为什么不用默认的高速波特率因为工业现场长线通信高速率的边沿上升时间更短对线间电容更敏感容易误码。38400足够用了ADS122U04转换速率最高才2000SPS一帧命令加一帧数据38400bps下完全不会成为瓶颈。dsPIC30F4011的UART初始化代码大致是这样// dsPIC30F4011 UART1初始化38400, 8N1 void UART1_Init(void) { U1MODEbits.UARTEN 0; // 先关闭UART U1MODEbits.PDSEL 0b00; // 8位数据无奇偶校验 U1MODEbits.STSEL 0; // 1位停止位 U1BRG ((FCY / 16) / 38400) - 1; // FCY 30MHz/2 15MIPS U1STAbits.UTXEN 1; // 使能发送 U1MODEbits.UARTEN 1; // 开启UART }注意dsPIC30F4011的系统时钟可以配置成PLL倍频我用的是7.37MHz晶振PLL 4x29.48MHz指令周期FCY14.74MIPS。U1BRG要根据FCY实际值算千万别套用8MHz单片机的公式。3.2 ADS122U04命令协议与寄存器配置ADS122U04的命令分为几类读寄存器、写寄存器、启动转换、读数据等。每次通信主机发一个命令字节可能带数据设备返回响应。上电后建议先发送复位命令再配置寄存器。关键寄存器是配置寄存器0到4寄存器0选择通道、增益、数据速率寄存器1模式选择连续/单次、内部基准、恒流源电流寄存器2恒流源输出引脚选择、PGA旁路寄存器3内部温度传感器、偏移校准寄存器4CRC使能、UART配置我的典型设置PT100测量// 写寄存器数组CH0差分AIN0/AIN1PGA820SPS内部基准激励电流500uA uint8_t regData[5]; regData[0] 0x20; // 通道0差分PGA8010即8倍 regData[1] 0x30; // 连续转换模式内部2.048V基准 regData[2] 0x10; // 恒流源电流为500uA regData[3] 0x02; // 恒流源从IEXT1输出 regData[4] 0x00; // CRC关闭UART默认 // 然后发送写寄存器命令这里要强调一下写入寄存器的具体位定义要对照datasheet的寄存器映射表不同型号的ADS1220U04和ADS122U04可能有个别位不同别凭印象写。我第一版固件就是把寄存器2的电流档位搞反了浪费了大半天。3.3 读取转换数据与温度计算连续转换模式下转换完成后数据寄存器更新主机需要按指定的命令读取。读取的数据是24位有符号数对应ADC码。PT100温度计算我推荐用比例测量的方式。简单说测量原理设恒流源为IPT100电阻为R参考电阻为Rref。 AIN0 - AIN1 电压 I * R REFP - REFN 电压 I * Rref因为REFN通过另一个同样的恒流源或同一电流流过Rref 24位ADC码值与电阻比的关系code (V_in / V_ref) * (2^23 - 1) 如果把V_ref做成I*Rref则code (R / Rref) * (2^23 - 1) 激励电流I被消掉了I的温漂不影响结果。这是个关键思路。ADS122U04有双恒流源可以让两个电流源的电流分别流过PT100和参考电阻虽然两个电流源不可能完全一致但电流比值基本稳定。更严谨的做法是用同一个电流源串联PT100和参考电阻但这样共模电压会比较高需要四线制接法。我通常用两个匹配电流源然后软件做归一化校准。得到ADC码后转换成电阻值float codeToResistance(int32_t adcCode, float refResistance) { float vIn (float)adcCode / 8388608.0f; // 24位满量程归一化 // 如果Vref I * Rref return vIn * refResistance; }然后根据电阻查表或调用Callendar-Van Dusen公式反算温度。这个公式在PT100标准里常用-200°C ~ 0°C: R R0 * (1 A*t B*t^2 C*(t-100)*t^3) 0°C ~ 850°C: R R0 * (1 A*t B*t^2) A3.9083e-3, B-5.775e-7, C-4.183e-12反算温度就不是简单代数了我用牛顿迭代法初始值猜50°C迭代三次就能收敛到0.01°C以内。在dsPIC30F4011上单精度浮点运算有硬件支持其实dsPIC30F的浮点是软件库但它有DSP乘加指令算一次几十微秒完全可接受。热电偶场景就更麻烦一点先把热电偶电压放大PGA128典型K型热电偶每度约40uV0-100°C才4mV测量到电压后查热电偶分度表得到温度再用ADC内部温度传感器或外部冷端温度做补偿实测温度 热电偶分度表查表(测到电压冷端补偿) 实际上更精确的做法是T_hot 表( V_hot 表( T_cold ) )? 不对。冷端补偿的标准做法测到电压V_meas V_hot - V_cold。 查冷端温度T_cold对应的电压V_cold然后把V_measV_cold作为热端电压查表得热端温度。这里代码写起来就是查表插值dsPIC30F4011的4KB RAM存两个分度表K型和J型有点紧张可以放到程序Flash里运行时用二分查找。我用的是const数组存储编译器会安排在程序空间。3.4 固件整体状态机因为ADS122U04是UART从机MCU是主机整个采集流程用状态机管理最可靠typedef enum { ST_IDLE, ST_WRITE_CFG, ST_WAIT_CFG_ACK, ST_START_CONV, ST_READ_DATA, ST_CALC_TEMP, ST_SEND_RESULT } SystemState;在定时器中断里每10ms轮询一次主循环只做状态切换和温度计算。这样能避免阻塞等待UART响应比阻塞式收发稳定得多。UART接收用中断FIFOdsPIC30F4011的UART自带4字符FIFO我配合一个自定义环形缓冲区能扛住突发数据。图省事的话还有一种暴力方法上电后延时100ms然后发读数据命令直到收到有效响应。这在调试阶段可以正式产品千万别这么干状态机才是正路。4. 工业与 HVAC 场景下的校准、滤波与抗干扰4.1 两点校准抹平增益和偏移误差没有任何ADC是完美的。ADS122U04虽然出厂校准过但系统级的误差还来自传感器、参考电阻、布线电阻。所以产品出厂前必须做校准。我的做法是准备两个精密电阻盒一个阻值对应量程下限比如0°C时的PT100阻值100Ω一个对应量程上限比如100°C时的138.51Ω。先在硬件上让ADC测量这两个标准电阻记录AD码然后软件计算增益和偏移gain_error (code_high - code_low) / (expected_high - expected_low) offset_error code_low - expected_low * gain_error 校正后的电阻 原始AD码 / gain_error - offset_error校准数据保存在dsPIC的Flash数据区EEPROM模拟段里每次上电读取。注意校准只对同一个PGA、同一个激励电流档位有效任何改动PGA或恒流源档位校准参数都要重建。4.2 冷端补偿与内部温度传感器ADS122U04内部有个温度传感器可以用来大致测环境温度做热电偶冷端补偿。但是精度一般典型精度±0.5°C左右而且它感受的是芯片温度不是冷端实际温度。如果你的热电偶冷端在接线端子排上和ADC芯片隔着一段铜箔那芯片温度和冷端温度会有偏差。更稳的冷端补偿方案在冷端端子附近放一个PT1000或者数字温度传感器比如TMP117读取冷端温度。用MCU内置的ADC读一个NTC也行但分辨率不够冷端误差会被放大。然后用软件查询分度表把冷端热电势补偿进去。我自己做得最多的是用ADS122U04内部温度传感器做粗调再用一个外部NTC做精调其实不对做法是如果精度要求±0.5°C用内部传感器凑合要求±0.1°C必须外部传感器。HVAC通常要求±0.2°C还是外部传感器更好。4.3 数字滤波策略不能只靠一个“平均”Δ-Σ ADC输出自带一定噪声20SPS下噪声已经很低了但工业现场还会有一阵阵的脉冲干扰。我的滤波链分三段去极值平均连续采8个点去掉一个最大值一个最小值剩下6个点平均。抗脉冲干扰。一阶低通滤波filt (1-alpha)*old alpha*newalpha取0.2~0.5让输出平滑。死区滞回如果滤波结果和上次上报值之差小于0.02°C不更新防止后端显示抖动得太厉害。这套组合在调速电机启停时实测温度波动从原来±0.5°C压到±0.08°C。代价是响应速度慢了但对于HVAC这种惯性大的对象慢一点无所谓。4.4 电磁兼容和长线布线注意事项ADS122U04的UART一旦用于跨板通信接地环路就成了噪声源。我的建议如果ADC板和MCU板分开用光耦隔离UART信号电源用隔离DC-DC彻底切断地环路。如果单板传感器线缆用屏蔽双绞线屏蔽层单端接地在ADC板一侧接地。传感器走线远离功率线220V/电机线距离至少5cm。共模电感在传感器输入端串上数值10mH左右能有效共模干扰抑制。HVAC系统里弱电和强电经常在一个配电箱我就见过因为动力线靠近传感器线温度读数乱跳的情况。后来加了隔离重新整理布线问题消失。5. 常见问题与排查技巧实录5.1 UART 通信无响应先从这些点查起很多新手把ADS122U04接到MCU后发命令石沉大海。排查顺序电源这ADC难伺候AVDD和DVDD都要供电任何一路没电都无响应。用万用表量别只看LED。接地数字地和模拟地没连好或和MCU不是一个参考地UART逻辑电平异常。TX/RX交叉两个UART相连必须TX接RX、RX接TX。这个低级错误比想象中常见。波特率偏差dsPIC30F4011的BRG算错导致波特率差超2%就会误码。用示波器量TX脚波形用逻辑分析仪解码。发送数据格式ADS122U04默认UART格式是不是8N1你要看手册。我遇到过需要配置成NON-ACK模式的情况上电后必须先发复位命令等待10ms再写寄存器。5.2 读数漂移或噪声过大读数飘十有八九是电源或基准问题。我列个速查表现象可能原因检查/解决读数周期性波动工频干扰采样率没设置成50Hz/60Hz抑制数据速率设为20SPS或60SPS并做陷波或平均读数随机抖动大电源纹波大/布局不良/输入保护电容过大改善AVDD滤波检查PCB分区减少输入电容到合理值读数缓慢漂移恒流源电流受温漂影响改用比例测量或选高精度恒流源方案读数一跳一跳过载或输入超出共模范围检查输入电压是否在AVDD和GND范围附近PGA倍数是否合适数值固定为满码输入开路或过压查传感器接线TVS钳位是否正常一个隐藏坑如果串联电阻和输入电容太大构成低通滤波转折频率低于信号频率会引入幅值误差。PT100那种慢信号没事但如果你把ADC用来测快速温度变化比如热敏电阻响应会变慢。5.3 恒流源档位选择不当导致自热误差PT100通过恒流源激励电流越大输出信号越大但自热也越严重。自热公式自热温升 I^2 * R * 热阻系数PT100的典型热阻系数自热系数约0.4°C/mW在空气中如果激励电流1mAPT100电阻100Ω功耗0.1mW自热约0.04°C。看起来不大但如果你激励电流是1.5mA功耗变成0.225mW自热约0.09°C。对于0.1%精度的应用这个误差不能忽略。我一般用500µA作为折中信号幅度在PT100上约50mVPGA8时量程足够自热约0.02°C。如果是PT1000阻值大电流用250µA电压同样大自热更低。5.4 固件移植和编译的坑dsPIC30F4011的C编译器XC16有一些和普通MCU不同的地方int是16位long才是32位。ADC码是24位读回来要存放在int32_t即long里。浮点运算默认是软件库编译时如果用-O2优化浮点计算可能出问题其实不会但要注意浮点格式是IEEE754单精度。中断优先级和UART接收中断标志位要正确处理丢数据多半是没清中断位。如果程序里同时用CAN和UART注意引脚复用冲突。dsPIC30F4011很多引脚是复用的比如UART1的TX/RX和某些CAN引脚冲突要看数据手册的PPS外设引脚选择dsPIC30F4011实际上没有PPS引脚复用是固定的查手册配置好。我自己踩过坑把UART2的TX配置错成UART1的RX方向结果收发都乱。后来对着手册逐个pin确认一次搞定。5.5 更进一步的改进方向ADS122U04的UART接口让我很喜欢的一点是它支持Daisy Chain这个型号好像不支持多片级联但可以通过UART总线挂多个ADC不行它是点对点从机。如果要多通道可以加一个UART多路复用芯片或者选带更多通道的型号。另外dsPIC30F4011自身也有一个12位ADC和热敏电阻接口如果你只是做NTC测温、精度要求不高直接用自带的ADC省一颗芯片。但24位ADC带来的精度优势是碾压性的尤其是宽温区和高精度需求的场合别省这个钱。6. 一些实操心得用经验换不踩坑这个组合我用过好几个项目从商用空调控制器到工业烤箱温控器稳定性都扛住了。几个经验原理图阶段就把测试点留好在ADC的REFP、AIN0、IEXT1引脚上放测试点调试时用电表就能量电压不用飞线。先跑通SDK示例再写产品代码TI官方有ADS122U04的评估板代码虽然是MSP432的但协议栈能参考。下载下来先拿串口调试助手模拟主机确认每个命令的返回字节再去写dsPIC的驱动省掉一半调试时间。固件里加诊断信息我习惯在温度前面附带上几个状态位ADC通信失败次数、数据超范围标志、参考电压异常标志。这样现场排查问题时能直接看状态而不是只看到一个错误温度。校准工艺不能省每个产品出厂时跑一次两点校准成本增加几秒但质量提升一个档次。尤其是PT100输入换一个电阻盒都不行必须用同一套校准设备。UART隔离方案如果系统有强电220V压缩机驱动ADC和MCU之间光耦隔离是性价比最高的方案。不要犹豫加上去。光耦的延时大约几微秒38400波特率下完全不影响。最后再分享一个小技巧如果读数老是差那么0.01V又找不到原因拿出示波器看看REFP上的噪声。很多时候不是因为电源不够好而是因为你的示波器探头地线夹太长把接地回路噪声带进来了。把探头地线尽量缩短用弹簧地线波形会瞬间干净。这个方案如果后续想扩展可以把多路ADS122U04挂到dsPIC30F4011的两个UART上一路测温度一路测压力或湿度。我最近就在做类似的事到时候再写篇专门的文章分享。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。