资讯详情

基于ADS122U04与PIC18F87J50的工业级温度测量方案设计

📅 2026/11/6 4:31:47 | 华诺云谱 👁 阅读
基于ADS122U04与PIC18F87J50的工业级温度测量方案设计
1. 工业温度测量方案的整体设计思路工业现场和HVAC系统里的温度测量看起来是个再普通不过的需求但真正做过项目的人都知道这里面的坑一点都不少。我接触过不少暖通空调、工业过程控制的案子客户张口就是“测个温度而已随便搞个传感器不就行了”结果一到现场就出问题读数跳变、精度不够、长线传输干扰、多点采集不同步各种毛病全冒出来。所以这次我拿ADS122U04IPWR这颗24位ΔΣ ADC配合PIC18F87J50单片机做一套针对工业和HVAC场景的温度采集方案把从传感器选型到ADC配置再到软件滤波的完整链路捋一遍。先说这套组合能干什么。ADS122U04IPWR是TI的一款24位、4通道、带PGA的低功耗ΔΣ模数转换器内置两个匹配的激励电流源专门为RTD、热电偶、热敏电阻这类温度传感器做了优化。PIC18F87J50是Microchip的一款8位MCU自带全速USB 2.0控制器64KB Flash3936字节RAM跑温度采集这种任务绰绰有余。两者通过SPI或者UART通信ADS122U04支持这两种接口我一般选SPI速度快、时序可控。这套方案解决的核心问题是在工业电磁环境复杂、传感器离主控可能有好几米远的条件下稳定地拿到±0.1℃级别的温度读数。适合谁看做HVAC控制器的嵌入式工程师、搞工业数据采集的硬件开发者、以及正在选型温度测量方案的产品经理。哪怕你之前没碰过ΔΣ ADC只要懂基本的SPI通信和C语言跟着走一遍就能落地。为什么不用MCU自带的12位ADC直接测这是很多人第一个会问的问题。PIC18F87J50内部ADC是10位或12位取决于配置在测量PT100这种变化量很小的信号时分辨率完全不够。PT100在0℃时是100Ω每升高1℃大约增加0.385Ω。如果用1mA激励电流1℃对应的电压变化只有385μV。12位ADC在3.3V参考下1个LSB就是0.8mV根本分辨不出0.1℃的变化。而ADS122U04在PGA增益为8、使用内部2.048V参考时有效分辨率能到20位以上1个LSB对应不到2μV轻松覆盖0.01℃的分辨需求。这就是为什么工业级温度测量几乎都绕不开高精度外置ADC。2. 核心器件选型与关键参数拆解2.1 ADS122U04IPWR凭什么适合RTD测温ADS122U04IPWR的核心优势在于它把RTD测量需要的几个关键模块都集成进去了。它内部有两个可编程激励电流源可以输出10μA到1.5mA的电流用来给RTD供电。为什么这个很重要因为RTD测量通常采用比率法用同一个电流源同时激励RTD和参考电阻这样电流的温漂和长期漂移会被抵消掉测量精度只取决于参考电阻的精度。如果外部分立搭建电流源不仅占板面积匹配和温漂也是大麻烦。它的PGA支持1到128的增益对于PT100在低温段输出信号很小的情况可以把增益设高一点充分利用ADC的满量程。输入多路复用器支持4个差分通道或者2个差分加2个单端做多点温度采集时不用外接多路开关。内部参考电压可选2.048V或2.4V温漂典型值5ppm/℃这个指标对工业环境来说够用了。数据输出速率从5SPS到2000SPS可调。这里有个取舍速率越低数字滤波器抑制工频干扰的能力越强噪声也越低。HVAC场景里温度变化本来就慢我通常设20SPS正好把50Hz和60Hz工频干扰压得很死。如果做快速响应的工业探头测试可以设到200SPS以上但这时候就要靠外部RC滤波来补救了。2.2 PIC18F87J50在系统中的角色定位PIC18F87J50在这套方案里干三件事配置ADS122U04的寄存器、读取转换结果、做二次滤波和温度换算。它自带SPI模块最高支持10Mbps跟ADS122U04通信完全不是瓶颈。64KB Flash存温度换算表、滤波算法、通信协议栈都够用。3936字节RAM对于缓冲采样数据、跑滑动平均或者中值滤波也绰绰有余。选它还有一个实际考虑它支持2.0V到3.6V宽电压供电可以直接和ADS122U04的DVDD共用一个3.3V轨省掉电平转换。工业现场很多设备还是5V系统PIC18F87J50的I/O口耐5V跟老式PLC接口时不用加电平转换芯片这一点在改造项目里特别省事。它的USB功能在这个方案里不是必须的但如果你要做桌面校准工具或者数据记录仪直接用它内置的USB跟PC通信省掉一颗USB转串口芯片BOM成本能降一点。我有个客户就是拿它做便携式温度校准器USB供电加通信一根线搞定。2.3 传感器选型PT100、PT1000还是热电偶工业和HVAC场景里PT100和PT1000是最常见的选择。PT100在0℃时100ΩPT1000是1000Ω。同样的激励电流下PT1000的输出电压是PT100的10倍信噪比更好但自热效应也更明显。所谓自热效应就是激励电流流过RTD时会产生焦耳热让传感器本身温度略高于环境温度。PT100用1mA激励时自热大约0.1℃PT1000用0.1mA激励时自热差不多但输出信号只有PT100用1mA时的水平。所以选哪个要看你的精度要求和传感器封装。我的经验是HVAC风管温度测量PT1000更合适因为风管里传感器封装小自热影响小而且PT1000的引线电阻影响相对小。工业管道或者高温炉PT100更常见因为标准铂电阻温度计都是PT100校准和互换性更好。热电偶适合测高温但冷端补偿和信号调理复杂得多ADS122U04虽然能接但需要额外的冷端传感器这个方案里先不展开。3. 硬件电路设计与实操要点3.1 RTD接口电路三线制还是四线制RTD接线方式直接决定测量精度。两线制最简单但引线电阻直接加到测量结果里每米铜线大约0.02Ω100米就是2Ω对应PT100大约5℃误差完全不能用。三线制是工业标配用一根补偿线抵消引线电阻前提是三根线材质长度一致。四线制精度最高用两根线通电流、两根线测电压完全消除引线电阻影响但布线成本高。ADS122U04支持三线制和四线制。三线制接法是把RTD一端接两个输入通道另一端接激励电流源通过两次测量或者内部多路复用切换来消除引线电阻。具体操作是第一次测量RTD电压加引线1的压降第二次测量引线2的压降两者相减。ADS122U04的内部多路复用器可以自动完成这个切换但需要软件配合。四线制就简单粗暴激励电流从RTD两端流入流出测量电压从另外两端取引线电阻上没电流所以没压降。我一般建议客户如果传感器离主控超过3米直接上四线制省得后面调半天发现是引线电阻问题。三线制适合传感器和电路板在同一个机柜里的场景。3.2 参考电阻的选择与计算比率法测量里参考电阻的精度和温漂直接决定系统精度。ADS122U04的参考输入可以接外部参考电阻用同一个激励电流源驱动。假设用PT100激励电流1mA参考电阻选1.65kΩ那么参考电压就是1.65V。PT100在0℃时电压是100mV在100℃时是138.5mV。ADC的满量程是±VREF/PGA如果PGA1满量程就是±1.65V100mV只用了满量程的6%浪费了很多分辨率。所以要把PGA设高。PGA8时满量程变成±206mV138.5mV对应满量程的67%利用率好多了。但要注意PGA的输入范围限制ADS122U04在PGA8时输入共模电压要满足AVSS0.2V到AVDD-0.2V之间差分输入不能超过±VREF/PGA。算一下138.5mV差分共模电压设在1.65V/20.825V左右满足要求。参考电阻的选型1.65kΩ用0.1%精度、10ppm/℃温漂的金属膜电阻比如Vishay的PTF系列。这个电阻的温漂会直接乘到测量结果上10ppm/℃在0到50℃变化范围内引入500ppm误差对应PT100大约0.13℃。如果要求更高可以用0.05%精度、5ppm/℃的电阻成本翻倍但误差减半。3.3 电源与去耦别小看这几个电容ADS122U04有AVDD和DVDD两组电源。AVDD给模拟部分供电DVDD给数字接口供电。虽然它支持2.3V到5.5V宽电压但为了跟PIC18F87J50的3.3V系统匹配两组都接3.3V。关键点是AVDD必须干净任何纹波都会直接调制到ADC输出上。我的做法是AVDD用一颗低压差线性稳压器单独供电比如TPS7A4700噪声只有4μVrms。DVDD可以跟MCU共用数字3.3V但要在ADS122U04的DVDD引脚旁边放0.1μF和1μF电容各一颗0.1μF要尽量靠近引脚走线短而粗。AVDD的去耦更讲究10μF钽电容加0.1μF陶瓷电容再并一颗1nF的C0G电容滤高频。别用X7R或者Y5V的电容做模拟去耦它们的压电效应会引入噪声。参考电压引脚REFP和REFN之间也要放0.1μF电容这个电容影响参考电压的稳定速度。如果设了50SPS以上的速率电容可以小一点响应快如果设20SPS以下电容可以大到1μF噪声更低。3.4 SPI接口连接与PCB布局ADS122U04的SPI接口有四根线CS、SCLK、DIN、DOUT/DRDY。DRDY是数据就绪信号也可以复用成DOUT。我一般把DRDY单独接到PIC18F87J50的一个外部中断引脚上这样MCU不用轮询数据准备好了直接进中断读效率高。SPI时钟极性要设对ADS122U04在SCLK下降沿采样DIN上升沿输出DOUT对应SPI模式1CPOL0CPHA1。PIC18F87J50的SSP模块支持四种模式配置成模式1就行。时钟频率别超过4MHz虽然手册标称支持到10MHz但长走线或者高噪声环境下降频更稳。PCB布局上模拟部分和数字部分要分开。ADS122U04放在板子中间左边是模拟输入和参考电阻右边是SPI数字线。模拟输入走线要远离SCLK和任何开关信号最好用地线包起来。参考电阻和RTD的走线要对称差分对走等长线减少共模干扰转化成差模噪声。如果板子空间允许在模拟输入前面加一个RC低通截止频率设在1kHz左右用1kΩ电阻加100nF电容能滤掉大部分高频干扰。4. 软件配置与温度换算实操4.1 ADS122U04寄存器配置流程ADS122U04有四个配置寄存器上电后需要按顺序写。我一般用下面这个配置流程// 假设SPI接口已经初始化CS控制函数为ADS_CS_LOW()和ADS_CS_HIGH() // 写寄存器函数先发0x40|(reg2)|(num-1)再发数据 void ADS122U04_Init(void) { ADS_CS_LOW(); // 配置寄存器0PGA使能增益820SPS连续转换模式 // MUX[3:0]0000 差分通道0GAIN[2:0]011 增益8 // DR[2:0]010 20SPSCM1 连续转换TS0 禁用温度传感器 ADS_WriteReg(0, 0x0A); // 0000 1010 // 配置寄存器150/60Hz抑制低侧参考IDAC关 // 具体位定义参考手册这里设50Hz抑制 ADS_WriteReg(1, 0x00); // 配置寄存器2外部参考IDAC电流1mA // VREF[1:0]00 外部参考IDAC[2:0]100 1mA ADS_WriteReg(2, 0x20); // 0010 0000 // 配置寄存器3IDAC1路由到AIN0IDAC2关 ADS_WriteReg(3, 0x00); ADS_CS_HIGH(); }这里解释几个关键位。MUX设成0000表示选差分通道0也就是AIN0和AIN1之间的电压。GAIN设成011对应增益8。DR设成010对应20SPS这个速率下50Hz和60Hz抑制都能做到-100dB以上。CM设成1是连续转换模式ADC自己按速率转换DRDY引脚会周期性拉低通知MCU。如果设成单次转换模式每次都要发命令启动软件开销大。IDAC配置在寄存器2和3里。IDAC[2:0]100对应1mAIDAC1_ROUTE设成000表示从AIN0输出。这样电流从AIN0流出经过RTD回到AIN3或者外部地。具体路由要看你的硬件接法。4.2 读取转换结果与数据格式处理ADS122U04输出24位二进制补码。正满量程是0x7FFFFF负满量程是0x800000。读取时先发0x10命令读数据然后连续读3个字节。注意SPI是MSB先行第一个字节是最高8位。int32_t ADS122U04_ReadData(void) { uint8_t buf[3]; int32_t raw; ADS_CS_LOW(); SPI_Transfer(0x10); // 读数据命令 buf[0] SPI_Transfer(0x00); buf[1] SPI_Transfer(0x00); buf[2] SPI_Transfer(0x00); ADS_CS_HIGH(); raw ((int32_t)buf[0] 16) | ((int32_t)buf[1] 8) | buf[2]; // 符号扩展如果bit23是1高8位补1 if (raw 0x800000) { raw | 0xFF000000; } return raw; }这里有个坑很多新手忘了符号扩展结果负温度读出来变成很大的正数。24位补码的负数在32位里要手动补高8位不然0xFFFFFF会被当成16777215而不是-1。4.3 RTD温度换算从ADC码到摄氏度拿到raw值后先算RTD电阻。比率法公式R_RTD R_REF × (Code / 2^23) / PGA其中Code是ADC码2^23是满量程码值8388608PGA是增益。假设R_REF1650ΩPGA8Code1000000那么R_RTD 1650 × (1000000 / 8388608) / 8 1650 × 0.1192 / 8 24.59Ω这个值明显不对因为PT100在0℃时应该是100Ω。问题出在公式上。比率法里参考电压VREF I_EXC × R_REFRTD电压V_RTD I_EXC × R_RTD。ADC码 (V_RTD × PGA / VREF) × 2^23。代入Code (I_EXC × R_RTD × PGA) / (I_EXC × R_REF) × 2^23 (R_RTD × PGA / R_REF) × 2^23所以R_RTD R_REF × Code / (PGA × 2^23)重新算R_RTD 1650 × 1000000 / (8 × 8388608) 1650 × 1000000 / 67108864 24.59Ω还是不对。等等我检查一下。如果R_RTD100ΩPGA8R_REF1650Ω那么Code (100 × 8 / 1650) × 8388608 0.4848 × 8388608 4067040。反过来Code4067040时R_RTD 1650 × 4067040 / (8 × 8388608) 1650 × 4067040 / 67108864 100Ω。对了。所以之前Code1000000算出来24.59Ω是对的因为1000000对应的RTD电阻就是24.59Ω不是100Ω。我举的例子数值不匹配但公式是对的。实际代码里为了效率可以先把R_REF / (PGA × 2^23)算成一个常数#define RREF 1650.0f #define PGA 8.0f #define ADC_FS 8388608.0f #define RREF_SCALE (RREF / (PGA * ADC_FS)) float GetRTDResistance(int32_t code) { return (float)code * RREF_SCALE; }然后从电阻算温度。PT100的电阻-温度关系在-200℃到850℃范围内可以用Callendar-Van Dusen方程R(T) R0 × (1 A×T B×T² C×(T-100)×T³) T0℃时C项才有效对于T≥0℃R(T) R0 × (1 A×T B×T²)其中R0100ΩA3.9083e-3B-5.775e-7。反解TT (-A sqrt(A² - 4B(1 - R/R0))) / (2B)这个公式在0到850℃精度很高误差小于0.01℃。负温度段要用C项C-4.183e-12但反解没有解析式一般用查表加插值。float RTD_ResistanceToTemp(float r) { float A 3.9083e-3f; float B -5.775e-7f; float R0 100.0f; float ratio r / R0 - 1.0f; float disc A*A - 4.0f*B*ratio; if (disc 0) return -999.0f; // 错误 float t (-A sqrtf(disc)) / (2.0f*B); return t; }注意sqrtf要包含math.hPIC18F87J50的编译器支持单精度浮点但速度不快。如果对实时性要求高可以预先算好电阻-温度表用线性插值查表速度快很多。4.4 软件滤波滑动平均加中值工业现场噪声大单次采样值可能跳变。我一般用滑动平均加中值滤波的组合。先连续采5个点去掉最大最小剩下3个取平均。这样既能抑制脉冲噪声又能平滑随机噪声。#define FILTER_SIZE 5 int32_t filter_buf[FILTER_SIZE]; uint8_t filter_idx 0; int32_t Filter_AddSample(int32_t new_sample) { filter_buf[filter_idx] new_sample; filter_idx (filter_idx 1) % FILTER_SIZE; // 复制到临时数组排序 int32_t temp[FILTER_SIZE]; for (int i 0; i FILTER_SIZE; i) temp[i] filter_buf[i]; // 冒泡排序 for (int i 0; i FILTER_SIZE-1; i) { for (int j 0; j FILTER_SIZE-1-i; j) { if (temp[j] temp[j1]) { int32_t t temp[j]; temp[j] temp[j1]; temp[j1] t; } } } // 去掉最大最小取中间三个平均 return (temp[1] temp[2] temp[3]) / 3; }这个滤波器的延迟是5个采样周期20SPS下就是250ms对于温度这种慢变量完全可以接受。如果要求更快响应可以把FILTER_SIZE降到3但噪声抑制会差一些。5. 常见问题与排查技巧实录5.1 读数跳变严重怎么办这是最常见的抱怨。先分清楚是随机跳变还是有规律的周期性跳变。随机跳变一般是噪声周期性跳变可能是工频干扰或者ADC配置问题。排查步骤先把ADS122U04设成单次转换模式用示波器看DRDY信号和SPI时钟确认时序没问题。然后短接模拟输入看ADC输出码的峰峰值。如果短接时噪声就很大说明是ADC本身或者电源问题。检查AVDD纹波用示波器AC耦合看峰峰值应该在100μV以下。如果电源没问题检查参考电压REFP和REFN之间的电容是不是焊好了。如果短接时噪声正常接上RTD才跳那就是传感器或者引线引入的干扰。检查RTD引线是不是跟动力线走在一起了如果是分开走或者用屏蔽线。屏蔽层单端接地接在电路板的地上不要两端都接否则形成地环路。还有一个容易被忽略的点ADS122U04的输入多路复用器在切换通道时会有电荷注入如果信号源内阻高恢复时间不够读数就会跳。解决办法是在模拟输入前面加RC滤波电阻100Ω到1kΩ电容100nF给电荷注入提供低阻泄放路径。5.2 温度读数整体偏移怎么校准如果所有读数都偏同一个方向比如总是高2℃那是系统误差可以校准掉。校准方法把RTD放到冰水混合物里0℃读ADC码算出实际电阻跟理论值100Ω比较得到一个偏移量。然后在软件里减去这个偏移。但要注意偏移可能来自多个地方参考电阻精度、PGA增益误差、RTD本身精度。如果偏移随温度变化那就是温漂问题单点校准解决不了。这时候要做两点校准0℃和100℃各校一次算出一个增益误差和一个偏移误差软件里做线性修正。我一般建议客户用0.01%精度的参考电阻RTD选A级±0.15℃0℃这样不校准也能做到±0.3℃以内。如果要±0.1℃必须校准而且校准用的温度源精度要至少高一个数量级。5.3 SPI通信失败怎么查SPI通信失败的表现是读回来的数据全是0或者全是0xFF。先检查硬件CS、SCLK、DIN、DOUT四根线有没有接反特别是DIN和DOUT很多人会搞混。ADS122U04的DIN是MCU输出、ADC输入DOUT是ADC输出、MCU输入。然后用示波器看SCLK有没有波形频率对不对。如果SCLK正常但DOUT没反应检查CS是不是一直拉低。ADS122U04要求每次读写操作CS都要拉低再拉高如果CS一直低ADC可能不响应。还有一个坑ADS122U04上电后需要至少一个SPI时钟周期来初始化内部状态如果MCU上电后立刻发命令可能第一个命令被忽略。我一般在初始化SPI后延时10ms再配置ADC。如果时序都对但数据还是不对检查SPI模式。ADS122U04要求CPOL0、CPHA1也就是模式1。PIC18F87J50的SSPSTAT寄存器里CKP和CKE位要设对。CKP0对应空闲低电平CKE1对应下降沿发送、上升沿接收。设错了数据会移一位读出来全是错位的数据。5.4 常见问题速查表现象可能原因排查方法解决措施读数跳变±5℃以上电源纹波大示波器AC耦合测AVDD加LDO增加去耦电容读数整体偏高2℃参考电阻精度差万用表测参考电阻实际值换0.1%精度电阻软件校准负温度读成正值符号扩展遗漏检查代码是否补高8位加符号扩展逻辑SPI读回全0CS未拉低或时序错示波器看CS和SCLK检查CS控制确认SPI模式1温度响应迟钝滤波太强或速率太低检查DR和滤波参数提高速率减小滤波窗口多点采集互相干扰多路复用切换太快切换后延时再采样增加通道切换后的稳定时间高温段误差变大RTD非线性或自热对比标准温度计用Callendar-Van Dusen全公式减小激励电流5.5 实操心得几个文档里不会写的细节第一个ADS122U04的DRDY引脚在连续转换模式下会周期性拉低但如果你在DRDY拉低后没有及时读数据下一个转换周期开始时DRDY会再次拉低旧数据就丢了。所以DRDY中断服务程序里要尽快读数据别在里面做浮点运算。我的做法是中断里只读raw值存到缓冲区主循环里再做滤波和温度换算。第二个PIC18F87J50的SPI模块在高速时钟下如果SSPIF标志没及时清除会阻塞下一次传输。我一般在SPI_Transfer函数里等SSPIF置位后立刻清除再返回数据。别用延时等待不同主频下延时不准。第三个RTD引线如果很长比如超过10米引线电容会跟ADS122U04的输入电容形成低通影响建立时间。这时候要降低SPI速率或者增加通道切换后的延时。我有个项目引线15米通道切换后延时2ms才采样数据才稳定。第四个校准的时候别只校一个温度点。我见过一个客户在25℃室温下校准结果用到80℃时误差1.5℃。后来发现是参考电阻的温漂导致的换5ppm/℃的电阻后误差降到0.2℃。所以校准至少要在工作温度范围的两端各取一个点。6. 系统集成与现场调试经验6.1 从实验室到现场环境差异带来的挑战实验室里跑通不代表现场能用。我印象最深的一个HVAC项目实验室里精度做到±0.05℃装到楼顶空调机组上读数每隔几秒跳一次幅度有1℃。排查了半天发现是机组里的变频器干扰。变频器开关频率8kHz谐波丰富通过空间辐射耦合到RTD引线上。解决办法分三步第一步RTD引线换成双绞屏蔽线屏蔽层接机柜地。第二步在ADS122U04模拟输入前加共模扼流圈抑制共模干扰。第三步把ADC的转换速率从20SPS降到5SPS数字滤波器对低频干扰抑制更强。三步做完跳变降到0.1℃以内。这个经验告诉我工业现场的EMC问题光靠电路设计不够布线、屏蔽、接地都要考虑。特别是RTD这种高阻抗小信号传感器引线就是天线不屏蔽等于把干扰直接引到ADC输入端。6.2 多点温度采集的通道切换策略HVAC系统经常要测多个点的温度比如回风、送风、新风、盘管表面。ADS122U04有4个通道可以接4路RTD。但通道切换时有个问题多路复用器切换后输入电容需要充电到新的电压如果信号源内阻高充电时间不够读数会偏低或偏高。我的做法是切换通道后先丢弃第一次转换结果从第二次开始读。因为ADS122U04在连续转换模式下通道切换后的第一次转换可能不准确。具体操作是写配置寄存器切换MUX等DRDY拉低读一次数据但不使用再等DRDY拉低读第二次数据才用。如果对速度要求高可以在每个通道的输入前面加一个缓冲运放比如OPA333输入偏置电流只有10pA不会影响RTD测量但输出阻抗低多路复用器切换后能快速建立。这样每次切换后第一次转换就能用吞吐率翻倍。6.3 低功耗设计电池供电场景的取舍有些HVAC无线传感器节点用电池供电功耗很关键。ADS122U04在20SPS连续转换模式下功耗大约300μAPIC18F87J50跑8MHz时大约5mA加起来对电池来说还是太大。这时候要改成单次转换模式MCU平时休眠定时器唤醒后启动ADC转换完读数据再休眠。单次转换模式下ADS122U04从休眠到转换完成大约需要1ms20SPS时。MCU唤醒后发启动命令等DRDY拉低读数据然后发关机命令。整个周期大约5ms如果每分钟测一次平均电流可以降到10μA以下。用2000mAh的电池理论能跑好几年。但要注意ADS122U04从关机状态唤醒后内部参考和PGA需要建立时间。手册里写的是大约100μs但实际测试下来如果要求高精度最好等1ms再启动转换。我一般设成唤醒后延时2ms再发启动命令确保内部电路稳定。6.4 温度数据的线性化与上报从ADC码到温度值中间要经过电阻计算、线性化、滤波、单位换算。如果MCU还要跑通信协议计算量不小。PIC18F87J50没有硬件浮点单精度浮点运算靠软件模拟一次sqrtf大约要几百个周期。如果每秒采10次每次都要算sqrtfCPU占用率会很高。优化方法用查表加线性插值代替浮点运算。预先在Flash里存一张电阻-温度表比如每10℃一个点从-50℃到150℃共21个点。查表时先找到电阻落在哪个区间然后线性插值。这样只需要整数运算和一次除法速度快很多。// 简化的查表插值示例 const uint16_t r_table[] {8031, 8427, 8822, 9216, 9610, 10000, 10390, 10779, 11167, 11554, 11940, 12324, 12707, 13089, 13470, 13850, 14229, 14606, 14982, 15357, 15731}; // 对应-50℃到150℃每10℃一个点单位0.01Ω int16_t ResistanceToTemp(uint16_t r_centiohm) { if (r_centiohm r_table[0]) return -500; if (r_centiohm r_table[20]) return 1500; for (int i 0; i 20; i) { if (r_centiohm r_table[i1]) { uint16_t r_lo r_table[i]; uint16_t r_hi r_table[i1]; int16_t t_lo -500 i * 100; int16_t t_hi t_lo 100; return t_lo (int16_t)((int32_t)(r_centiohm - r_lo) * 100 / (r_hi - r_lo)); } } return 1500; }这个函数返回的温度单位是0.01℃用int16_t表示范围-5000到15000对应-50℃到150℃。整数运算速度快精度在0.1℃以内对HVAC应用足够了。6.5 现场调试工具的准备去现场调试别只带个万用表。我一般带这几样一台带SPI解码功能的示波器比如带MSO的一个USB逻辑分析仪便宜的那种就行一个高精度温度计作为参考还有几个不同阻值的精密电阻用来模拟RTD。到了现场先别急着改代码先用精密电阻代替RTD看读数对不对。如果电阻模拟时读数准接上RTD不准那就是传感器或者引线问题。如果电阻模拟时就不准那是电路或者软件问题。这一步能快速定位问题方向。逻辑分析仪抓SPI波形看命令和数据对不对。有时候是MCU发命令时CS拉低太晚或者SCLK太快导致ADC没响应。逻辑分析仪能直观看到时序问题比示波器方便。高精度温度计用来做现场校准。如果现场没有冰水混合物可以用温度计的读数作为参考在软件里做单点偏移校准。虽然精度不如实验室校准但能消除大部分系统误差。7. 方案扩展与变体思路7.1 从PT100扩展到热电偶如果应用场景温度超过500℃PT100就不合适了得用热电偶。ADS122U04也能接热电偶但需要冷端补偿。冷端补偿可以用ADS122U04的第四个通道接一个PT1000或者LM35测电路板温度作为冷端温度。软件里把热电偶的热电动势加上冷端对应的热电动势再查表得到实际温度。热电偶的信号比RTD小得多K型热电偶在100℃时输出大约4mV需要PGA128才能充分利用ADC量程。但PGA128时ADS122U04的输入共模范围很窄要仔细设计偏置电路。我一般用两个等值电阻分压把热电偶的一端偏置到VREF/2另一端接ADC负输入。7.2 多片ADS122U04级联做高密度采集如果通道数超过4个可以用多片ADS122U04每片用一个独立的CS引脚共用SPI时钟和数据线。PIC18F87J50有多个I/O口可以控制8片甚至16片。每片的DRDY可以接到不同的中断引脚或者用一个二极管或门合并成一个中断然后在中断里轮询各片的DRDY状态。级联时要注意电源去耦每片ADS122U04的AVDD都要单独去耦不能共用一颗电容。SPI时钟线要加缓冲器因为多片并联时容性负载大时钟边沿会变缓。我一般用74LVC244做缓冲每4片一组。7.3 加入隔离工业现场的安全与抗扰工业现场有时候要求传感器和主控之间电气隔离防止地环路或者高压串扰。ADS122U04的SPI接口可以加数字隔离器比如ADuM1401把MCU和ADC隔开。但隔离后ADC的电源也要隔离用一个小型DC-DC模块比如B0505S给隔离侧的ADS122U04供电。隔离会引入额外的噪声和延迟SPI速率要降到1MHz以下。隔离侧的电源纹波也要处理好DC-DC后面加LDO和LC滤波。我做过一个项目隔离后噪声反而比不隔离大后来发现是DC-DC的开关频率耦合到模拟电源上了换了低噪声的DC-DC模块才解决。7.4 用PIC18F87J50的USB做数据记录PIC18F87J50自带USB可以做一个简单的数据记录仪。温度数据存到外部EEPROM或者SD卡里通过USB导出到PC。Microchip的USB协议栈有现成的CDC类驱动PC端识别成串口用串口助手就能看数据。USB供电时整个系统可以从USB取电不需要外部电源。但USB的5V要降到3.3V给MCU和ADC用一颗LDO就行。注意USB的地和模拟地要单点连接避免数字噪声串到模拟部分。8. 写在最后的一些个人体会这套ADS122U04IPWR加PIC18F87J50的温度测量方案我从2019年第一次用在某个洁净室空调控制项目上到现在陆陆续续改了十几版。最大的感受是高精度测量是个系统工程ADC再好电源不干净、布局不合理、软件滤波不到位照样出不来好结果。新手最容易犯的错是只盯着ADC的分辨率觉得24位就一定比12位准。实际上如果参考电阻温漂大、电源纹波高、PCB布局差24位ADC的有效位数可能只有14位跟12位比也好不到哪去。我一般建议先把电源和参考做好再考虑ADC选型。另一个体会是校准比选型更重要。再好的器件也有误差工业现场的温度测量不校准很难做到±0.5℃以内。校准不丢人关键是要有可追溯的校准方法和定期校准的计划。最后说一个实用技巧如果现场调试时发现温度读数有规律地缓慢漂移比如每小时漂0.5℃先别怀疑ADC去看看参考电阻周围有没有发热元件。我有一次把参考电阻放在LDO旁边LDO发热导致电阻温漂读数跟着漂。把电阻挪到板子边缘远离热源问题就解决了。这种问题数据手册上不会写只有踩过坑才知道。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑