ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

双结点控制系统实战:ADC采样与CAN通信协同设计

双结点控制系统实战:ADC采样与CAN通信协同设计 双结点控制系统说简单点就是一头负责采集、一头负责控制中间用CAN总线连起来。这样的结构在工业现场很常见传感器装在设备端控制器放在控制柜里两边距离可能隔着十几米甚至几十米模拟信号直接拉线过来既不现实也容易被干扰于是ADC采样结点把模拟量变成数字量通过CAN总线送过去控制结点收到数据后做策略运算再输出控制信号。P3这个项目就是把这两块完整走通包含ADC采样链路的处理、CAN通信链路的规划以及两个结点之间怎么配合才能形成一个稳定的控制闭环。这篇文章主要写给正在做嵌入式控制、工业数据采集或者准备把ADC采集和CAN通信组合到同一个系统里的开发者。我会把项目中真正影响成败的细节拆开讲包括采样周期怎么算、报文ID怎么规划、双结点时序怎么同步以及联调时最容易翻车的几个坑。1. 双结点控制的项目任务拆解ADC采样结点与CAN控制结点各自要承担什么1.1 这套系统要解决的现场问题我最早接到这个需求时现场的情况是这样的传感器信号分布在设备的不同位置控制器却必须集中在一个柜子里。如果每个传感器都直接拉模拟量信号线到控制器线缆成本高不说长距离传输时模拟量太容易受电机启停、变频器干扰信号到控制器那边已经没法看了。所以项目定下来的方案就是把系统拆成两个结点采集结点放在传感器附近做ADC采样把模拟量转成数字量后通过CAN总线发送控制结点放在柜子里接收CAN数据执行控制算法再通过PWM或者开关量输出驱动执行机构。两个结点中间只走一对CAN差分线抗干扰能力比模拟量长线传输强得多。这个拆分看起来简单但它带来了一个额外的挑战两个结点不是同一个芯片它们各自有独立的时钟、独立的程序运行节奏怎么保证采集端的数据能及时送到控制端控制端算出来的结果能准确作用到执行机构上这就要靠CAN通信协议的设计和双结点的时序配合来解决了。1.2 硬件拓扑与结点分工P3项目的硬件拓扑可以概括为采集结点 总线 控制结点的结构。采集结点结点A的核心器件是一颗带12位ADC的MCU前端是信号调理电路包括分压电阻、RC滤波、电压跟随器把传感器输出的0到10V电压或4到20mA电流转换成MCU ADC口可以承受的0到3.3V范围。MCU通过ADC规则通道采样使用DMA自动搬运结果然后周期性把最新的采样值打包成CAN报文发出去。控制结点结点B也是一颗同样的MCUCAN接收中断把报文存到缓冲区主循环里做控制运算输出PWM到执行机构。结点B同时会周期发送心跳报文或者控制参数给结点A形成一个双向通信的关系。这两个结点的程序是分开写的但设计时必须放在一起考虑——比如结点A的CAN发送周期要跟结点B的控制周期对齐结点B的接收缓冲区要能容忍CAN总线的抖动两边对报文ID的定义必须一致否则联调时就是灾难。1.3 为什么选中ADCCAN这个组合很多人在选型时会纠结为什么不用RS485为什么不用以太网我当时的考虑是这几点CAN总线是差分信号共模抑制能力强在电机、变频器附近工作比RS485更稳。CAN的多主仲裁特性意味着总线上挂多个采集结点时每个结点可以直接发数据不依赖主机轮询采集数据的实时性好。CAN报文有CRC校验和错误帧机制数据传错了会重发或者报错可靠性比纯UART高。在控制类场景里CAN的短帧结构最大8字节反而成了优势一帧数据量不大但非常紧凑适合高频周期通信。ADC则是采集模拟量绕不开的环节12位分辨率在大多数工业传感场景下足够用关键在于怎么把采样值采得稳、采得准这部分我在下一章详细展开。2. ADC采样链路的完整设计从采样周期计算到数据去漂移很多人以为ADC采样就是把寄存器读出来那么简单实际上采样周期配错了、前端电路没处理好、滤波算法没跟上读出来的数据根本没法用。这一章我会从采样周期、信号调理、数据滤波三个层面把ADC链路讲透。2.1 采样周期怎么配置才够用ADC采样不是一个瞬间完成的操作。STM32的ADC是逐次逼近型SAR结构内部有一个采样电容转换前需要先闭合采样开关让外部信号给采样电容充电。采样时间太短电容没充满转换出来的值就会偏小但采样时间也不是越长越好太长会限制转换频率影响采样率。以一颗主频72MHz的MCU为例ADC时钟通常配置为12MHzPCLK2 72MHz经过6分频。ADC完成一次完整转换所需的时间是转换时间 (采样周期 12.5个ADC时钟周期) / ADC时钟频率如果采样周期配置为1.5个ADC时钟总转换时间为(1.5 12.5) / 12MHz ≈ 1.17微秒如果采样周期配置为55.5个ADC时钟总转换时间为(55.5 12.5) / 12MHz ≈ 5.67微秒这里有个关键点外部输入阻抗和采样电容的匹配关系。采样时间越短对外部信号源的内阻要求越低。如果传感器经过一个大电阻分压后直接进ADC内阻很高采样时间又很短电容根本充不满采出来的值就会偏低而且这个偏低程度跟信号内阻有关不同通道偏差还不一样表现为数据很稳但就是不准。我在这个项目里把采样周期设成28.5个ADC时钟实际转换时间大约3.4微秒单个通道采样率可以做到30kSPS以上远高于控制周期10ms内含一个采样值的要求。这种余量是为了保证前端即使有一点阻抗采样也足够稳定。2.2 信号调理前端与参考电压细节ADC采集精度不只是MCU内部的事前端电路直接决定了你能采到什么样的信号。项目里传感器信号范围是0到10VMCU的ADC输入范围是0到3.3V必须做分压和调理。分压我用的是1%精度的金属膜电阻比例大致为3.3比10也就是分压比约1比3.03再并联一个100nF电容到地构成一阶低通滤波截止频率大约1.6kHz。这个滤波很关键主要作用是滤掉现场的工频干扰和高频噪声但是要注意滤波电容不能太大否则ADC采样时电容放电太慢会让信号响应变迟钝。另一个容易忽略的是参考电压。很多MCU的ADC参考电压直接接VDDA而VDDA如果跟数字电源没有做隔离MCU引脚翻转时的噪声就会耦合到参考电压上导致采样值跳动。项目里我在VDDA和VSSA之间加了磁珠和10uF100nF的双电容去耦必要时还可以外接一颗高精度基准芯片。操作层面的建议是在ADC输入前加一级运放电压跟随器可以有效降低信号源内阻让采样更稳定。如果采样的是电流信号4到20mA先在输入端并联一个250欧姆精密电阻转成1到5V电压再调理。所有模拟地的走线要单独回流不能跟数字地混在一起最后在电源入口处单点连接。2.3 数据漂移的根源与滤波方案ADC数据漂移是干这行必然遇到的问题。所谓漂移就是同一个输入电压前后两次读取的值却不一样比如在某个固定电压下采样值在上下几十个LSB之间来回跳。这种情况下单片机外围电路正常、接线正常但数据就是不稳定。漂移的来源主要有三个电源噪声、参考电压纹波、外部干扰。还有一个来源是ADC本身的热噪声尤其是高阻抗输入时。滤波是解决漂移最直接的手段。项目里我试过几种方案最终采用的是滑动平均加中值滤波的组合。滑动平均实现简单代码如下#define FILTER_LEN 8 uint16_t adc_filtered_value(uint16_t new_sample) { static uint16_t buffer[FILTER_LEN] {0}; static uint8_t index 0; static uint32_t sum 0; sum - buffer[index]; buffer[index] new_sample; sum new_sample; index (index 1) % FILTER_LEN; return (uint16_t)(sum / FILTER_LEN); }中值滤波对付突发性尖峰特别有效因为滑动平均会把一个尖峰当成有效值平均进去。我的是先取5个原始采样值排序取中值再做8次滑动平均这样既抑制了随机噪声又滤掉了尖峰。从实测来看滤波前ADC原始值峰峰值跳动大约20到30个LSB滤波后可以压到5个LSB以内换算成电压大约是5mV以内满足项目控制精度要求。2.4 规则通道、注入通道与DMA的配合STM32的ADC有两类通道规则通道和注入通道。规则通道就像常规排队一次转换多个通道时按顺序来注入通道更像插队可以在规则通道转换途中强制插入一次高优先级转换。在这个项目里我把周期采样的主信号放在规则通道上使用扫描模式加DMA连续采集多个传感器信号。DMA配置成循环模式每次转换完成自动搬运到内存数组里CPU完全不干预采样和数据处理可以并行。需要注意的坑有两个一个是DMA传输宽度必须和ADC数据寄存器对齐12位数据右对齐时每个采样值是16位DMA要配成半字Half Word模式另一个是如果开了扫描模式多通道采集DMA缓冲区长度必须大于等于通道数乘以每通道采样次数否则DMA写穿缓冲区会造成不可预知的错误。我在联调时遇到过DMA只搬运一次就不动了的情况后来发现是DMA的循环模式没有正确使能ADC转换完成信号没有持续触发DMA请求。排查方式很简单在内存里看缓冲区首地址的值有没有持续更新没有更新就从ADC和DMA两边的使能配置逐项查。3. CAN通信链路设计报文ID规划、仲裁和双结点控制时序怎么配合CAN这块如果只是把数据发出去、收回来其实难度不大。真正的难点是报文ID怎么规划才能让两个结点在总线上有序工作波特率怎么配才不会出现大量错误帧以及采集结点和控制结点之间怎么建立一个稳定的闭环时序。3.1 报文ID规划优先级就是控制权的分配CAN总线的仲裁机制基于报文IDID越小优先级越高。当两个结点同时往总线上发数据时ID小的报文会赢得仲裁继续发送ID大的那个会自动退避等到总线空闲再发。这个机制用在双结点控制系统里有一个非常实用的设计原则把实时性要求最高的报文放在ID最小段。我在项目里的ID分配这样设计的报文类型ID标准帧方向含义控制指令0x100结点B - 结点A启动、停止、参数下装采样数据0x200结点A - 结点B压力传感器采样值心跳报文0x300双向结点在线状态检测诊断报文0x400双向故障码、配置信息这样设计的一个直接好处是即使结点A正在发采样数据结点B突然需要下发一条控制指令控制指令也能立刻赢得仲裁不会因为总线被采样数据占住而错过时机。在双结点控制系统里控制指令的优先级永远是第一位的。另一个细节是CAN标准帧的ID最多11位如果系统之后要扩展到更多结点ID规划要提前留好分组区间不要写死在代码里。我习惯用宏定义把ID集中管理方便后续调整。3.2 波特率与位时序的配置计算CAN的波特率不是随便配一个数字就能稳定工作的。它由同步段、传播段、相位缓冲段1BS1、相位缓冲段2BS2组成这些段的长度决定了采样点位置采样点位置不对长距离或高波特率下就会出现大量错误帧。以CAN外设时钟36MHz为例目标波特率500kbps计算方式如下波特率 CAN时钟 / (预分频器BRP × (1 BS1 BS2))代入500kbps 36MHz / (BRP × (1 BS1 BS2))需要满足BRP × (1 BS1 BS2) 72我采用BRP4BS112BS25总的位时间量化单元为112518个4×1872波特率正好500kbps。采样点位置为采样点 (1 BS1) / (1 BS1 BS2) 13 / 18 ≈ 72.2%采样点放在72%附近是推荐的在这个点上采样能最大程度避开信号跳变沿抗干扰能力最好。BS1和BS2还有一个隐藏作用它们可以吸收总线上信号传播延迟和时钟偏差。两个结点之间的线缆越长信号传播延迟越大BS1就要适当加大。项目里两个结点之间距离大概30米500kbps下BS1设12足够。3.3 双结点控制闭环的时序设计这一节是双结点控制的核心也是跟单结点采集单结点控制最本质的区别。两个结点各自有独立的MCU和时钟如果只是结点A发、结点B收那本质上还是一个开环系统控制效果取决于通信延迟是否稳定。但CAN的发送时机受总线仲裁影响延迟是抖动的所以必须设计一个明确的时序约定。我在项目里约定了一个10ms的控制周期时间节点结点A动作结点B动作T0ADC采样完成DMA搬运等待/处理上一帧T01ms内发送采样数据帧CAN接收中断收到数据T1周期中点等待控制指令执行控制算法输出PWMT11ms内接收控制指令发送控制指令帧T2周期末状态更新状态更新这个时序的关键点是结点A的ADC采样和CAN发送必须同步在一个节奏上。最简单可靠的做法是用一个定时器中断作为统一的时基中断里触发ADC采样采样完成后置标志位主循环检测到标志位就发送CAN帧。这样可以避免采样完成得早但发送得晚造成的额外延迟。结点B那边用CAN接收中断作为隐式时基每次收到结点A的采样帧就记录时间戳控制算法基于最新一帧数据运算。如果超过一个周期10ms没收到新数据就进入数据超时保护输出保持或者进入安全状态。3.4 经典CAN与CAN FD的取舍项目初期有人建议直接用CAN FD说速度更快、数据更长。我评估后还是选了经典CAN 2.0。原因是这个双结点系统单帧数据量很小采样值加状态字也就8个字节以内经典CAN的标准帧完全够用。CAN FD优势在于数据场最多64字节、波特率可以更高但代价是总线时序要求更苛刻、终端电阻匹配要求更高在30米传输距离下经典CAN 500kbps的稳定性更让我放心。如果你的系统后来要扩展成多结点而且每个结点要上报大块数据比如波形记录那时候再考虑CAN FD不迟硬件上选用同时支持CAN 2.0和CAN FD的控制器就行。4. 双结点联调中最容易翻车的三个问题与排查过程双结点联调阶段遇到的问题往往不是单纯ADC的问题也不是单纯CAN的问题而是两者叠加后暴露出来的。我挑三个最典型、最容易让新手卡住的问题把完整排查链路写出来。4.1 DMA数据紊乱缓冲区被写穿或数据错位现象是结点A发送的采样数据在结点B端看起来时好时坏有时候压力值和温度值互相串了有时候连续几帧都是同一个值。第一反应是CAN通信的问题于是用CAN分析仪挂在总线上看发现总线上发出的数据本身就是乱的。问题定位到结点A的ADC采集侧。排查过程是这样的先关掉CAN发送在结点A本地用串口打印ADC缓冲区内容确认ADCDMA采集本身是否正确。结果发现本地数据也有错位说明问题在DMA搬运环节。检查DMA配置发现DMA的长度配置成了字节模式而ADC数据是半字16位导致每个采样值的高8位和低8位被拆开搬运数据自然全乱了。同时发现扫描模式下使能了多个通道但DMA缓冲区大小只申请了单通道的容量第二个通道的数据直接写穿了缓冲区。修复方案是DMA传输宽度改为半字数据长度改为通道数 × 每通道缓冲个数。改完后本地打印数据恢复正常CAN发送的数据也正常了。这事的教训就是DMA配置里数据宽度和外设寄存器宽度必须严格对齐多通道扫描的缓冲区长度一定要按通道数预留。4.2 采样数据正常但控制效果差采样时刻和控制周期错位第二个问题很隐蔽。单独看结点A的采样数据没问题单独看结点B的PWM输出也正常但整个系统联调时控制的动态响应总是慢半拍而且不是固定的慢是一会快一会慢。我怀疑过PID参数调整了积分系数效果不明显。后来用逻辑分析仪同时抓了两个信号结点A的CAN发送引脚和结点B的PWM输出引脚。对比发现从结点A发出采样帧到结点B更新PWM延迟时间在1ms到5ms之间波动这个波动直接导致控制效果变差。根因是结点A的ADC采样在中断里完成但CAN发送在主循环里执行主循环里还有其他任务占用了时间导致采样完成和数据发出之间多了一段不确定的等待。解决方法是把CAN发送也放到定时器中断的时基里采样完成中断触发后直接置发送请求标志定时器中断里检查到标志位就立刻调用CAN发送函数。这样从采样到报文出炉的时间抖动控制在微秒级控制结点的反馈延迟稳定了。4.3 总线错误帧频发终端电阻和采样点不匹配还有一个常见故障是总线上一会通一会不通用CAN分析仪看全是错误帧。我先量了CAN_H和CAN_L之间的静态电阻发现总线两端只有一个终端电阻另一个在布线时漏装了。CAN总线标准是两端各接一个120欧姆终端电阻用来消除信号反射。漏掉一个后短距离通信看起来还能工作但一有干扰信号反射就会造成位错误。补上终端电阻后错误帧明显减少但还没有完全消失。继续检查位时序配置发现结点B的BS1和BS2配置跟结点A不一致导致两边采样点一个在75%一个在60%信号边沿稍微抖动就会误判。统一两侧的位时序配置后错误帧彻底清零。这类问题的定位方法很固定先用万用表量终端电阻再用CAN分析仪统计错误帧类型最后逐项核对双方的位时序寄存器配置。5. 影响采样精度的PCB布局要点和实测数据项目中遇到的很多ADC数据异常追到根上其实来自PCB布局。尤其是ADC和CAN同时在板子上工作CAN收发器发送时会产生比较大的瞬态电流处理不好就会污染ADC的参考电压和采样信号。5.1 时钟抖动对ADC采样的影响ADC的转换精度依赖采样时钟的稳定性。如果采样时钟抖动过大采样电容的充电时间就会不稳定转换结果出现随机误差。在MCU内部ADC时钟通常来自PLL分频如果PLL配置不当或者电源噪声耦合到PLL的模拟供电引脚抖动就会直接体现为ADC数据的随机跳动。实测中我发现当板子上CAN总线繁忙高频发送时ADC采样值的跳动明显增大。用示波器看ADC采样保持触发信号发现在CAN发送瞬间有较大抖动。你在PCB布局时ADC的供电引脚和CAN收发器的供电引脚要尽量分开走线ADC的VREF引脚去耦电容要靠近引脚放置走线要短粗。5.2 电源噪声的处理方式电源噪声对ADC的影响主要体现在两个方面一是参考电压波动二是模拟输入信号被耦合干扰。最有效的处理方式是在电源入口做磁珠隔离。我给模拟电源单独走了一路磁珠磁珠后面接10uF钽电容和100nF陶瓷电容并联去耦。这样做的好处是数字部分的高频开关噪声被磁珠挡在模拟域之外ADC参考电压稳定了采样值的底噪也下来了。实测数据对比布局状态ADC采样值峰峰值波动备注模拟电源直接共用数字电源30 LSB明显可见漂移磁珠双电容隔离8 LSB满足控制要求磁珠隔离RC前端滤波4 LSB最佳状态5.3 采样前端RC滤波的布局位置RC低通滤波的电容一定要靠近MCU的ADC引脚放置而不是靠近信号源放置。原因是靠近ADC引脚可以最短路径滤除引脚上耦合进来的噪声。如果电容放在远端电容到ADC引脚之间的那一段走线就相当于一根天线会把噪声重新引入采样回路。另外一个细节是ADC输入走线不要跟CAN收发器的差分信号线平行走线很长距离。CAN在发送时差分线上的共模电流会通过寄生电容耦合到相邻走线如果相邻走线正好是ADC输入采样值就会出现和CAN发送节奏同步的周期性跳动。实测中把ADC输入走线和CAN走线拉开距离并加地线隔离后这种同步跳动直接消失。6. 项目收尾后的经验沉淀P3双结点控制跑通之后我最大的体会有两点。第一ADC采样和CAN通信单独拿出来都不算难但放在一起联调时所有问题都藏在时间和噪声这两个维度里。时间维度上采样、发送、接收、控制必须形成稳定的节奏噪声维度上电源、地线、走线布局任何一个环节偷懒最终都会以数据漂移或者总线错误的形式暴露出来。第二双结点系统排查问题一定要分侧隔离先确认本地数据是否正确再上总线看报文最后核对对端接收逻辑一层层缩小范围比盲目改参数高效得多。如果之后你有类似项目要做我的建议是先画一张时序图把两个结点的动作对齐再动手写代码。硬件上严格按模拟电源隔离、ADC引脚就近滤波、CAN终端电阻齐全来设计能省掉联调阶段一半的麻烦。这套方案在P3项目里最终跑到了500kbps波特率、10ms控制周期、采样值波动5mV以内的效果你按照这个思路走大概率也能稳定落地。
返回列表