Skip to content

第 4 章:SBUS 遥控接收

📂 示例代码04_sbus_rc

4.1 知识要点

  • SBUS 协议帧格式:25 字节,100000 baud,8E2,信号反相
  • 16 通道 11-bit 数据的位域解包算法
  • ESP-IDF UART 驱动配置与信号反相
  • Failsafe 与 Lost Frame 标志位的处理

4.2 课程内容

SBUS 是 Futaba 开发的数字遥控协议,广泛用于航模和机器人领域。它通过单根串行线传输 16 个模拟通道和 2 个数字通道的数据,每帧 25 字节,以 14 ms(高速模式)或 7 ms 间隔发送。OSRCORE 使用 UART0 的 GPIO44 接收 SBUS 信号,硬件反相器将 SBUS 的反相逻辑还原为标准 UART 电平。

4.3 基础学习

SBUS 帧格式

字节 0:0x0F(帧头)
字节 1-22:22 字节数据(16 通道 × 11 bit = 176 bit)
字节 23:标志字节
  bit2 = lost_frame(帧丢失)
  bit3 = failsafe(接收机失联保护激活)
字节 24:0x00(帧尾)

注意:早期文档中 bit2/bit3 的含义有误(两者互换),代码中已按 FrSky/Futaba 规范更正:bit2 = lost_frame,bit3 = failsafe。

通道值范围:240(最小)~ 1810(最大),中立约 1024。

位域解包

16 个通道的 11-bit 数据紧密打包在 22 字节中,需要按位提取。完整 16 通道解包:

c
ch[0]  = ((buf[1]       | buf[2]  << 8) & 0x07FF);
ch[1]  = ((buf[2]  >> 3 | buf[3]  << 5) & 0x07FF);
ch[2]  = ((buf[3]  >> 6 | buf[4]  << 2 | buf[5] << 10) & 0x07FF);
ch[3]  = ((buf[5]  >> 1 | buf[6]  << 7) & 0x07FF);
ch[4]  = ((buf[6]  >> 4 | buf[7]  << 4) & 0x07FF);
ch[5]  = ((buf[7]  >> 7 | buf[8]  << 1 | buf[9] << 9) & 0x07FF);
ch[6]  = ((buf[9]  >> 2 | buf[10] << 6) & 0x07FF);
ch[7]  = ((buf[10] >> 5 | buf[11] << 3) & 0x07FF);
ch[8]  = ((buf[12]      | buf[13] << 8) & 0x07FF);
ch[9]  = ((buf[13] >> 3 | buf[14] << 5) & 0x07FF);
ch[10] = ((buf[14] >> 6 | buf[15] << 2 | buf[16] << 10) & 0x07FF);
ch[11] = ((buf[16] >> 1 | buf[17] << 7) & 0x07FF);
ch[12] = ((buf[17] >> 4 | buf[18] << 4) & 0x07FF);
ch[13] = ((buf[18] >> 7 | buf[19] << 1 | buf[20] << 9) & 0x07FF);
ch[14] = ((buf[20] >> 2 | buf[21] << 6) & 0x07FF);
ch[15] = ((buf[21] >> 5 | buf[22] << 3) & 0x07FF);

/* 标志字节:bit2=lost_frame,bit3=failsafe */
bool lost_frame = (buf[23] & (1 << 2)) != 0;
bool failsafe   = (buf[23] & (1 << 3)) != 0;

UART 配置要点

SBUS 使用非标准参数:100000 baud(非 115200)、偶校验(8E2)、信号反相。ESP-IDF 通过 uart_set_line_inverse() 在硬件层面处理反相,无需外部电路。

4.4 程序学习

UART 初始化(含反相):

c
uart_config_t cfg = {
    .baud_rate  = 100000,
    .data_bits  = UART_DATA_8_BITS,
    .parity     = UART_PARITY_EVEN,
    .stop_bits  = UART_STOP_BITS_2,
    .flow_ctrl  = UART_HW_FLOWCTRL_DISABLE,
    .source_clk = UART_SCLK_DEFAULT,
};
uart_driver_install(UART_NUM_0, 256, 0, 0, NULL, 0);
uart_param_config(UART_NUM_0, &cfg);
uart_set_pin(UART_NUM_0, 43, 44, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
uart_set_line_inverse(UART_NUM_0, UART_SIGNAL_RXD_INV | UART_SIGNAL_TXD_INV);

帧同步与解析:

c
// 同步到帧头 0x0F
uint8_t byte;
do {
    uart_read_bytes(UART_NUM_0, &byte, 1, portMAX_DELAY);
} while (byte != 0x0F);

buf[0] = byte;
int got = uart_read_bytes(UART_NUM_0, buf + 1, 24, pdMS_TO_TICKS(10));
if (got == 24 && sbus_parse(buf, &data)) {
    // data.lost_frame = (buf[23] & (1<<2)) != 0
    // data.failsafe   = (buf[23] & (1<<3)) != 0
    if (!data.failsafe && !data.lost_frame) {
        // 处理通道数据
    }
}

SBUS 通道值转换为 PWM 脉宽(µs):

c
// SBUS 范围 240-1810 → PWM 1000-2000 µs
#define SBUS_TO_US(v) ((uint32_t)(((v) - 240) * 1000 / 1570 + 1000))

4.5 课程总结

本章掌握了 SBUS 协议的帧格式和位域解包算法,学会了配置 ESP-IDF UART 驱动处理非标准波特率和信号反相。SBUS 接收是机器人遥控操作的基础,第 12 章将把它集成到完整控制系统中。


Built for OSRCORE robot development board.