☰
ADS122U04+PIC18:多通道温度采集模块设计与实战
2026/11/5 1:09:29 网站建设 项目流程

做工业现场和HVAC项目的人,应该都有同感:温度采集看着简单,做起来却处处是坑。风管送风温度、冷水机组进出水温、配电柜环境温度、电机绕组温升,这些信号种类杂、幅度小、现场干扰大,还得跟控制器、上位机打通通信。我最近搭的一套多通道温度采集模块,选了 TI 的 ADS122U04IPWR(24位、自带UART接口的Δ-Σ ADC)做主采集,搭配 Microchip 的 PIC18F86J10 单片机做控制和协议转换,把 RTD、热电偶、NTC 三类传感器统一进一套体系里,实测下来稳定性和精度都让我比较满意。这篇就把这套组合从头到尾拆开讲:选型逻辑、硬件布线、固件寄存器配置、现场调试踩过的坑,一条条捋清楚,想直接抄作业的也能跟着复现。

1. 整体架构与选型思路

1.1 为什么用"24位ADC + MCU"而不是单片机自带的ADC

很多HVAC控制器里的单片机都带12位ADC,能不能直接用?说实话,做做室内温度显示没问题,一旦碰上PT100这类小阻值传感器,或者K型热电偶这种微伏级信号,12位分辨率就不太够看了。以PT100为例,0到100℃范围内阻值变化只有约38.5Ω,用1mA恒流激励也就产生38.5mV的电压变化,折算到1℃大约0.385mV。12位ADC在3.3V参考下,一个LSB就是0.8mV,算下来分辨率还不到2℃,这还没算噪声和失调漂移,根本没法用在精度要求高的工艺控制里。

所以独立ADC是必需品。ADS122U04IPWR是24位Δ-Σ架构,内部带可编程增益放大器(PGA,增益1到128倍),输入量程可以按传感器类型灵活匹配。对PT100,用8倍或16倍增益,再配合IDAC恒流源做比例式测量,能绕过参考电压温漂这个大坑;对热电偶,用32倍甚至64倍增益,把微伏级信号抬到ADC能“看清”的范围;对NTC热敏电阻,直接当成单端电压测量就行。24位的底子摆在那,短时间噪声折合到输入也就是微伏级别,足够覆盖工业现场的典型需求。

另一个关键点是内部门狗和传感器诊断。工业应用最怕传感器断线或短路,ADS122U04支持输入传感器开路/短路检测,这一点在做批量设备时很省心,省了外置比较电路。整体架构就是:传感器信号进ADC,ADC通过UART把结果送给PIC18,PIC18负责数据转换、线性化、标定,以及对上位机的MODBUS-RTU、RS-485或开关量输出。

1.2 为什么特意选UART接口的ADC型号

ADS122U04IPWR这颗料,和常见的SPI接口ADC最大区别就是通信口是UART。SPI接口在板内通信很好用,但在工业现场就有麻烦:线一长受干扰影响大,还需要额外占用MCU好几个IO,加上SPI没有统一帧校验,稍不小心就出现收发错位。UART的优势在于物理层实现简单,一个发送脚一个接收脚就能跑,配合RS-485收发器或光耦可以轻松实现上百米传输和电气隔离。

尤其是在HVAC这种弱电强电混装的现场,控制柜里有接触器、变频器、开关电源,传感器又往往装在几米甚至几十米外的风管或水管上,把模拟小信号一路引到控制板是最差的做法。用了UART接口ADC之后,结构就能变成:传感器就近接入采集模块,模块内ADC把模拟量变成数字量,UART信号再长线传输到主机控制器。数字信号对干扰的耐受能力远强于模拟信号,这设计好在哪,做过现场的人应该体会很深。

ADS122U04的UART帧格式是8数据位、无校验、1停止位(8-N-1),波特率默认9600,也支持19200。对一颗24位ADC来说,这个速率完全够用,因为温度信号本来就不需要高采样率,20SPS最多45SPS的转换速率足够平滑。

1.3 PIC18F86J10在系统里的分工

PIC18F86J10是Microchip的8位单片机,3.3V供电,片上64KB程序Flash、接近4KB的RAM,I/O资源丰富,带多个EUSART模块,其中一个专门跟ADC通信,另一个可以接其它设备或做调试串口,互不干扰。这颗片子在3V左右供电下跑得稳,功耗也低,做无风扇的壁挂式采集器很合适。

它的任务不复杂,但很杂:上电初始化UART、发送指令配置ADC寄存器、周期读取24位转换结果、把原始码值换算成温度、处理各种传感器类型的查表和线性化方程,最后通过MODBUS或者其他协议把温度值上报。别被24位精度吓到,PIC18本身运算能力有限,但温度换算这种量级的浮点运算,用单精度float是能扛住的,实际循环周期几十毫秒,完全没问题。

我还特意留了几个GPIO做DDC(直接数字控制)用途,比如接继电器控制风机、水泵,或者做传感器故障报警输出,把PIC18的丰富IO利用起来,一块小板子就完成了采集加控制两件事,省掉一块PLC模块的成本。

2. 硬件设计要点与接线

2.1 电源方案:统一3.3V供电的关键细节

ADS122U04的模拟电源AVDD和数字电源DVDD都是2.3V到5.5V,PIC18F86J10的工作范围是1.8V到3.6V,所以整个系统取3.3V统一供电最省事。别把ADC供5V、单片机供3.3V,那样电平接口还得做转换,反而增加故障点。

电源路径上我建议用低压差线性稳压器(LDO),比如LM1117-3.3或更安静的型号,输入用24V或12V现场电源通过DC-DC先降压。这里有个实测教训:DC-DC输出纹波对精度影响非常明显。因为ADS122U04的PGA高增益模式下,电源纹波会耦合到参考和模拟输入上。我最初图省事直接拿一个7805和几个电容给模拟部分供电,24位ADC实际有效分辨率掉到17位左右;后来改成LDO单独给模拟供电,并在AVDD引脚前加一个磁珠、100μF电解电容加0.1μF陶瓷电容的组合,有效位数恢复到20位以上。

去耦电容的布局也讲究:电容要尽量靠近芯片电源引脚,磁珠放在电源进线位置,模拟地和数字地在MCU的某个地引脚附近单点汇合。PCB上最好一整块完整地平面,不要为了走线把地平面切开,模拟区和数字区在地平面上自然分区即可,不要强行把地分成两块孤立的岛,否则跨区走线反而引入更大的回路电感。

2.2 传感器前端电路:RTD、热电偶、NTC分别怎么接

ADS122U04内部有两个IDAC电流源,这个一定要用好。IDAC的优势在于恒流激励,配合比例式测量可以消除参考电压温漂和增益误差。

先说RTD。三线制PT100是最常见做法,原理是这样的:IDAC电流从AIN0流出,经过PT100到AIN1,同时再用一根引线把电流引到RREF基准电阻上,建立参考电压VREF。测量时只关心PT100上的电压和RREF基准电压的比值,因为IDAC电流的任何漂移会同时影响分子和分母,抵消掉。三线制接法还能消除引线电阻误差:一根引线在激励回路,两根引线分别承担传感和参考,只要引线材质均匀,误差在工程上可以控制在0.1℃以内。激励电流选250μA比较稳妥,电流太大PT100会自热,太小信噪比不够。

PT1000和NTC可以放宽一些。PT1000阻值大,250μA到500μA都可以,自热效应小得多;NTC在25℃下通常是10kΩ,用内部参考分压测量即可,不需要IDAC,只要注意分压电阻的精度和温漂,最好选0.1%精度、25ppm温漂的金属膜电阻。

热电偶是完全另一种思路。K型热电偶输出只有40μV/℃左右,需要PGA高增益放大。把热电偶正端接AIN0、负端接AIN1,采用差分输入,并把AIN1附近的热电偶冷端通过一个小等温块贴上板子,利用ADS122U04内部集成温度传感器测出冷端温度,软件里再做冷端补偿。这里最容易被忽视的是冷端温度传感器和热电偶接线端子的热耦合:如果冷端和内部传感器之间存在热梯度,补偿就形同虚设。所以热电偶接线端子要尽量靠近芯片,并且用大面积铜箔连接,让两者温度一致。

前端还需要加RC低通滤波。我在每个模拟输入引脚对地放一个1kΩ电阻和一个0.1μF电容(截止频率约1.6kHz),有效滤掉手机射频、PWM驱动等干扰。不过要注意,ADC输入端挂电容会影响PGA建立时间,数据手册里有最大允许外部电容值,做高增益测量时最好按推荐的RC取值,不要随意加大。

2.3 UART接口连接与隔离

ADS122U04的DOUT/DOUT? 数据线是集电极开路/推挽输出我这里用标准UART与PIC18的EUSART1直连。3.3V供电时电平匹配天然一致,RX/TX交叉连接即可。PIC18的RX引脚还要注意开放漏极带上拉。

如果采集模块和主机要远距离通信,我的做法是:采集端到主机之间用RS-485,中间加隔离光耦,不共地。现场出现地电位差是常事,不隔离就会烧串口。ADS122U04负责把模拟小信号变成数字,隔离层放在UART之后,这时候信号已经是数字电平,光耦或数字隔离器性能足够,成本也可控。位置一定要对:ADC和传感器之间绝对不搞隔离,因为模拟信号隔离非常难做,要把模拟隔离放在ADC之前,精度和成本都吃不消。

2.4 布局里的工程取舍

PCB布局我按“模拟传感区—ADC区—数字控制区—隔离通信区”做了严格的物理分区。传感器接口端子放在板边,信号一进来就进滤波和输入保护,然后进ADC,尽量不走长线连接。ADC底下不要过其它数字信号线,尤其是UART和PWM线。

输入保护电路不能省。HVAC现场长线上经常感应出静电压或浪涌,我在每个模拟输入端对地加了一对反向串联的BAT54S肖特基二极管,把输入电压箝位在电源轨和地之间。别觉得温度传感器“只不过”就是几百毫伏,感应雷和短路碰电的案例我见过不止一回,不加保护的板子返修率明显高。

3. 固件实现:从寄存器配置到温度值

3.1 先打通UART链路

PIC18这边初始化EUSART的代码很简单。我用的是内部8MHz振荡器倍频到32MHz作为FOSC,波特率9600。SPBRG计算公式是 FOSC/(16×BAUD)-1,32M/(16×9600)-1 = 207.3,取207,误差约0.15%,完全在UART容差范围内。

void UART1_Init(void) { TRISCbits.TRISC7 = 1; // RX1 输入 TRISCbits.TRISC6 = 1; // TX1 配置为输出,稍后由TXEN控制 BAUDCON1bits.BRG16 = 1; TXSTA1bits.SYNC = 0; // 异步模式 TXSTA1bits.TXEN = 1; RCSTA1bits.SPEN = 1; RCSTA1bits.CREN = 1; SPBRG1 = 207; // 9600 baud @ 32MHz }

发送一个字节和接收一个字节用查询轮询就行,因为ADC的转换速率很慢,20SPS,每50ms才出一个完整结果,轮询和中断都无所谓。我实际用的就是查询,省去中断嵌套的麻烦。但接收时一定要保证在帧间隔内读完,尤其是连续读三字节转换结果时,三个字节之间相隔不到1ms,用查询在一个循环里连着读完,别中途去做延时。

3.2 寄存器配置拆解

ADS122U04的配置分布在寄存器0到寄存器4。我按实际项目的配置来逐项解释,你拿到数据手册对照就能看懂。

寄存器0负责输入多路复用器、PGA增益和单双极性。对PT100差分测量,我配置成AIN0和AIN1差分输入,PGA增益8倍,双极性模式(因为热电阻信号没有负向,理论上单极性也能做,但双极性对失调处理更灵活)。对K型热电偶,差分输入不变,PGA增益64倍。这里有个原则:增益不是越高越好,在保证分辨率的前提下尽量选低增益,因为PGA会放大有用信号,同时也会放大失调和噪声。我用8倍增益时PT100满量程200℃对应的信号约85mV×8 = 680mV,距离内部2.048V参考的最大量程还有余量,信噪比足够了。

寄存器1配置数据速率和转换模式。温度测量不需要高速率,我固定用20SPS,配合数字滤波器能有效抑制50Hz工频干扰。有人问,50Hz干扰为什么20SPS挡得住?因为Δ-ΣADC内部的数字滤波器在采样速率和其整数倍频率附近有陷波特性,20SPS时恰好能把50Hz和60Hz的干扰压得很低。这是HVAC应用选20SPS或45SPS的隐藏理由。

寄存器2控制参考电压和温度传感器。我的设计里,外部RTD用RREF做比例参考,热电偶和NTC用内部2.048V参考。同时配置内部温度传感器为“温度传感器模式”,用于热电偶冷端补偿。寄存器3配置IDAC电流源和路由:PT100把IDAC1配到250μA并输出到AIN0,IDAC2关闭。寄存器4是UART配置项,保持默认8位数据、无校验,波特率按默认9600。

配置发送的过程是一个典型UART操作。TI这颗料在发送配置命令时,要按它的命令格式把寄存器地址、后续寄存器和数据字节依次发出。我写了一个函数,把配置数组一次发出去:

void ADS122U04_WriteRegs(uint8_t startReg, uint8_t count, uint8_t *data) { uint8_t cmd = 0x60 | (startReg << 2) | (count - 1); UART1_WriteByte(cmd); for (uint8_t i = 0; i < count; i++) { UART1_WriteByte(data[i]); } }

注意,这里命令字节的高位和地址组合要按TI手册里的WREG格式来。不同批次数据手册的某些细节可能存在勘误,接线和代码都正确却通信不上的话,第一件事就是去查最新版数据手册的命令码定义,我曾经被旧手册里的一个命令错误坑过大半天。

3.3 读取数据与温度换算

读一次转换结果是发RDATA命令,然后连续读取三个字节,高位、中位、低位。因为ADS122U04的转换字是24位二进制补码格式,组合时要小心符号扩展:

int32_t ADS122U04_ReadData(void) { uint8_t bytes[3]; int32_t raw; UART1_WriteByte(0x10); // RDATA命令,具体以手册为准 bytes[0] = UART1_ReadByte(); bytes[1] = UART1_ReadByte(); bytes[2] = UART1_ReadByte(); raw = ((int32_t)bytes[0] << 16) | ((int32_t)bytes[1] << 8) | bytes[2]; if (raw & 0x800000) raw |= 0xFF000000; // 符号扩展成32位负数 return raw; }

拿到原始码值后,先换算成电压。假设PGA增益为G,参考电压为VREF,转换结果为24位补码,那么输入电压 = raw × VREF / (G × 2^23)。对比例式RTD测量,直接用原始码值的比值更精准:RTD电阻值 = RREF × raw_measure / raw_reference。之所以用这个比值,是因为IDAC电流和VREF的任何漂移都同时影响分子和分母,互相抵消,这是整颗ADC精度架构里最值钱的地方。

换算成电阻后,再用多项式或查表得到温度。PT100的IEC 751多项式权威,但要在单片机里跑高次多项式有些吃力。我采用的做法是:把0到400℃按1℃间隔做成静态查表,电阻值用uint16_t数组存放,测量后二分查找,再线性插值到0.01℃。这个表放在Flash里只占800字节,查询时间极短。PT1000的曲线和PT100共用查表法,只是阻值按10倍关系换算,温度结果不变。

热电偶要麻烦一些:先测热电偶输出电压Vtc,再测内部温度传感器的冷端温度Tcold,查热电偶分度表得到Tcold对应的热电动势Vcomp,然后V真实 = Vtc + Vcomp,再用反向查表得到被测端温度。ADS122U04内部温度传感器分辨率有余,但要注意冷端必须是等温块,否则软件算得再准也白搭。

NTC就简单了,用Steinhart–Hart方程:T = 1/(A + B·ln(R) + C·(lnR)^3) - 273.15。这个方程用float运算,PIC18完全跑得过来。B值、C值在25℃附近是准的,超出使用温度范围误差会大,HVAC用正好。

3.4 标定环节不能省

我每次贴片完,都要做一次两点校准。方法也不复杂:把探头放进0℃的冰水混合物维持10分钟,记录ADC原始码值的平均值,记为偏移量;再把探头放进接近满量程的恒温槽(比如100℃沸水或精密干井炉),记录增益校准系数。把这个偏移和增益系数写进EEPROM,运行时在转换结果里做一阶修正。

如果是批量生产,每台都要校准,其实也不用太久,关键是把校准自动化:PC端通过串口发指令,固件接收校准点温度值和ADC码值并写入EEPROM。我这样批量搞过几百台的温控仪表,一致性可以做到全量程±0.3℃以内,对于HVAC应用已经属于很宽裕的水平。

4. 常见问题与排查技巧

4.1 ADC无响应或读回的数据全是0

这是最常见的情况。先别怀疑芯片,优先检查三样东西:供电、复位、波特率。用示波器看ADC的TX脚有没有波形,如果MCU发出RDATA命令后,TX脚一直无输出,说明ADC根本没响应。最常见原因是波特率偏差过大。我曾经遇到过用内部RC振荡器做UART时钟,误差超过2%,波特率对不上,偶尔通偶尔不通。解决方法是:项目里UART通信必须用外部晶振或校准过的内部振荡器,PIC18的振荡器校准值在深睡眠后要重新写入OSCTUNE寄存器,这个坑很隐蔽。

另外注意ADS122U04的上电时序:确保VDD稳定后再通信,上电后至少等待10ms让内部基准和振荡器稳定。如果上电瞬间就发WREG,芯片可能处于未复位状态,指令丢失。稳妥做法是主程序循环开头反复发NOP命令或重写寄存器配置,而不是只启动时写一次。

4.2 读数跳动、噪声比规格书大

出现这个问题的第一反应应该是查电源纹波,不是换芯片。我用DC-DC供电时的有效分辨率掉了,前面提到过;换成低噪声LDO并加磁珠就改善。另一个隐藏因素是PGA输入端外部电容太大,导致斩波不稳定。ADS122U04的PGA在10倍以上增益时对外部电容很敏感,电容超过手册上给的上限,就会出现额外噪声甚至振荡。做完RC滤波后,最好用示波器在AIN引脚观察有没有自激迹象。

还有一个容易忽略的是参考电压去耦。内部参考虽然不需要外部电容,但REF引脚如果接了外部电容,容值必须在手册范围内。有人习惯性在参考引脚放一个10μF大电容,结果反而把内部参考的建立时间和噪声搞坏。我实际用的是0.1μF,稳得很。

最后是地线问题。如果传感器和采集板距离远,传感器的屏蔽层不能两头都接大地,只能单端接地,否则地环路会灌进工频噪声。这个信号处理的原则是“屏蔽层单端接地,且靠近采集端接”。我在现场改过一次屏蔽层接法,噪声从±3LSB直接降到±0.5LSB。

4.3 热电偶测量误差大,怎么查

先做一个简单实验:把热电偶从端子上拿下来,让ADC两个输入短接,读数应该接近0。如果这个基础读数不是0,说明PGA失调或参考有问题。再把手捏住端子,温度读数应该缓慢变化。如果读数很怪,先查冷端补偿:开机后等5分钟让板子达到热平衡再校准一次。我见过很多人在上电后立刻校准冷端,板子还没热,冷端温度和ADC内部温度传感器差了四五度,测出来的温度当然不对。

热电偶线极性接反也很典型,K型热电偶正负极接反后,随着温度升高读数反而下降。如果你发现测出来的“温度”方向反了,把两根线对调试试,这个排查只要一分钟。

4.4 HVAC现场干扰与长线问题

在HVAC控制柜里,最大的干扰源是接触器通断和变频器输出。接触器断开瞬间会产生很大的脉冲尖峰,哪怕是数字信号线也会被感应。我在采集板和主机之间用的是隔离RS-485,线缆用屏蔽双绞线,屏蔽层在主机端单点接地。传感器线则远离动力线布线,不要跟220V线走同一个线槽,间距至少20cm以上。

还有一个抗脉冲干扰的办法:PIC18固件里做“三次读取取中值”滤波。ADC以20SPS采样,数据本来就不快,每500ms做一次中值滤波,对脉冲干扰几乎完美。做中值滤波时别用平均值,平均值会被毛刺拉偏,中值更抗脉冲,代价只是100ms以内的延迟,HVAC里完全可以接受。

4.5 快速问题速查表

现象可能原因排查动作
无响应波特率不匹配示波器测TX/RX波形,查时长
无响应上电时序不对加10ms以上延时,重发寄存器配置
读回全0命令码与手册不符对照最新数据手册确认WREG/RDATA指令
读数乱跳电源纹波/地环路换LDO、磁珠,检查屏蔽层接法
读数乱跳PGA输入电容偏大减小RC滤波电容到手册范围
热电偶方向反极性接反对调热电偶输入线
热电偶冷端误差冷端热梯度确保端子靠近芯片,大面积铜箔等温
阻抗不准激励电流被旁路检查输入防护二极管是否漏电

5. 个人体会与扩展想法

这套方案我后面又做了几版,结构基本没变,只是根据现场需求调整了传感器口和通信方式。ADS122U04IPWR和PIC18F86J10这个组合,最大的价值不在于单个芯片多强,而在于把模拟小信号、数字处理和长线传输之间的边界划得很清楚:传感器端的信号完整性由ADC保证,UART之后就是纯数字世界,隔离和抗干扰都变得简单。

如果后续要扩展,我最想说的是:先把单点做稳,再谈扩展。很多朋友一上来就想做8通道、16通道,结果被调试搞得焦头烂额。我建议第一版只做2到4路,把一类传感器调通、标定准确,再复用通道。等PT100这一路跑顺了,加热电偶和NTC只是寄存器配置和软件查表的问题,硬件改动很小。这样一步步走,比一开始追求通道数量靠谱得多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询