跳到主要内容SBUS 协议详解:从原理到 STM32 实战 | 极客日志C算法
SBUS 协议详解:从原理到 STM32 实战
SBUS 协议是无人机与航模领域主流的串行控制通信方案,相比传统 PWM 具有单线传输、抗干扰强、延迟低等优势。详细解析了 SBUS 基于反向电平 UART 的工作原理,涵盖物理层连接、电平转换方案(如 74HC14 反相器)、100kbps 波特率配置及 25 字节帧结构拆解。重点讲解了 16 通道 11bit 数据的位运算解析方法,并提供 STM32 HAL 库的中断与 DMA 接收实现代码,帮助开发者快速完成硬件对接与软件解析。
数字游民1 浏览 在无人机、航模和机器人等精密控制领域,"稳定、快速、可靠"是控制信号传输的核心诉求。传统的 PWM 信号虽然简单直观,但存在通道数有限、抗干扰能力弱、布线复杂等痛点。而 SBUS(Serial Bus)协议——由 FUTABA 公司专为遥控设备设计的串行数字通信协议,凭借单线传输多通道数据、抗干扰强、延迟低的核心优势,逐渐成为行业主流。
我们将从原理、硬件实现到代码解析,层层拆解 SBUS 协议。无论你是刚入门的电子爱好者,还是需要落地项目的工程师,都能从中找到所需的实用信息。
一、SBUS 协议基础认知:核心定位与优势对比
在深入技术细节前,我们先通过对比和基础定义,快速建立对 SBUS 的认知。很多人会把 SBUS 和常见的 UART、PWM 等混淆,这里先明确其核心定位:SBUS 是基于反向电平 UART 的'应用层控制协议',专门用于遥控器与接收机、接收机与飞控/执行器之间的控制信号传输。
1.1 为什么需要 SBUS?传统方案的痛点
在 SBUS 出现之前,航模和早期无人机主要使用 PWM 或 PPM 协议传输控制信号。我们通过表格直观对比其局限性:
| 传输方案 | 通道数限制 | 布线复杂度 | 抗干扰能力 | 延迟表现 | 适用场景 |
|---|
| PWM(脉冲宽度调制) | 每个通道需 1 根信号线,常见 4-6 通道,多通道需大量布线 | 极高:N 个通道需 N+1 根线(含 GND),布线杂乱,易拉扯损坏 | 弱:模拟信号易受电磁干扰,导致信号漂移、控制失灵 | 中等:单通道延迟约 10ms,多通道同步性差 | 入门级航模、简单机器人,对通道数和稳定性要求低的场景 |
| PPM(脉冲位置调制) | 单线可传多通道(常见 8 通道以内),通道数仍有限制 | 低:单线传输多通道,布线简洁 | 中等:仍为模拟信号,抗干扰能力优于 PWM,但不如数字协议 | 中等:帧周期约 20ms,延迟略低于 PWM | 中端航模,对布线有要求但对通道数和抗干扰要求不极致的场景 |
| SBUS(串行数字协议) | 单线可传 16 通道(标准),SBUS 2.0 支持更多通道 + 双向传输 | 极低:仅需 1 根信号线 +GND,布线极简,适合小型设备内部集成 | 强:数字信号传输,带校验机制,抗电磁干扰能力大幅提升 | 低:标准帧周期 10ms(100Hz),高速模式 4ms(250Hz),延迟远低于 PWM/PPM | 无人机、专业航模、工业机器人、无人车等对稳定性和低延迟要求高的场景 |
1.2 SBUS 的核心优势
通过上述对比,SBUS 的核心优势已清晰,结合补充信息整理如下:
| 核心优势 | 具体说明 | 带来的价值 |
|---|
| 单线多通道传输 | 标准 SBUS 单线可传输 16 个控制通道数据,SBUS 2.0 支持更多通道 | 大幅简化布线,减少设备内部线路占用空间,降低线路拉扯损坏的风险 |
| 抗干扰能力强 | 采用数字信号传输,帧结构带校验位,且为反向电平逻辑(减少环境干扰影响) | 在无人机高空飞行、工业机器人复杂电磁环境等场景下,保证控制信号稳定不丢失 |
| 延迟低 | 标准模式帧刷新率 100Hz(10ms/帧),高速模式 250Hz(4ms/帧),远高于 PWM/PPM | 实现精准实时控制,比如无人机的姿态调整、航模的特技动作、机器人的快速响应 |
| 协议简洁易实现 | 基于 UART 协议扩展,帧结构固定(25 字节),解析逻辑简单,主流 MCU 均可支持 | 降低开发者门槛,无需复杂的协议栈,快速集成到项目中 |
| 支持故障检测 | 帧结构含标志位,可检测信号丢失、FailSafe 状态等故障 | 提升系统可靠性,故障时可触发预设保护动作(如无人机自动返航、机器人急停) |
| 宽电压兼容 | 支持 3.5V~8.4V 输入电压,适配不同设备的供电需求 | 减少额外电源转换模块的使用,简化硬件设计,提升供电兼容性 |
| 高兼容性 | 广泛兼容 Betaflight、APM、PX4 等主流飞控系统,以及各类开源控制平台 | 降低设备选型成本,适配多场景开发需求,无需担心系统兼容问题 |
1.3 典型应用场景
SBUS 协议凭借其核心优势,广泛应用于各类需要精准控制的场景:
- 无人机:消费级 DIY 穿越机、工业级测绘无人机的飞控与遥控器通信
- 航模:固定翼、直升机、多旋翼等专业航模的遥控系统,尤其适合大型航模与滑翔机(简化多舵机布线)
- 机器人:工业机械臂、服务机器人、AGV 小车的运动控制模块通信
- 智能设备开发:通过 Arduino、ESP32 等开源平台实现自定义控制(如遥控车船、智能云台)
- 其他:特种作业设备(如遥控巡检机器人)、教学实验平台等需要精准实时控制的电子设备
二、SBUS 核心工作原理:反向电平的 UART 协议详解
SBUS 的本质是'反向电平的 UART 串行协议'——这句话是理解 SBUS 工作原理的核心。简单来说,SBUS 并没有脱离 UART 的基本框架,只是在电平逻辑、波特率等参数上做了定制化调整,以适应控制信号传输的需求。
下面从物理层、电平逻辑、波特率、帧周期、工作流程五个核心维度,拆解 SBUS 的工作原理,并用表格对比标准 UART,帮助理解差异。
2.1 物理层与电平逻辑:硬件第一门槛
2.1.1 物理层参数
SBUS 的物理层非常简单,仅需要 2 根线即可完成通信:1 根信号线(用于传输串行数据)+1 根 GND(地线,保证电平参考一致)。
| 物理层参数 | 具体规格 | 设计目的 | 与标准 UART 的差异 |
|---|
| 传输线数量 | 1 根信号线 + 1 根 GND(共 2 根) | 极简布线,降低硬件成本和线路复杂度 | 标准 UART 通常为 TX/RX 双线(全双工),SBUS 为单线(半双工,仅接收或发送,控制场景多为单向传输) |
| 供电电平 | 3.3V 电平(部分设备兼容 5V,但主流为 3.3V) | 适配主流 MCU(如 STM32、ESP32)的 3.3V IO 口,减少电平转换成本 | 标准 UART 可支持 3.3V 或 5V,无强制要求 |
| 传输距离 | 常规场景下可达 10 米以内,优质线材可延长至 20 米 | 满足大多数控制设备的内部或短距离通信需求(如无人机内部飞控与接收机的距离通常在 0.5 米内) | 标准 UART 传输距离类似,若需长距离需加差分电路(如 RS485),SBUS 不直接支持长距离 |
2.1.2 反向电平逻辑(核心难点)
这是 SBUS 与标准 UART 最核心的差异之一,也是很多开发者初次接触 SBUS 时最容易踩坑的地方——SBUS 采用'反向电平逻辑',与标准 UART 完全相反。
| 逻辑状态 | SBUS 电平(反向逻辑) | 标准 UART 电平(正向逻辑) | 注意事项 |
|---|
| 逻辑'1'(高电平) | 低电平(约 0V) | 高电平(3.3V/5V) | 若直接将 SBUS 信号接入标准 UART 接口,会导致无法正确解析数据,必须添加电平反向电路 |
| 逻辑'0'(低电平) | 高电平(约 3.3V) | 低电平(约 0V) | |
重点提醒:SBUS 的反向电平逻辑是'硬件适配的第一道门槛'。如果跳过电平反向步骤,即使 UART 参数配置正确,也无法解析出正确的 SBUS 数据,只会得到一堆乱码。
2.1.3 常用电平转换方案
实现 SBUS 反向电平到标准 UART 电平的转换,主流有三种方案,适配不同场景需求:
方案 1:SN74LVC1G240 总线缓冲器(推荐小型设备)
SN74LVC1G240 是一款单路总线缓冲器/线路驱动器,具备电平转换和信号缓冲功能,适合 3.3V 系统。其核心优势是静态电流小、工作电压范围宽(1.65V~5.5V),封装小巧(如 SOT-23),非常适合无人机、航模等小型设备。
| SN74LVC1G240 引脚 | 连接对象 | 作用说明 |
|---|
| A(输入端) | SBUS 接收机信号输出端 | 接收反向电平的 SBUS 原始信号 |
| Y(输出端) | MCU 的 UART 接收引脚(如 STM32 的 USART2_RX) | 输出转换后的标准 UART 电平信号 |
| G(使能端,低有效) | MCU 的 GPIO 引脚(如 STM32 的 PA0)或直接接 GND | 控制芯片是否启用 |
| VCC | 3.3V 电源 | 为芯片提供工作电压,需与 MCU 电平匹配 |
| GND | 电源地 | 保证电平参考一致,需与接收机、MCU 共地 |
#define SN74LVC1G240_EN_GPIO_PORT GPIOA
#define SN74LVC1G240_EN_GPIO_PIN GPIO_PIN_0
#define SN74LVC1G240_EN_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
void SN74LVC1G240_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
SN74LVC1G240_EN_CLK_ENABLE();
GPIO_InitStruct.Pin = SN74LVC1G240_EN_GPIO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(SN74LVC1G240_EN_GPIO_PORT, &GPIO_InitStruct);
HAL_GPIO_WritePin(SN74LVC1G240_EN_GPIO_PORT, SN74LVC1G240_EN_GPIO_PIN, GPIO_PIN_RESET);
}
void SN74LVC1G240_Enable(void)
{
HAL_GPIO_WritePin(SN74LVC1G240_EN_GPIO_PORT, SN74LVC1G240_EN_GPIO_PIN, GPIO_PIN_RESET);
}
void SN74LVC1G240_Disable(void)
{
HAL_GPIO_WritePin(SN74LVC1G240_EN_GPIO_PORT, SN74LVC1G240_EN_GPIO_PIN, GPIO_PIN_SET);
}
方案 2:74HC14 反相器(低成本通用)
74HC14 是六路施密特触发反相器,具备信号整形和反向功能,成本低、易采购,适合原型开发或批量生产场景。使用时仅需其中一路反相器即可完成电平转换。
| 74HC14 引脚 | 连接对象 | 作用说明 |
|---|
| 1A(反相输入端) | SBUS 接收机信号输出端 | 接收反向电平的 SBUS 原始信号 |
| 1Y(反相输出端) | MCU 的 UART 接收引脚 | 输出转换后的标准 UART 电平信号(完成两次反向,还原为正向逻辑) |
| VCC | 3.3V/5V 电源(与 MCU 电平匹配) | 为芯片提供工作电压 |
| GND | 电源地 | 与接收机、MCU 共地,保证电平稳定 |
优势与注意事项:
施密特触发功能可过滤信号噪声,适合电磁环境复杂的场景;六路设计可预留多路备用。注意事项:需确保输入信号幅度满足芯片阈值要求(3.3V 系统下高电平≥2V,低电平≤0.8V)。
#define SBUS_RX_GPIO_PORT GPIOB
#define SBUS_RX_GPIO_PIN GPIO_PIN_7
#define SBUS_RX_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
void SBUS_RX_Pin_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
SBUS_RX_CLK_ENABLE();
GPIO_InitStruct.Pin = SBUS_RX_GPIO_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(SBUS_RX_GPIO_PORT, &GPIO_InitStruct);
}
方案 3:三极管反相电路(极简低成本)
若临时开发或成本敏感,可采用 NPN 三极管搭建极简反相电路,仅需三极管、两个电阻即可实现。
- SBUS 信号通过 1kΩ 电阻连接到 NPN 三极管(如 S9014)的基极;
- 三极管发射极接地;
- 集电极通过 10kΩ 上拉电阻连接到 3.3V 电源,同时集电极作为输出端连接到 MCU 的 UART 接收引脚。
优势与注意事项:
元件极少、成本极低,适合临时验证。注意事项:信号整形效果较差,抗干扰能力弱,不适合批量生产或复杂电磁环境;需合理选择电阻阻值,确保三极管工作在开关状态。
特殊说明:集成飞控内置转换电路
在集成度高的飞控(如 Pixhawk、Betaflight 飞控)中,SBUS 接收端口已内置电平反转电路,可直接将 SBUS 接收机的信号输出端连接到飞控的'SBUS'标注定制口,无需额外添加电平转换电路。
2.2 波特率与帧周期:参数必须精准匹配
2.2.1 波特率:固定 100kbps
波特率是串口通信的核心参数之一,SBUS 采用'非标准波特率'——100kbps(100000 bit/s),且数据格式固定为 8 位数据位、偶校验、2 位停止位(8E2),这是正确配置串口的基础。
| 参数 | SBUS 规格 | 常见误区 | 影响 |
|---|
| 波特率 | 固定 100000 bit/s(100kbps),无其他可选值 | 将 SBUS 按 115200(标准常用波特率)配置 UART,导致数据解析错误 | 波特率不匹配会直接导致通信失败,无法解析出有效帧数据 |
| 数据格式 | 8 位数据位、偶校验(Even Parity)、2 位停止位(8E2) | 忽略校验位或停止位配置,导致帧同步失败 | 数据格式错误会出现帧丢失、数据错乱,影响控制稳定性 |
| 比特率误差容忍度 | ≤1%(优质 MCU 的晶振可满足,部分廉价 MCU 可能因晶振精度不足导致误差超标) | 使用精度低的外置晶振,导致波特率误差过大 | 误差过大会出现帧丢失、数据错乱等问题,影响控制稳定性 |
UART_HandleTypeDef huart1;
void SBUS_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 100000;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_2;
huart1.Init.Parity = UART_PARITY_EVEN;
huart1.Init.Mode = UART_MODE_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
HAL_UART_Receive_IT(&huart1, (uint8_t*)&sbus_rx_buf, 1);
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
static uint8_t sbus_frame_buf[25];
static uint8_t frame_index = 0;
if (sbus_rx_buf == 0x0F)
{
frame_index = 0;
}
sbus_frame_buf[frame_index++] = sbus_rx_buf;
if (frame_index >= 25)
{
frame_index = 0;
SBUS_Frame_Parse(sbus_frame_buf);
}
HAL_UART_Receive_IT(&huart1, (uint8_t*)&sbus_rx_buf, 1);
}
}
uint8_t sbus_dma_buf[50];
void SBUS_UART_DMA_Init(void)
{
SBUS_UART_Init();
__HAL_RCC_DMA2_CLK_ENABLE();
hdma_usart1_rx.Instance = DMA2_Stream2;
hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(&huart1, hdmarx, hdma_usart1_rx);
HAL_UART_Receive_DMA(&huart1, sbus_dma_buf, sizeof(sbus_dma_buf));
}
2.2.2 帧周期:多模式适配不同实时性需求
SBUS 以'帧'为单位传输数据,每帧包含完整的 16 通道控制信息。帧周期(两帧数据之间的时间间隔)决定了控制信号的刷新率,直接影响控制延迟,支持三种传输模式:
| 传输模式 | 帧周期 | 刷新率 | 延迟表现 | 适用场景 |
|---|
| 标准模式(默认) | 10ms | 100Hz | 单帧延迟≤10ms,满足绝大多数控制场景需求 | 普通无人机、航模、机器人等常规控制场景 |
| 高速模式 | 4ms | 250Hz | 单帧延迟≤4ms,实时性大幅提升 | 穿越机、竞速航模等对实时性要求极高的场景(需接收机和遥控器均支持) |
| 低速模式 | 14ms | 71.4Hz | 延迟较高,但功耗更低 | 低功耗设备、长距离遥控等对功耗敏感的场景(较少见) |
补充说明:帧周期是'从接收机发送一帧数据到下一次发送的时间间隔',而单帧数据的传输时间极短(25 字节×8bit=200bit,按 100kbps 波特率计算,传输时间=200bit/100000bit/s=2ms),因此控制延迟主要由帧周期决定,而非单帧传输时间。
2.3 完整工作流程:从遥控器到执行器的信号流转
SBUS 的工作流程可分为'信号采集 - 编码 - 传输 - 解码 - 执行'五个步骤,全程实现数字信号的闭环流转,具体如下:
- 信号采集:遥控器通过摇杆、拨杆等操作部件,采集用户的控制指令(如油门、方向、姿态调整等),将这些操作转换为模拟电信号(电压变化)。
- 模拟转数字 + 编码:遥控器内部的 MCU 将模拟电信号转换为数字信号,然后按照 SBUS 协议的帧结构,将 16 个通道的数字控制信号编码为 25 字节的 SBUS 数据帧。
- 无线传输:遥控器通过 2.4GHz 无线通信模块(常见 FHSS 跳频技术,抗干扰更强),将编码后的 SBUS 数据帧发送给接收机。
- 接收 + 解码:接收机通过 2.4GHz 模块接收无线信号,解调后得到 SBUS 数据帧,再按照 SBUS 协议解析出 16 个通道的控制值(原始范围 0~2047)。
- 信号输出 + 执行:接收机通过 SBUS 单线将解析后的控制信号传输给飞控/执行器(如舵机、电机驱动器),飞控/执行器将控制值映射到自身所需的范围(如 1000~2000),驱动执行部件完成相应动作。
简化流程图:用户操作 → 遥控器(采集 + 编码) → 2.4GHz 无线传输 → 接收机(接收 + 解调) → SBUS 单线传输 → 飞控/执行器(解码 + 映射 + 执行)
三、SBUS 通讯协议深度解析:25 字节帧结构拆解
SBUS 协议的核心是'固定 25 字节的帧结构'——每帧数据的长度、字段定义、字节顺序都是固定的,这也是其解析逻辑简单的关键原因。掌握帧结构,就掌握了 SBUS 协议的核心,下面逐一字段拆解,结合表格和实例让你彻底搞懂。
3.1 帧结构总览:25 字节的固定组成
标准 SBUS 帧(1.0 版本)的总长度为 25 字节,字段从前往后依次为:起始字节、通道数据(22 字节)、标志位、结束字节。各字段的字节数、固定值、功能如下表所示:
| 字段名称 | 字节数 | 固定值/格式 | 核心功能 | 备注 |
|---|
| 起始字节(Start Byte) | 1 | 0x0F(十六进制) | 标志一帧数据的开始,用于帧同步 | 所有合法 SBUS 帧的第一个字节必须是 0x0F,是判断帧开始的唯一标识 |
| 通道数据(Channel Data) | 22 | 16×11bit 数据(共 176bit) | 存储 16 个控制通道的原始值,每个通道用 11bit 表示 | 22 字节=176bit,正好容纳 16 个 11bit 通道数据,是帧结构的核心字段 |
| 标志位(Flags Byte) | 1 | 8bit 标志位(每 bit 对应一个状态) | 故障检测、帧状态指示(如 FailSafe、帧丢失) | 不同 bit 的含义有明确规定,是实现故障保护的关键 |
| 结束字节(End Byte) | 1 | 0x00 或 0x7E(十六进制) | 标志一帧数据的结束,用于确认帧完整性 | 多数设备使用 0x00,部分设备支持 0x7E,解析时需兼容两种情况 |
关键计算:16 个通道×11bit/通道=176bit;176bit÷8bit/字节=22 字节。这就是通道数据字段长度为 22 字节的原因——精准匹配 16 个 11bit 通道数据的存储需求,无冗余也无缺失。
3.2 各字段详细解析(重点!)
下面对每个字段进行详细拆解,尤其是通道数据和标志位,这两个字段是解析 SBUS 数据的核心。
3.2.1 起始字节:0x0F——帧同步的'敲门砖'
起始字节的唯一作用是'帧同步'——告诉解析端(如飞控 MCU)'从这个字节开始,后面是完整的 SBUS 帧数据'。
解析逻辑:MCU 在接收 SBUS 数据时,会持续监测接收字节,当检测到某个字节为 0x0F 时,就认为后续 24 个字节(共 25 字节)是一帧完整的 SBUS 数据,开始后续的解析流程。
注意:如果在监测过程中,连续多个字节都不是 0x0F,说明当前没有有效帧,解析端会持续等待,直到检测到 0x0F 为止。
3.2.2 通道数据:22 字节承载 16 个 11bit 通道值(核心难点)
这是 SBUS 帧结构中最复杂的部分——16 个通道的控制值被'紧密打包'在 22 字节中,每个通道占用 11bit,没有字节对齐,需要按位解析。
- 每个通道的原始值范围:0~2047(11bit 无符号整数,2^11=2048,因此范围是 0 到 2047),这一范围已被开源 Rust 解析库(sbus-rs)等多个实践来源证实。
- 实际应用中,遥控器发送的原始通道值通常在 200
1800 之间(预留了上下限冗余,避免因信号漂移导致超出范围),而飞控(如 PX4、Betaflight)常用的控制范围是 10002000,因此解析后需要进行线性缩放。
22 字节共 176bit,按从低字节到高字节、从低位到高位的顺序,依次存储 16 个通道的 11bit 数据。具体排列如下(以字节编号 B1~B22 表示通道数据字段的 22 个字节,bit0 表示最低位,bit7 表示最高位):
| 通道编号 | 占用的比特位(字节 B1~B22 的 bit 位) | 解析逻辑(以 STM32 为例,C 语言) |
|---|
| 通道 0(CH0) | B1 的 bit0~bit10(共 11bit) | `channels[0] = ((sbus_frame[1] |
| 通道 1(CH1) | B2 的 bit3bit13(B2 的 bit3bit7 共 5bit,B3 的 bit0~bit5 共 6bit,合计 11bit) | `channels[1] = ((sbus_frame[2] >> 3 |
| 通道 2(CH2) | B3 的 bit6bit16(B3 的 bit6bit7 共 2bit,B4 的 bit0bit7 共 8bit,B5 的 bit0bit0 共 1bit,合计 11bit) | `channels[2] = ((sbus_frame[3] >> 6 |
| 通道 3(CH3) | B5 的 bit1bit11(B5 的 bit1bit7 共 7bit,B6 的 bit0~bit3 共 4bit,合计 11bit) | `channels[3] = ((sbus_frame[5] >> 1 |
| 通道 4(CH4) | B6 的 bit4bit14(B6 的 bit4bit7 共 4bit,B7 的 bit0~bit6 共 7bit,合计 11bit) | `channels[4] = ((sbus_frame[6] >> 4 |
| 通道 5(CH5) | B7 的 bit7bit17(B7 的 bit7 1bit + B8 的 bit0bit7 8bit + B9 的 bit0~bit1 2bit,合计 11bit) | `channels[5] = ((sbus_frame[7] >> 7 |
| 通道 6(CH6) | B9 的 bit2bit12(B9 的 bit2bit7 6bit + B10 的 bit0~bit4 5bit,合计 11bit) | `channels[6] = ((sbus_frame[9] >> 2 |
| 通道 7(CH7) | B10 的 bit5bit15(B10 的 bit5bit7 3bit + B11 的 bit0~bit7 8bit,合计 11bit) | `channels[7] = ((sbus_frame[10] >> 5 |
| 通道 8(CH8) | B12 的 bit0bit10(B12 的 bit0bit7 8bit + B13 的 bit0~bit2 3bit,合计 11bit) | `channels[8] = ((sbus_frame[12] |
| 通道 9(CH9) | B13 的 bit3bit13(B13 的 bit3bit7 5bit + B14 的 bit0~bit5 6bit,合计 11bit) | `channels[9] = ((sbus_frame[13] >> 3 |
| 通道 10(CH10) | B14 的 bit6bit16(B14 的 bit6bit7 2bit + B15 的 bit0bit7 8bit + B16 的 bit0bit0 1bit,合计 11bit) | `channels[10] = ((sbus_frame[14] >> 6 |
| 通道 11(CH11) | B16 的 bit1bit11(B16 的 bit1bit7 7bit + B17 的 bit0~bit3 4bit,合计 11bit) | `channels[11] = ((sbus_frame[16] >> 1 |
| 通道 12(CH12) | B17 的 bit4bit14(B17 的 bit4bit7 4bit + B18 的 bit0~bit6 7bit,合计 11bit) | `channels[12] = ((sbus_frame[17] >> 4 |
| 通道 13(CH13) | B18 的 bit7bit17(B18 的 bit7 1bit + B19 的 bit0bit7 8bit + B20 的 bit0~bit1 2bit,合计 11bit) | `channels[13] = ((sbus_frame[18] >> 7 |
| 通道 14(CH14) | B20 的 bit2bit12(B20 的 bit2bit7 6bit + B21 的 bit0~bit4 5bit,合计 11bit) | `channels[14] = ((sbus_frame[20] >> 2 |
| 通道 15(CH15) | B21 的 bit5bit15(B21 的 bit5bit7 3bit + B22 的 bit0~bit7 8bit,合计 11bit) | `channels[15] = ((sbus_frame[21] >> 5 |
uint16_t sbus_channels[16] = {0};
void SBUS_Frame_Parse(uint8_t *sbus_frame)
{
if (sbus_frame[0] != 0x0F || (sbus_frame[24] != 0x00 && sbus_frame[24] != 0x7E))
{
return;
}
sbus_channels[0] = ((sbus_frame[1] | sbus_frame[2] << 8) & 0x07FF);
sbus_channels[1] = ((sbus_frame[2] >> 3 | sbus_frame[3] << 5) & 0x07FF);
sbus_channels[2] = ((sbus_frame[3] >> 6 | sbus_frame[4] << 2 | sbus_frame[5] << 10) & 0x07FF);
sbus_channels[3] = ((sbus_frame[5] >> 1 | sbus_frame[6] << 7) & 0x07FF);
sbus_channels[4] = ((sbus_frame[6] >> 4 | sbus_frame[7] << 4) & 0x07FF);
sbus_channels[5] = ((sbus_frame[7] >> 7 | sbus_frame[8] << 1 | sbus_frame[9] << 9) & 0x07FF);
sbus_channels[6] = ((sbus_frame[9] >> 2 | sbus_frame[10] << 6) & 0x07FF);
sbus_channels[7] = ((sbus_frame[10] >> 5 | sbus_frame[11] << 3) & 0x07FF);
sbus_channels[8] = ((sbus_frame[12] | sbus_frame[13] << 8) & 0x07FF);
sbus_channels[9] = ((sbus_frame[13] >> 3 | sbus_frame[14] << 5) & 0x07FF);
sbus_channels[10] = ((sbus_frame[14] >> 6 | sbus_frame[15] << 2 | sbus_frame[16] << 10) & 0x07FF);
sbus_channels[11] = ((sbus_frame[16] >> 1 | sbus_frame[17] << 7) & 0x07FF);
sbus_channels[12] = ((sbus_frame[17] >> 4 | sbus_frame[18] << 4) & 0x07FF);
sbus_channels[13] = ((sbus_frame[18] >> 7 | sbus_frame[19] << 1 | sbus_frame[20] << 9) & 0x07FF);
sbus_channels[14] = ((sbus_frame[20] >> 2 | sbus_frame[21] << 6) & 0x07FF);
sbus_channels[15] = ((sbus_frame[21] >> 5 | sbus_frame[22] << 3) & 0x07FF);
SBUS_Flags_Parse(sbus_frame[23]);
}
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- Gemini 图片去水印
基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
- Markdown转HTML
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
- HTML转Markdown
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online