ARTICLE DETAIL

资讯详情

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

SBUS协议与反相电路详解:从串口原理到飞控集成实战

SBUS协议与反相电路详解:从串口原理到飞控集成实战 玩穿越机、固定翼航模的朋友说到接收机和飞控之间的连接SBUS这三个字基本绕不开。它是一套用串口承载遥控通道数据的协议最早由Futaba推出来后来被各家接收机厂商广泛采用几乎成了航模遥控接收机的标配输出方式。很多新手第一次接SBUS接收机十个有九个会栽在同一个地方——信号反相。明明看着线接对了飞控就是识别不到摇杆或者通道跳得像抽风排查半天才发现是硬件反相电路的问题。这篇内容把SBUS协议本身、硬件反相电路、飞控集成配置和常见坑一次讲清楚不管是第一次接触SBUS的玩家还是想自己画一块带SBUS输入的小板子的开发者都可以直接照着做。1. SBUS协议基础别只看串口参数1.1 SBUS到底是怎么传数据的传统PWM接收机每个通道就需要一根信号线。一台固定翼用6个舵机就要接6根PWM线穿越机动辄8个通道以上线束会绕成一团飞控的输入引脚也不够用。SBUS的思路是接收机把所有通道的脉宽值按位打包成一串数字帧通过一根信号线连续发给飞控飞控再解包还原出每个通道的值。再加上锂电池电压、遥控器开关量、失控保护状态这些信息一根线就能传16个通道这是PPM都无法比的优势。SBUS本质上是串口UART协议波特率是100000bps8个数据位偶校验Even Parity2个停止位没有硬件流控。注意这个波特率不是常用的9600、115200而是偏门的100000调试的时候如果选错读出来的就是一团乱码。实际传输的物理电平是逻辑电平接收机通常输出3.3V或者5V信号所以F4、F7这类飞控的芯片引脚能够直接兼容只是反相问题需要特别处理。1.2 25字节一帧16个通道怎么塞进去的SBUS协议每一帧固定25个字节格式很规整字节位置内容Byte 0帧头 0x0FByte 1 ~ Byte 22通道数据共22字节Byte 23状态字节内含帧丢失、失控保护等标志位Byte 24帧尾 0x0016个通道每个通道值是11bit16个通道一共占用176bit正好等于22字节×8bit。数据按位连续打包从通道1开始低比特在前、高比特在后。实际通道值范围一般约为0~2047飞控拿到后会按照自己的逻辑映射到1000~2000甚至更多。所以在飞控配置页面能看到摇杆量程而不是直接看到PWM脉宽。解码的时候如果把22字节数据看成一个整数用小端模式拼接然后每11bit切一段就能得到16个通道的值。这个做法我在后面调试部分会给出一个能直接跑的Python函数。帧头0x0F和帧尾0x00是锁定帧边界的关键。不过要注意状态字节里面如果出现0x00也容易让人误判帧尾所以固定长度扫描比单纯找帧尾更可靠找到0x0F后直接往后取25字节再检查最后一个字节是不是0x00。1.3 为什么会有“反相”这种反人类设计这是SBUS新手最不理解的地方。普通UART空闲时是高电平起始位是低电平停止位是高电平。而SBUS恰恰相反空闲时为低电平起始位是高电平停止位是低电平。也就是说SBUS信号是标准UART信号的反向。有人会问好好一个串口为什么非要反着来SBUS是从Futaba的遥控系统里出来的当初设计时可能考虑到与某些射频前端或光耦隔离电路配合更方便具体原因没有官方文档说得很清楚但结果就是你用普通UART直接收会一直收到break错误、帧错误飞控根本解析不出来。解决方式要么是接收机输出非反相信号部分固件支持要么在外部加一个反相器这正是接下来要讲的重点。2. 硬件反相电路设计选型、计算与实战2.1 先判断你的飞控到底需不需要反相器加不加外部反相器先看飞控。很多成品飞控上会留一个专门标注“SBUS”的焊盘比如接在某个UART的RX脚旁边板子上已经集成了反相电路有些飞控则只给了普通UART接口如果你把SBUS反相信号直接接到普通RX上大概率通道完全不进。怎么判断最直接的方法看飞控原理图或者产品说明。要是没有资料就自己测把接收机单独供电用万用表测量SBUS输出引脚对地电压。接收机没收到遥控信号时如果测到接近0V说明这是反相SBUS如果测到接近3.3V或5V说明输出是非反相信号。还有一种土办法把SBUS信号直接连到USB转TTL模块的RX用串口助手设好100000波特率、8E2如果出来的全是乱码或根本无输出大概率就是反相问题。大多数接收机默认输出反相SBUS所以“直接接普通UART就能用”反而是例外。保险起见我施工时都会先测静态电平再决定要不要加反相器而不是一上来就焊。2.2 三极管反相电路一个能直接抄的电路我推荐最常用的NPN三极管方案元件到处都能买到成本几毛钱。电路非常经典接收机SBUS ──┬── R1(10kΩ) ──┬── Q1(NPN) 基极 │ │ R3(100kΩ) Q1 发射极 ── GND │下拉 GND Q1 集电极 ──┬── 飞控UART RX └── R2(4.7kΩ) ── 3.3V电源原理一句话输入为低电平时Q1截止集电极通过R2被拉到3.3V所以输出高电平输入为高电平时Q1饱和导通集电极被拉到接近0V所以输出低电平。输入输出刚好反相同时把电平钳在3.3V对飞控MCU安全。元件参数不是随便选的。设接收机SBUS高电平为3.3VQ1选择2N3904集电极电流Ic主要由R2决定R24.7kΩ时Ic≈3.3V/4.7kΩ≈0.7mA。要让三极管深度饱和基极电流Ib至少取Ic/10约0.07mA。基极电阻R1如果取10kΩ基极电流约为(3.3V-0.7V)/10kΩ0.26mA余量足够。R3的下拉电阻要尽量大取100kΩ避免和R1分压把基极电压拖低如果换成1kΩ输入高电平时基极可能连0.7V都达不到三极管根本不开这也是很多自制反相器失败的常见原因。为什么R2取4.7kΩ而不是100Ω集电极上拉电阻太小静态电流会很大三极管导通时功耗也会增加上拉电阻取太大输出上升沿被RC时间常数拖慢100kbps波特率下容易出误码。4.7kΩ到10kΩ是我实测比较稳的范围。2.3 用MOS管反相和逻辑门反相的区别除了NPN三极管还可以用增强型NMOS管比如2N7000。电路类似源极接地漏极输出外部上拉R2到3.3V栅极接输入栅极对地接一个100kΩ到1MΩ的下拉电阻。输入低电平时Vgs0MOS截止输出高输入高电平时Vgs大于阈值MOS导通输出低。2N7000的导通电阻很低输出低电平很接近0V波形比三极管更干净。不过使用MOS管要注意栅极阈值电压。2N7000的Vgs(th)一般在1V到2V之间3.3V逻辑没问题如果接收机输出高电平只有2.8V这种低电压建议选逻辑电平MOS管否则可能无法完全导通。更省心的方案是逻辑门反相器比如74HC04、74LVC1G04这类芯片。把输入接到其中一个反相器输入输出接到飞控RX芯片电源接3.3V。逻辑门的优势是输出波形上升下降沿很陡几乎无失真抗干扰也强缺点是比单管多焊一个芯片还要加0.1μF电源去耦电容。如果你只是给一块飞控改SBUS三极管方案就够了如果要在强干扰环境下做信号整形逻辑门更稳。2.4 焊接和布线阶段的三个建议第一反相器要尽量靠近飞控RX焊盘焊接输出线越短越好。SBUS波特率100k不算高但飞行环境里电调和电机是强干扰源输入线如果和电源线平行长距离走线可能把噪声耦合进来。第二接收机、反相器、飞控三者必须共地地线尽量粗不要靠信号线自己回流。第三如果接收机输出的是5V信号输入侧经过R1限流进入三极管基极只要R1不是太小不会烧管子输出侧因为上拉接3.3V飞控RX不会承受5V比较安全。焊接完成后先别急着装桨上电用万用表量一下反相器输出端静态电压。正常的SBUS信号在空闲时输入是低电平所以反相器输出应为约3.3V高电平。如果输出是0V说明电路没工作可能是管子脚位焊错也可能R3取值太小把输入高电平拉没了。3. 飞控集成实操接线、配置与验证3.1 从接收机到飞控的完整接线流程在动手之前先把链路理清接收机输出SBUS信号反相器负责把反相信号变成普通UART信号飞控的UART RX接收固件解析出通道。整个链路里每个环节都必须对。以穿越机最常见的F4飞控为例接线步骤如下接收机的电源线接飞控5V和GND或者用独立BEC供电但GND一定要和飞控共地。接收机SBUS输出接反相器输入。注意有些接收机有S.BUS和S.PORT两个口S.PORT是传感器总线不要接错。反相器输出接飞控目标UART的RX焊盘比如UART1 RX、UART2 RX。具体哪个看飞控手册接错串口后面配置就乱了。上电后用万用表测反相器输出的静态电平应当约为3.3V同时测一下接收机供电是否正常。再把飞控连接地面站进入端口配置页面。这个过程看似简单但我见过不少人把RX和TX焊反或者把SBUS信号接到了S.PORT焊盘上结果怎么配都没有反应。所以强烈建议第一步先看飞控丝印再拿万用表蜂鸣档对着原理图找焊盘。3.2 Betaflight / INAV 里的固件配置硬件接好后需要在飞控固件里打开对应串口并选择SBUS协议。以Betaflight为例打开Betaflight Configurator连接飞控后进入“端口Ports”页面找到你接的那个UART。在对应的“Serial RX”列打勾确保状态变成“Enabled”。有些默认固件里这个端口已经被其他功能占用比如GPS或遥测需要先关掉。接着进入“配置Configuration”页面接收器Receiver Mode选择“Serial (via UART)”接收器协议Receiver Provider选择“SBUS”。保存并重启飞控。INAV的流程类似也是在端口页面把对应UART设为串行RX然后在配置页面选择SBUS。如果找不到某个选项先检查固件版本和刷写时的目标板别把F4的固件刷到F7上去。完成配置后在Betaflight的“接收器Receiver”页面或者遥控器打杆的同时观察对应通道的进度条。正常情况通道值应该在1000~2000之间波动中位接近1500。如果通道有反应但数值不在正常范围检查遥控器端通道映射和端点的设置。3.3 关于serialrx_inverted这类隐藏参数的说明在Betaflight的CLI命令行里有一些和串行接收机有关的参数比如get serialrx_provider get serialrx_invertedserialrx_provider用来查看当前选择的协议正常会显示SBUS。serialrx_inverted这个参数各个版本含义略有不同如果你的信号链路里已经通过外置反相器或飞控板载反相器把SBUS转成了普通UART通常保持OFF如果某个飞控板把反相逻辑又反转了一次或者你接了非反相SBUS信号进MCU导致最终到芯片的是反相UART可能需要把这个参数设为ON才能正常解析。我的建议是不要乱改这个参数。先确认硬件链路里反相次数SBUS接收机出来是反相经过外置反相器后变正常这算一次飞控板载反相器再反一次MCU看到的又变回反相那么该飞控设计时就应该有对应处理。你只需要按照飞控官方接线图接除非你确认信号极性不对才用CLI参数去“软件反相”救命。3.4 ArduPilot或其他开源固件的参考ArduPilot通常不是用Betaflight那种“串口协议”的思路来配SBUS。很多飞控板有专门的RCIN接口SBUS接收机可以直接插RCIN排针固件自动检测协议当然也包括SBUS。如果是通过普通串口接入一般需要在Mission Planner的完整参数列表里找到对应的SERIALx_PROTOCOL把它设为23即RCIN同时确认SERIALx_OPTIONS里有没有需要打开的反相选项。不同版本的ArduPilot对SBUS的支持有一些差异而且飞控硬件五花八门我不建议完全照抄别人的参数。最可靠的方法是去查对应飞控板和ArduPilot官方wiki确认RCIN或串口输入的具体引脚和默认协议。飞控集成这种东西最怕的就是“我朋友说这样配能用”结果板子根本不是同一个型号。4. 调试、故障排查与一些独家避坑经验4.1 常见问题速查表症状可能原因排查步骤完全没通道数据接收机灯正常信号极性不对、串口选错、RX/TX接反万用表测反相器输出静态电平确认接到飞控RX脚重新检查端口配置通道值跳变、偶尔抽风共地不良、供电不足、虚焊加粗地线检查接收机供电电压重新补焊信号线地面站显示RXLOSS接收机没有输出SBUS、接线断路、协议没选SBUS用示波器/逻辑分析仪看SBUS引脚有无帧波形检查配置页面通道值只有一半或无中位遥控器通道映射错误、EndPoint设置不对在遥控器上校准行程地面站里确认通道映射表接上SBUS后其他串口设备异常占用同一个UART或者信号误接换一个空闲UART重新配置端口上电后反相器发烫上拉电阻太小、三极管引脚接错检查R2阻值用万用表确认集电极、发射极、基极是否和电路图一致这些都是我实际见过的问题。尤其是共地不良在通电后电机转动时特别明显通道值会跟着油门抖很多人还以为是接收机坏了。4.2 现场排除过的一个反相器故障有一次给一架固定翼改SBUS用的是2N3904三极管反相电路焊好以后万用表测输入静态低电平0V输出却只有0.4V怎么看都不对。最后发现是集电极和发射极焊反了三极管EBC脚位没对上输入信号从集电极进去输出从发射极出来管子根本没有工作在正确状态。换过来以后输出恢复到3.3V重上电立刻有通道值。后来我养成一个习惯焊完三极管先用万用表二极管档量一遍确认B/E/C三脚和焊盘的对应关系再上电。尤其是从元件盒里翻出来的散装三极管丝印经常模糊脚位不一定都是同一种排列。这类小元件问题排查起来最浪费时间而且新手很容易忽略。还有一个案例是接收机输出SBUS信号在电脑USB转TTL上能看到正常帧但接上飞控后就是没反应。查了半天发现反相器输出和飞控RX之间隔了一根20cm的杜邦线杜邦线内部折断万用表量静态电压有3.3V但信号一到高频就丢包。把杜邦线换成直接焊接的短跳线后解决。从这里得到的教训是信号线上的任何劣质连接都对100kbps传输有影响。4.3 用逻辑分析仪定位SBUS信号异常如果没有飞控日志或者日志里看太抽象逻辑分析仪是排查SBUS问题最好的工具。我习惯把逻辑分析仪的地接GND一个通道接到反相器输出端也就是飞控RX这一侧采样率至少设到2MHz。在PulseView这类软件里可以加一个UART协议解码器波特率设100000数据位8校验Even停止位2然后重点看解码器设置里有没有“反相信号Invert Signal”选项。因为SBUS的原始输出是反相的如果逻辑分析仪直接夹在接收机SBUS输出端必须勾选反相如果夹在反相器输出端就可以当成普通UART来解。正常情况下你能看到一帧接一帧的25字节数据帧头是0x0F尾部有0x00。如果解码出来全是0x00或0xFF这种规律数据八成是极性搞反了如果帧头能找到但后面数据乱跳检查停止位、校验位和波特率是否严格按照8E2、100000。定位问题之后再往回查接收机输出、反相器、飞控RX很快就能锁定故障点。4.4 一个能直接用的Python通道解析函数调试时如果手头没有飞控也可以把SBUS信号接到USB转TTL模块配一个反相电路在电脑上直接读串口。但注意USB转TTL的RX输入也需要反相别把接收机SBUS直接怼进去。下面这段Python代码输入一个25字节完整帧输出16个通道值适合放在日志分析脚本里def parse_sbus_frame(frame): if len(frame) ! 25: return None if frame[0] ! 0x0F: return None payload int.from_bytes(frame[1:23], little) channels [] for i in range(16): value (payload (i * 11)) 0x7FF channels.append(value) flags frame[23] footer frame[24] return { channels: channels, ch1: channels[0], frame_lost: bool(flags 0x04), failsafe: bool(flags 0x08), footer_ok: footer 0x00, } # 用法示例从一段原始字节流中按0x0F固定长度取帧 def extract_frames(raw_bytes): frames [] i 0 while i len(raw_bytes) - 24: if raw_bytes[i] 0x0F: candidate raw_bytes[i:i 25] if candidate[24] 0x00: frames.append(candidate) i 25 continue i 1 return frames两个关键点一是用int.from_bytes把22字节按小端模式拼成一个整数比一个字节一个字节移位更简单二是帧头0x0F可能出现在数据区所以一定要检查第25字节是否为0x00。这段代码不能替代示波器但用来批量回放日志、验证解包算法非常方便。最后再分享一个实用习惯我焊反相器焊了无数次最后养成一个习惯直接用一小块万用板做一个“SBUS反相转接小板”输入焊三根线输出焊三根线中间放一个SOT-23封装的NPN三极管和两个电阻用热缩管包起来尺寸不到指甲盖大。以后不管是改飞控、接地面站、还是给DIY设备做遥控输入拿出来就能用不用每次重新焊。反相电路本身不难难的是理解SBUS协议为什么要这样设计以及在不同飞控、不同固件里怎么正确配置。希望这篇内容能帮你少走点弯路。真到了现场记住一句话先测静态电平再看地盘站配置最后才怀疑元件。按这个顺序排查大部分SBUS问题都能在十分钟内解决。
返回列表