1. 项目缘起与整体设计思路多通道温度采集这个需求在工业现场、实验室环境、设备老化测试台架上出现的频率极高。我最早接触这类项目是在一个电机温升测试的场景里当时需要同时监测8个测点的温度变化采样间隔要求1秒以内数据要实时显示曲线并且能存下来做后续分析。市面上现成的多路温度巡检仪要么通道数不够灵活要么通讯协议封闭不好集成要么价格高得离谱。后来用Labview加单片机自己搭了一套成本压到几百块通道数想扩就扩数据格式完全自己说了算用到现在已经迭代了三版。这套系统的核心思路其实很朴素单片机负责前端的多路切换和模数转换Labview负责后端的显示、存储和分析。为什么这么分工因为单片机擅长做实时性要求高、逻辑简单的底层采集而Labview擅长做界面交互、数据处理和文件管理。把两者用串口连起来各干各擅长的事整个系统的稳定性和开发效率都是最优的。具体来说系统由三个部分组成。第一部分是传感器与信号调理电路负责把温度信号转换成单片机可以采集的电压信号。第二部分是单片机采集与传输模块负责多通道轮询、AD转换、数据打包和串口发送。第三部分是Labview上位机负责串口接收、数据解析、实时显示、报警判断和历史数据存储。这个方案最大的优势在于灵活。通道数不够加一片多路模拟开关就行。想换传感器类型改一下信号调理电路和软件里的换算公式就行。想加远程查看功能Labview这边加个网络发布就搞定。相比买成品设备自己搭的系统在可扩展性上完全是另一个维度。不过话说回来这套方案也有它的门槛。硬件上需要懂一点模拟电路和单片机编程软件上需要熟悉Labview的串口通信和数据处理。但这些都是可以边做边学的我见过不少非电子专业出身的人照着教程一步步来也能做出来。关键是理解每个环节在干什么为什么要这么干。2. 核心细节解析与实操要点2.1 传感器选型与信号调理温度传感器选型是整个系统的起点选错了后面全白搭。常见的方案有热电偶、热电阻和集成温度传感器三类。热电偶适合高温测量但信号微弱需要冷端补偿电路复杂。热电阻精度高、线性度好但需要恒流源激励成本略高。集成温度传感器比如DS18B20这类直接输出数字信号用一根线就能读但测温范围有限一般不超过125度。我最终选的是PT100铂热电阻三线制接法。为什么选三线制而不是两线制因为两线制没法消除导线电阻带来的误差导线越长误差越大。三线制通过补偿导线电阻能把误差控制在0.1度以内。具体电路上我用一个恒流源给PT100供电把电阻变化转换成电压变化再经过仪表放大器放大最后送入单片机的AD口。这里有个关键细节恒流源的精度直接决定了测量精度。我试过用普通的运放搭恒流源温漂比较大后来换成专用的恒流源芯片稳定性好了很多。放大倍数也要仔细算PT100在0度时是100欧姆100度时是138.5欧姆对应的电压变化范围要和单片机的AD量程匹配。比如用2mA恒流源0度时电压是200mV100度时是277mV变化范围只有77mV。如果单片机AD是10位、参考电压5V那最小分辨率是4.88mV对应温度分辨率大概是6.3度这显然不够用。所以必须放大放大倍数选50倍左右77mV变成3.85V刚好覆盖AD量程的大部分分辨率能到0.13度左右。多路切换用的是模拟多路开关比如CD4051这类8选1的芯片。用两片级联就能扩展到16通道。切换控制信号由单片机IO口给出注意切换后要留足够的建立时间再启动AD转换否则通道间会串扰。我一般留100微秒左右实测下来这个时间足够信号稳定。2.2 单片机采集与串口通信单片机这边我选的是STC15系列原因很简单便宜、资源够用、串口下载方便。它自带10位AD最多8通道如果不够就外扩多路开关。主频跑到24MHz做多通道轮询采集绰绰有余。采集流程是这样的定时器产生1秒的定时中断中断里依次切换通道、启动AD、读取结果、存入缓冲区。所有通道采集完后把数据打包成一帧通过串口发送给上位机。帧格式我设计成帧头两个字节加通道数据加校验和。帧头用0xAA和0x55这两个字节在数据里出现的概率低不容易误判。每个通道数据用两个字节表示高字节在前。最后加一个校验和把前面所有字节加起来取低八位。串口波特率选的是9600为什么不用更高的因为采集周期是1秒每次发送的数据量很小16个通道也就30多个字节9600的波特率完全够用。波特率低一点抗干扰能力反而更强传输距离也能更远。如果以后要缩短采集周期或者增加通道数再考虑提高到115200。这里有个坑要注意串口发送和AD采集如果都在中断里做要合理安排优先级。我的做法是AD采集用定时器中断串口发送用查询方式在主循环里做。采集到的数据先存到缓冲区主循环检测到缓冲区有新数据就发送。这样中断里的任务很轻不会影响采集的实时性。2.3 Labview上位机架构Labview这边是整个系统的脸面用户看到的就是这个界面。我的设计思路是左边显示实时曲线右边显示各通道当前值底部是控制按钮和状态栏。曲线用波形图表控件可以同时显示多条曲线每条曲线对应一个通道颜色自动分配。串口通信用的是VISA模块配置好波特率、数据位、停止位和校验位后用“串口字节数”属性节点判断缓冲区里有没有数据有就读出来。读出来的数据是字符串格式需要转成字节数组再解析。解析的时候先找帧头找到后按固定长度取出一帧校验通过后再把每个通道的两个字节拼成16位整数最后根据传感器特性换算成温度值。换算公式这里要特别注意。PT100的电阻和温度关系是非线性的但在0到100度范围内用线性近似公式R1000.385*T误差不超过0.5度。如果要求更高精度可以用查表法或者分段线性插值。我一般用线性公式加一个修正系数实测下来在0到150度范围内误差能控制在0.3度以内。数据存储用的是TDMS文件格式这是Labview自带的一种二进制格式写入速度快文件体积小而且自带通道分组和属性信息后期用DIAdem或者Excel都能打开。我一般按天建文件文件名里带上日期方便查找。每个通道存一列时间戳存一列这样后期分析的时候直接读进来就能用。3. 实操过程与核心环节实现3.1 硬件搭建与调试硬件部分我分成三块来搭传感器板、主控板和电源板。传感器板负责PT100的接线和信号调理主控板放单片机和多路开关电源板提供正负5V和3.3V。三块板之间用排线连接方便单独调试和更换。焊接的时候有个经验模拟部分和数字部分的地要分开走最后在电源入口处单点共地。我第一版没注意这个结果AD采集出来的数据跳动很大后来改了接地方式跳动从十几个字降到两三个字。另外PT100的引线要用屏蔽线屏蔽层接模拟地能有效抑制工频干扰。调试步骤我一般是这样先不接传感器用精密电阻箱模拟PT100的阻值从100欧姆到150欧姆逐点测试看Labview上显示的温度值对不对。如果不对先检查放大倍数和AD参考电压再检查换算公式。确认采集通道没问题后再接上真实的PT100放到恒温水浴里对比标准温度计做几点校准。校准的时候用两点校准法就够了选0度和100度两个点分别记录AD值和标准温度值算出斜率和截距写进单片机或者Labview的换算公式里。如果要求更高可以多做几个点用最小二乘法拟合。3.2 单片机程序关键代码单片机程序用C语言写开发环境是Keil。主程序框架很简单初始化定时器、串口和AD然后进主循环。定时器中断里做通道切换和AD采集主循环里做数据打包和串口发送。AD采集的关键代码如下void Timer0_ISR() interrupt 1 { static unsigned char ch 0; static unsigned int adc_buf[16]; ADC_CONTR 0x80 | ch; // 选择通道并启动转换 while (!(ADC_CONTR 0x20)); // 等待转换完成 adc_buf[ch] (ADC_RES 2) | (ADC_RESL 0x03); ADC_CONTR ~0x20; // 清除完成标志 ch; if (ch CHANNEL_NUM) { ch 0; data_ready 1; // 一帧采集完成 } }这段代码里有个细节STC15的AD结果是10位高8位在ADC_RES低2位在ADC_RESL的低两位。拼的时候要先把高8位左移2位再或上低2位。我见过有人直接读ADC_RES忘了低2位结果精度白白丢了4倍。串口发送的代码更简单把数据按帧格式填好然后逐个字节写入SBUF等发送完成标志置位后再发下一个字节。注意发送前要关串口中断发完再开否则中断里的接收逻辑会干扰发送。3.3 Labview程序框图设计Labview程序我分成三个并行循环串口读取循环、数据处理循环和界面刷新循环。三个循环之间用队列传递数据这样各循环的速率可以不一样不会互相阻塞。串口读取循环里VISA读函数设置为读取缓冲区所有字节读出来的数据直接入队。数据处理循环从队列里取数据做帧同步和解析解析出来的温度值再入另一个队列。界面刷新循环从第二个队列取数据更新波形图表和数值显示。帧同步的逻辑要仔细写。因为串口数据是流式的可能从中间某个字节开始读所以要先搜索帧头。我的做法是维护一个移位寄存器把新读到的数据和上次残留的数据拼起来然后从头搜索0xAA 0x55。找到后判断剩余长度够不够一帧够就取出来校验不够就留着等下次数据来了再拼。校验和的计算用“商和余数”函数把帧内所有字节求和后取低八位和帧尾的校验字节比较。如果对不上就丢弃这一帧重新搜索帧头。这个机制能过滤掉大部分干扰导致的数据错误。波形图表刷新的时候要注意如果数据点太多界面会卡。我的做法是每50毫秒刷新一次每次把队列里积累的数据一次性追加到图表上。这样既保证了实时性又不会因为刷新太频繁拖慢程序。4. 常见问题与排查技巧实录4.1 温度读数跳动大怎么办这是最常见的问题原因可能有三个。第一个是电源纹波大尤其是开关电源给模拟部分供电的时候。解决办法是在模拟电源上加LC滤波或者干脆用线性稳压器给模拟部分单独供电。第二个是接地不合理数字地和模拟地混在一起数字部分的开关噪声串到模拟部分。解决办法是分开走地单点共地。第三个是AD参考电压不稳如果直接用电源做参考电源波动会直接反映在AD结果上。解决办法是用专用的基准电压芯片比如REF3033这类。我遇到过一次特别诡异的跳动排查了半天发现是PT100的引线太长而且和电机的动力线捆在一起走工频干扰直接耦合进来了。后来把信号线单独走线槽远离动力线跳动立刻消失。所以布线的时候一定要把信号线和动力线分开交叉的时候尽量垂直交叉。4.2 串口通信丢数据怎么排查丢数据一般出在三个环节单片机发送、传输线路、上位机接收。排查的时候先看单片机这边用示波器或者逻辑分析仪抓串口波形看发送的字节数对不对波特率准不准。如果单片机发送没问题再看线路串口线太长或者周围有强干扰源都会导致数据错误。可以试试降低波特率或者换成屏蔽双绞线。上位机这边VISA读取的时候如果缓冲区设置太小数据来得太快就会溢出。解决办法是把缓冲区设大一点比如4096字节然后读取的时候一次性全读出来。另外Labview的串口读取循环如果处理太慢也会导致缓冲区溢出。可以把读取循环的优先级设高一点或者把数据处理放到另一个循环里做。我踩过的一个坑是串口打开后没有清空缓冲区结果上次残留的数据混进来导致帧同步一直失败。后来在打开串口后加了一个清空缓冲区的操作问题就解决了。4.3 多通道之间的串扰问题多路开关切换的时候如果建立时间不够上一个通道的电荷会残留在下一个通道上导致读数偏高或偏低。解决办法有两个一是增加切换后的延时让信号充分稳定二是在多路开关的输出端加一个电压跟随器提高输入阻抗加快建立时间。我实测下来CD4051在5V供电下通道切换的建立时间大概在几十微秒量级。如果采集速率要求不高延时100微秒就很保险了。如果要求高速采集就得换建立时间更短的开关芯片比如ADG系列。还有一个容易被忽略的点多路开关的导通电阻会随温度变化如果信号源内阻比较大导通电阻的变化会直接影响分压比。解决办法是保证信号源内阻远小于开关导通电阻或者用导通电阻更小且更稳定的开关芯片。4.4 常见问题速查表问题现象可能原因排查方法解决措施温度读数跳动大电源纹波、接地不良、参考电压不稳示波器看电源纹波检查接地方式加滤波、分开走地、用基准芯片串口丢数据波特率不准、线路干扰、缓冲区溢出逻辑分析仪抓波形检查缓冲区设置校准波特率、换屏蔽线、增大缓冲区通道间串扰切换建立时间不够、开关导通电阻大增加延时看是否改善增加延时、加电压跟随器、换开关芯片温度值偏差大换算公式不对、校准点不准用电阻箱模拟标准阻值重新校准、修正换算公式上位机界面卡顿刷新太频繁、数据处理太慢看CPU占用率降低刷新率、用队列分离循环5. 系统扩展与优化方向这套系统搭好之后扩展空间其实很大。通道数不够的话用两片CD4051级联就能到16通道再多可以用CD4067做16选1四片级联就是64通道。传感器类型也可以混用比如一部分通道接PT100测中低温一部分通道接热电偶测高温软件里针对不同通道用不同的换算公式就行。数据存储方面如果采集周期很短、数据量很大TDMS文件可能会比较大。可以加一个数据压缩功能比如相邻数据点变化小于某个阈值就不存或者用二进制格式存体积能小很多。另外Labview这边可以加一个数据库连接功能把数据直接存到数据库里方便多台设备的数据汇总和分析。远程查看也是一个很实用的扩展。Labview自带Web发布功能可以把前面板发布成网页局域网内任何一台电脑用浏览器就能看实时曲线。如果要做成手机也能看可以用Labview的HTTP客户端功能把数据推送到一个简单的Web服务上手机端用网页或者小程序展示。报警功能也值得完善。现在的报警只是界面上变个颜色可以加上声音报警、邮件报警或者短信报警。Labview这边检测到超温后调用邮件发送功能或者通过串口控制一个短信模块就能实现远程报警。我做过一个项目就是超温后自动给值班人员发邮件响应速度比人盯着屏幕快多了。最后再分享一个小技巧整个系统搭好之后建议做一个自检功能。单片机上电后先读一个已知阻值的参考电阻如果读数在合理范围内就发一个自检通过的命令给上位机否则发故障代码。这样每次开机就能知道系统是不是正常省去了很多现场排查的时间。我在一个长期无人值守的测试台上加了这个功能后来每次出问题都是自检先报出来的比等人发现要快得多。