这几年的项目里用 ADS122U04IPWR 这颗带 UART 接口的 24 位 ADC 搭配 PIC18F46K22 单片机做工业和 HVAC 温度测量是我个人觉得比较顺手的组合。这个标题看着像是一行选型记录但真把它从原理图变成能稳定出数的样机中间有不少细节值得聊。无论你是刚接触 RTD 和热电偶测量还是已经在做暖通控制器但苦于模拟前端噪声这篇文章都适合你。我会把硬件连接、寄存器配置、驱动代码、标定经验这些实操层面的东西以及踩过的坑尽量按实际开发顺序讲清楚。1. 项目整体设计与硬件选型思路1.1 为什么选 UART 型 ADC而不是常规 SPI 型先说选型逻辑。很多工程师一提到高精度 ADC下意识就会选带 SPI 接口的型号因为这确实是主流。但你在做分布式温度采集时SPI 有两个让人头疼的地方一是时钟线、片选线、数据线加起来至少四根线现场走线会比较麻烦二是 SPI 时序对从机距离和信号完整性比较敏感线一长就容易丢数据或者粘波。ADS122U04IPWR 的特殊价值在于它把 SPI 换成了 UART一根发送、一根接收接法和串口一模一样。对于 PIC18F46K22 这类带硬件 EUSART 的 MCU 来说驱动起来特别省事波特率设好发命令、收数据就行不用像 SPI 那样自己模拟片选时序也不用担心主从时钟相位错位的问题。而且 UART 天然适合做隔离未来如果要在工业现场加数字隔离器串口侧隔离实现起来也比 SPI 简单很多。当然UART 型 ADC 不是没有代价比如它的寄存器配置是需要按字节操作、时序有固定帧格式不能像 SPI 那样随意拉时序。但对于温度测量这个场景采样率本来就不高单次转换、读结果、再计算这个节奏和串口通信很配。1.2 为什么 PIC18F46K22 足够胜任有人可能会问都 202x 年了还选 8 位单片机我的回答是温度测量这个项目的瓶颈从来不是 MCU 的算力而是模拟前端的稳定性和算法上的标定精度。PIC18F46K22 在这类项目里的优势主要有几点片内集成两个 EUSART其中一个专门给 ADS122U04 用另一个留给 Modbus 或调试串口互不干扰。内部振荡器经过校准后精度足够跑 UART省掉一个外部晶振成本低、BOM 简单。工作电压范围宽5V 供电时可以直接和 ADS122U04 的 I/O 兼容不需要额外的电平转换。工业级温度范围在 HVAC 控制柜里长期运行没什么压力。从软件架构上讲8 位机上用状态机轮询 UART 中断、管理转换命令、做滑动滤波整套逻辑非常清晰。非要上 Cortex-M 反而有点浪费而且 5V 系统的外设接口兼容性还得重新设计。1.3 系统架构与信号流向这套系统的信号链路大致如下温度传感器PT100/PT1000 或热电偶就近接入 ADS122U04。ADS122U04 内部 PGA 做小信号放大24 位 delta-sigma ADC 完成数字化通过 UART 把转换结果发给 MCU。MCU 负责发送转换命令、读取 24 位数据、执行线性化算法和标定补偿再输出给显示、继电器控制或者 Modbus 通信模块。把模拟前端独立到 ADC 这颗芯片上而不是用 MCU 内部 ADC最大的好处是噪声隔离。MCU 内部往往有数字开关噪声直接采样几百微伏的 RTD 信号很难保证稳定。外置高精度 ADC 可以离传感器更近信号还没到 MCU 就已经被转成数字量抗干扰能力完全不一样。1.4 适合的应用场景这套方案最典型的应用有两块工业过程监测和 HVAC 系统。工业场景里常见的有电机轴承温度、冷却水温度、管道介质温度。这些场合传感器距离控制器常常有几十米信号线会经过变频器、继电器等强干扰源对 ADC 的动态范围和稳定性要求高。HVAC 场景则包括回风温度、送风温度、盘管进出水温度、室外温度等。这些地方对绝对精度的要求通常在 ±0.5°C 以内但对长期稳定性和批量一致性要求很高毕竟暖通控制器是 7x24 小时运行的而且现场维护条件差。ADS122U04 内部有可编程激励电流源和精密基准可以把 RTD 接成比例测量长期漂移能做到很小恰好匹配这类需求。2. 传感器接入与测量原理拆解2.1 为什么用比例测量来消除电流源漂移温度测量里最常见的传感器就是铂电阻PT100 在 0°C 时阻值 100Ω大约每升高 1°C 阻值增加 0.385Ω。这个变化量非常小如果只靠 ADC 测“绝对电压”那电流源哪怕漂一点点换算出来的温度就会偏很多。ADS122U04 有内置可编程电流源 IDAC可以给 RTD 供电。关键点在于我们可以用同一个电流源同时驱动一个精密参考电阻 RREF然后把 RREF 两端的电压作为 ADC 的参考电压RTD 两端的电压作为输入信号。这样最终转换结果只取决于 RTD 和 RREF 的阻值比电流源本身的温漂、老化、电压波动全都被抵消了。这个原理和数字万用表测电阻用的比例法是一个思路。只要 RREF 选得好系统精度主要被 RREF 的精度和温漂决定而不是 ADC 的绝对参考电压。2.2 两线、三线、四线制 RTD 的误差分析RTD 接线方式直接决定测量误差现场很容易忽略。两线制最省线但问题很明显导线电阻直接串联进 RTD比如 10 米线缆铜导线电阻可能有 1~2Ω换算成温度就是好几度。所以两线制只能用在短线、低精度要求的场合。三线制是工业现场的主流方案。做法是让 IDAC 电流从一根线进去从 RTD 出来后再分两条路回到测量端利用多一根线的对称性把导线压降从差分测量结果中抵消掉。只要两根线阻值一致误差就能压到很小。四线制最精确用一对线给 RTD 供电流另一对线专门测电压电压测量回路几乎没有电流流过导线电阻带来的误差基本为零。实验室和计量设备常用但现场布线成本高。HVAC 项目里我一般推荐三线制精度足够施工成本也合理。唯一要注意的是现场接线时两根引线尽量用同一段电缆里的双绞线保证阻值对称和抗干扰能力。2.3 热电偶接入与冷端补偿热电偶的输出是毫伏级别的热电势而且它测的是“温差”必须知道冷端温度才能算热端真实温度。ADS122U04 内部集成了片内温度传感器可以直接测量芯片附近温度这个温度通常可以当作冷端参考温度。把热电偶的冷端尽量贴近 ADC 的引脚区域用内部温度传感器读数做补偿就能把误差控制在可接受范围。如果对冷端精度要求比较高也可以外接一个 PT1000 紧贴冷端位置用另一路 ADC 通道专门测量冷端温度效果更好。只是这样要多占一个通道还要多一个传感器。2.4 信号链路的增益与数据率选择热电偶信号通常只有几十毫伏RTD 信号经过电流源转换后也大概是几十到几百毫伏。这就需要 PGA 做前置放大。ADS122U04 的 PGA 增益有多个档位选增益时要注意增益高了小信号分辨率高但噪声也会被放大增益低了信号可能填不满 ADC 的量程分辨率浪费。数据率也要和噪声做平衡。delta-sigma ADC 的数据率越低内部数字滤波器抽样的平均值越多噪声越小。温度测量本身是慢变信号我一般选 20SPS 或 50SPS实时性完全够用噪声又能压到很低。如果做快速响应温度计可以提到 200SPS但要做好读数波动的心理准备。3. 硬件连接和 PIC18F46K22 驱动实现3.1 引脚分配与供电去耦以 HVAC 控制板为例我常用的引脚分配如下PIC18F46K22 引脚功能方向连接目标说明RC6/TX1输出ADS122U04 的串口接收端发送命令RC7/RX1输入ADS122U04 的串口发送端接收数据RA0输出片选或复位控制可选根据实际芯片行为决定VDD/VSS-5V 供电需要稳定的电源轨AN0输入可选冷端参考测量如果用外部冷端补偿ADS122U04 的电源去耦要特别注意因为它是混合信号芯片模拟电源和数字电源虽然内部有管理但外部该加的去耦电容一个都不能省。我习惯在每个电源引脚附近放一个 10uF 钽电容加一个 0.1uF 陶瓷电容而且尽量靠近引脚。参考电阻 RREF 要用低温漂的金属膜电阻精度 0.1%温漂 25ppm 以内否则它会成为整个系统精度天花板。UART 连接比较直接TX、RX 交叉互联共地。如果 MCU 是 5V、ADC 也支持 5V电平兼容没有问题。如果两者供电电压不同就需要加电平转换或串阻分压别图省事直接硬接。3.2 XC8 环境下的 UART 初始化PIC18F46K22 用 Microchip 的 XC8 编译器开发。UART1 初始化的核心代码大致如下以 9600 波特率、8 位数据、无校验、1 停止位为例#define _XTAL_FREQ 16000000UL void uart1_init(void) { TRISC6 0; // TX1 - RC6 输出 TRISC7 1; // RX1 - RC7 输入 TXSTA1bits.TXEN 1; // 使能发送 RCSTA1bits.SPEN 1; // 使能串口 BAUDCON1bits.BRG16 1; SPBRG1 ((_XTAL_FREQ / 9600UL) / 16UL) - 1; // 如果波特率误差偏大微调 BRG16 和 SPBRGH1 }UART 波特率误差要注意PIC 的 UART 硬件如果 BRG 值计算误差超过 2%长帧通信或者连续多字节数据时容易出错。最好在代码里顺手算一遍实际波特率偏差超过 1% 就换晶振频率或降低波特率。3.3 ADS122U04 的寄存器配置顺序ADS122U04 的配置寄存器需要按照数据手册的帧格式写入命令一般是复位、写寄存器、启动转换、读数据这几类。建议上电后第一件事就是发一次复位命令把芯片内部状态清干净然后再配置寄存器。顺序很重要因为某些寄存器位在写的时候有依赖关系。一个典型的单次转换配置流程// 发送单字节复位命令 void ads122u_reset(void) { uart1_send_byte(0x06); __delay_ms(2); } // 写配置寄存器reg_addr 为寄存器地址data 为配置值 void ads122u_write_reg(uint8_t reg_addr, uint8_t data) { uart1_send_byte(0x40 | (reg_addr 0x0F)); uart1_send_byte(0x00); // 高字节地址位根据手册定义 uart1_send_byte(data); } void ads122u_init(void) { ads122u_reset(); // 配置输入多路复用器例如 AIN0/AIN1 作为差分输入 ads122u_write_reg(0x00, 0x10); // 配置 PGA 8数据率 20SPS ads122u_write_reg(0x01, 0x08); // 使能内部参考电压并启用参考电阻输入 ads122u_write_reg(0x02, 0x40); // 设置 IDAC 电流为 500uA 并输出到 AIN0 ads122u_write_reg(0x03, 0x10); }上面代码里的配置数值是示例实际必须以官方数据手册的位定义为准因为不同版本的寄存器编码方式可能有差异。但你只要把“复位 - 写寄存器 - 启动转换 - 读数据”这个顺序理解了换寄存器值就只是查手册的事。3.4 启动转换和读取 24 位结果单次转换模式下MCU 先发启动命令等待 DRDY 信号或者固定延时然后读取 24 位数据。ADS122U04 在 UART 模式下发送请求后会返回转换结果读取字节数要和 24 位对齐。核心代码框架如下void ads122u_start(void) { uart1_send_byte(0x08); // 启动单次转换 } int32_t ads122u_read_data(void) { int32_t raw 0; raw | (int32_t)uart1_receive_byte() 16; raw | (int32_t)uart1_receive_byte() 8; raw | (int32_t)uart1_receive_byte(); // 如果 24 位数据用补码表示负数时扩展符号位 if (raw 0x800000) { raw | ~0x7FFFFF; } return raw; }读取数据后要判断数据是否有效比如检查溢出位或者 DRDY 状态。我见过很多人直接拿头三字节开始算温度结果数据其实还是上一次转换的旧值。稳妥做法是每次转换完成后再读数据返回后再用新的值更新结果避免异步错位。3.5 温度换算与标定流程对于 RTD 比例测量最简单的换算公式是float rtd_resistance(int32_t raw_code, float rref) { float ratio (float)raw_code / 0x800000UL; // 双极性满量程归一化 return rref * ratio; }拿到 RTD 阻值后再用铂电阻分度表或 Callendar-Van Dusen 多项式换算成温度。工程上我建议用查表加线性插值这比在 8 位单片机上跑复杂的浮点多格式快很多而且在 0~100°C 范围内插值精度完全够。标定流程不要省。虽然 ADS122U04 内部基准已经很不错RREF 也选高精度但批量生产时还是建议做两点校准用精密电阻箱分别模拟 0°C 和 100°C 对应的阻值读出原始码然后算出增益误差和偏置误差写进 EEPROM 存储运行时做线性修正。顺带一提软件滤波也别过度。滑动平均窗口取 8~16 次就够了窗口太大不但延时大而且会对真实温度变化反应迟钝。HVAC 里温度本来就变化慢16 点滑动平均很合适但如果做工业报警联锁窗口要适当缩短。4. 常见问题与排查技巧4.1 读数跳字大噪声降不下来这是最常遇到的问题。如果你发现转换结果在 ±几 LSB 甚至几十 LSB 之间跳先别急着怀疑芯片按顺序排查供电纹波。用示波器看 AVDD 引脚如果高频噪声明显加大去耦电容必要时在电源入口加磁珠或 LDO。参考电阻两端噪声。RREF 两端是 ADC 的参考电压它上面的噪声会直接反映到转换结果上。周围如果有数字信号线高速翻转尽量拉开距离。PGA 增益和数据率的配合。增益高加数据率也高时噪声肯定大。把数据率降到 20SPS噪声通常会有明显改善。接线是否绞合。RTD 两根引线必须双绞否则磁场耦合会让共模噪声变成差模噪声。4.2 UART 通信偶尔丢字节数据错位UART 通信不稳定最常见原因是波特率误差。PIC18F46K22 内部振荡器虽然校准过但温度变化后可能会有偏移。如果你发现热机后通信频繁出错多半是振荡器漂移导致的波特率偏差。解决办法有几个降波特率比如从 9600 降到 4800容错时间窗变宽。改用外部晶振稳定性更好。在 UART 线上加 RC 滤波或者用带光耦隔离的方案。另外如果 ADC 和 MCU 之间的地线回路比较大UART 电平在瞬态噪声下容易误判。工业现场布线时ADC 侧地线和 MCU 侧地线要尽量短最好单点接地。4.3 换了三线制 RTD 后温度还是偏三线制要真正起作用必须保证两根引线电阻对称。我在现场见过很多次工人把三线制传感器接成三根不同长度的线或者用不同线径的线续接这等于没做三线补偿。还有一个容易忽略的点IDAC 电流档位要选合适。如果电流太小信号幅度不足电流太大RTD 自身发热会造成自热误差。PT100 我常用 500uA~1mAPT1000 用 250uA~500uA这样自热影响可以控制在 0.1°C 以内。4.4 冷端补偿怎么调都差一两度热电偶冷端补偿不准多数情况是冷端温度传感器和热电偶的冷端不在同一个温度点上。ADS122U04 内部温度传感器反映的是芯片内部温度如果你把热电偶连接器贴在 PCB 板上但芯片发热明显内部传感器读到的温度和连接器实际冷端温度就会有偏差。解决办法有几个思路让热电偶冷端尽量靠近芯片的引线区域同时在 PCB 上做等温区设计减少热梯度或者干脆用外置 PT1000 贴在端子排上直接测量冷端温度再代入热电偶多项式计算。后者在工程上更可靠尤其是环境温度变化大的场合。4.5 切换通道后读数要等多久如果系统配置了多个通道比如同时测回风温度和盘管水温每次切换 MUX 后不能立刻读数据。ADC 内部滤波器和 PGA 需要建立时间通道切换后至少要等几个转换周期。很多人设计多通道扫描时切完通道马上启动转换结果前几次读数都是上一通道的残余值。我习惯的做法是通道切换后先丢弃当前通道前 2~3 次转换结果再开始正常采样。这样牺牲一点点响应时间换来的是数据可靠性。5. 工程落地经验与后续扩展方向5.1 从样机到量产供电和 EMC 是重头戏实验室里跑得好好的板子一到现场就飘多半是供电和 EMC 的问题。温度采集板在工业现场通常和接触器、变频器、水泵电机装在一个柜子里干扰环境非常恶劣。我的建议电源入口加 TVS 管和共模电感防浪涌和共模干扰。ADC 模拟部分供电单独走 LDO不要和 MCU 数字供电共用一路开关电源。所有传感器线都用屏蔽线屏蔽层单端接地避免形成地环路。PCB 上模拟地和数字地单点连接不要让数字电流流过模拟地平面。另外批量标定一定要有流程。每个通道的增益误差和偏置都要测不能只校准一个通道就批量套用。ADS122U04 有多个输入通道每个通道的开关导通电阻虽然很小但并不是完全一致批量生产时通道之间的校准值要分开存。5.2 扩展方向从单机采集到总线组网这套系统再往上发展自然就是组网。PIC18F46K22 还有一路多余的 UART可以直接挂 Modbus RTU把温度数据上报给 PLC 或楼宇自控系统。ADS122U04 负责模拟采集MCU 负责协议栈各干各的活架构非常清晰。如果现场干扰特别大考虑在 UART 和 MCU 之间加数字隔离器把模拟侧和数字侧完全隔开。隔离后系统的共模抑制能力会提升很多但要注意隔离电源的噪声不要因为隔离反而引入了更大的电源纹波。5.3 关于成本的一点看法很多人一看到 24 位 ADC 就觉得贵。但实际上对于工控和暖通产品来说PCB 面积、调试时间、售后维护成本往往比几块钱的芯片差价更值钱。ADS122U04 这种把激励源、基准、温度传感器、UART 全部集成在一起的方案省掉了外围一堆分立元件整板物料成本和布板难度反而更低。手头正在做相关项目的朋友我个人建议是先把比例测量的电阻网络搭好用精密电阻箱熟悉读数规律再上热电偶和冷端补偿这些复杂功能。温度测量这行没有玄学所有异常都能在“噪声、参考、接线、校准”这四个维度里找到解释。把这几个环节的功夫下足了剩下的就是把数据算准、把产品做稳。 SEO 优化官网定制响应式建站教育培训建站