S.BUS协议

2023-05-16

内容

本篇文章主要是S.BUS协议原理介绍,并实现了arduino输出S.BUS数据。

S.BUS简介

SBUS是一个接收机串行总线输出,通过这根总线,可以获得遥控器上所有通道的数据。目前很多模型及无人机电子设备都支持SBUS总线的接入。使用SBUS总线获取通道数据,效率高的,而且节省硬件资源,只需要一根线即可获取所有通道的数据。

SBUS总线使用的是TTL电平(3.3v)的反向电平,即标准TTL中的1取反为0,而0则取反为1,串口波特率为100000,数据位为8位,2个停止位,偶校验。

SBUS一帧数据的长度为25个字节,其中第"0"个字节为帧头:0x0f;第24个字节为帧尾:0x00;从第1个字节到第22个字节为1-16号比例通道的数据字节;第23字节中,第7位为数字开关通道17通道,第6位为数字开关通道18通道,第5位为帧状态标志为(判断是否丢帧),用于控制接收机上的LED的状态,第4位为失控保护激活标志位,此位为1时,表示接收机进入失控保护状态。
在这里插入图片描述

重要的点

SBUS本质是一种串口通信协议,采用100K的波特率,8位数据位,两位停止位,偶效验,即8E2的串口通信。

这里对于单片机学得不精的人来说特别容易搞混,波特率100000,两位停止位没什么问题。问题在于8位数据位,偶校验,这段话在单片机中却需要这样子表达9位数据位、偶校验。对没有错是9位数据位、偶校验。刚开始编码的时候我就一直卡在了这里,F4的飞控一直识别不了我编码的SBUS信号。原因如下:

如果需要8位数据,无奇偶校验,则数据长度=8
如果需要8位数据,有奇偶校验,则数据长度=9

值得注意的有三点:

1.SBUS采用负逻辑,所以无论接收还是发送都要进行硬件取反(注意,一定要硬件取反),电路如下
(用普通NPN三极管就可以,我试过可以用8050)
三极管使用8050就可以
2.SBUS有两种模式,

  a.高速模式:每4ms发送一次

  b.低速模式:每14ms发送一次

就是说每间隔4或者14ms这个串口就发送25个字节的数据,这25个字节的数据最多可以包含16个信息

3.100K的波特率不是标准波特率,一般串口工具都不能直接读取(所以不要直接用电脑调试,除非你的电脑写好了非标准串口),可以用单片机读取。

具体协议的格式如下:
在这里插入图片描述

C语言

S.BUS协议每帧数据有25字节。每字节含有12个比特,使用1个起始位“0”,8个数据位,1个奇校验位(8个数据位中1的数量为奇数则此位为“1”否则为“0”)两个终止位“1”。采用LSB first方式发送,即最低有效位(二进制数据右侧)先发。
帧头:1111 0000(二进制),帧尾:0000 0000(二进制)。
数据:从第1数据字节起,到第22字节,一共有数据位176个,(11 16=822)它们按照顺序分别是通道1至通道16的舵机控制数据,每个通道占11比特。取值范围是0~2047。
第23字节我管它叫做“功能字节”,第0比特为数字通道1的值,第1比特为数字通道2的值,第2比特为丢帧信息,第3比特为失效保护开关,第4~7比特暂时保留没用。

编码

uint8_t sbus_data[25]={0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint16_t ChValue[16]//通道数据,即遥控器发送过来的PWM
//PWM转SBUS
    // SBUS header
    sbus_data[0] = 0x0F;
    // 16 ChValue of 11 bit data
    sbus_data[1]  = (unsigned char) ((ChValue[0] & 0x07FF));
    sbus_data[2]  = (unsigned char) ((ChValue[0] & 0x07FF)>>8   | (ChValue[1] & 0x07FF)<<3);
    sbus_data[3]  = (unsigned char) ((ChValue[1] & 0x07FF)>>5   | (ChValue[2] & 0x07FF)<<6);
    sbus_data[4]  = (unsigned char) ((ChValue[2] & 0x07FF)>>2);
    sbus_data[5]  = (unsigned char) ((ChValue[2] & 0x07FF)>>10  | (ChValue[3] & 0x07FF)<<1);
    sbus_data[6]  = (unsigned char) ((ChValue[3] & 0x07FF)>>7   | (ChValue[4] & 0x07FF)<<4);
    sbus_data[7]  = (unsigned char) ((ChValue[4] & 0x07FF)>>4   | (ChValue[5] & 0x07FF)<<7);
    sbus_data[8]  = (unsigned char) ((ChValue[5] & 0x07FF)>>1);
    sbus_data[9]  = (unsigned char) ((ChValue[5] & 0x07FF)>>9   | (ChValue[6] & 0x07FF)<<2);
    sbus_data[10] = (unsigned char) ((ChValue[6] & 0x07FF)>>6   | (ChValue[7] & 0x07FF)<<5);
    sbus_data[11] = (unsigned char) ((ChValue[7] & 0x07FF)>>3);
    sbus_data[12] = (unsigned char) ((ChValue[8] & 0x07FF));
    sbus_data[13] = (unsigned char) ((ChValue[8] & 0x07FF)>>8   | (ChValue[9] & 0x07FF)<<3);
    sbus_data[14] = (unsigned char) ((ChValue[9] & 0x07FF)>>5   | (ChValue[10] & 0x07FF)<<6); 
    sbus_data[15] = (unsigned char) ((ChValue[10] & 0x07FF)>>2);
    sbus_data[16] = (unsigned char) ((ChValue[10] & 0x07FF)>>10 | (ChValue[11] & 0x07FF)<<1);
    sbus_data[17] = (unsigned char) ((ChValue[11] & 0x07FF)>>7  | (ChValue[12] & 0x07FF)<<4);
    sbus_data[18] = (unsigned char) ((ChValue[12] & 0x07FF)>>4  | (ChValue[13] & 0x07FF)<<7);
    sbus_data[19] = (unsigned char) ((ChValue[13] & 0x07FF)>>1);
    sbus_data[20] = (unsigned char) ((ChValue[13] & 0x07FF)>>9  | (ChValue[14] & 0x07FF)<<2);
    sbus_data[21] = (unsigned char) ((ChValue[14] & 0x07FF)>>6  | (ChValue[15] & 0x07FF)<<5);
    sbus_data[22] = (unsigned char) ((ChValue[15] & 0x07FF)>>3);
    // flags
    sbus_data[23] = 0x00;
    // footer
sbus_data[24] = 0X00;

解码

#define SIZE_BUFF   (100)//S-BUS协议中遥控器通道数值范围
 
//S-BUS解析函数
int sbus_read_parse(int _fd, uint16_t *val){
    //读取遥控器通道数据
    uint8_t _buf[SIZE_BUFF];
    int len = read(_fd, _buf, SIZE_BUFF);
    if (len < 0)
    {
        return -1;
    }
 
    //略过协议包头、包尾、长度判断过程
 
    //按11bits解析遥控器通道
    val[0] = ((buff[ind + 1] | buff[ind + 2] << 8) & 0x07FF);
    val[1] = ((buff[ind + 2] >> 3 | buff[ind + 3] << 5) & 0x07FF);
    val[2] = ((buff[ind + 3] >> 6 | buff[ind + 4] << 2 | buff[ind + 5] << 10) & 0x07FF);
    val[3] = ((buff[ind + 5] >> 1 | buff[ind + 6] << 7) & 0x07FF);
    val[4] = ((buff[ind + 6] >> 4 | buff[ind + 7] << 4) & 0x07FF);
    val[5] = ((buff[ind + 7] >> 7 | buff[ind + 8] << 1 | buff[ind + 9] << 9) & 0x07FF);
    val[6] = ((buff[ind + 9] >> 2 | buff[ind + 10] << 6) & 0x07FF);
    val[7] = ((buff[ind + 10] >> 5 | buff[ind + 11] << 3) & 0x07FF);
    val[8] = ((buff[ind + 12] | buff[ind + 13] << 8) & 0x07FF);
    val[9] = ((buff[ind + 13] >> 3 | buff[ind + 14] << 5) & 0x07FF);
    val[10] = ((buff[ind + 14] >> 6 | buff[ind + 15] << 2 | buff[ind + 16] << 10) & 0x07FF);
    val[11] = ((buff[ind + 16] >> 1 | buff[ind + 17] << 7) & 0x07FF);
    val[12] = ((buff[ind + 17] >> 4 | buff[ind + 18] << 4) & 0x07FF);
    val[13] = ((buff[ind + 18] >> 7 | buff[ind + 19] << 1 | buff[ind + 20] << 9) & 0x07FF);
    val[14] = ((buff[ind + 20] >> 2 | buff[ind + 21] << 6) & 0x07FF);
    val[15] = ((buff[ind + 21] >> 5 | buff[ind + 22] << 3) & 0x07FF);
 
 
    return 0;
}

参考:https://www.jianshu.com/p/b0b81c45280c
https://blog.csdn.net/qq1113512618/article/details/96628893?biz_id=102&utm_term=sbus&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-3-96628893&spm=1018.2118.3001.4187

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

S.BUS协议 的相关文章

  • WSL2中使用systemctl报错Failed to connect to bus: Host is down

    问题截图 xff1a System has not been booted with systemd as init system PID 1 Can t operate Failed to connect to bus Host is d
  • Codeforces1153A-Serval and Bus(数学)

    原题链接 xff1a http codeforces com contest 1153 problem A 题目原文 xff1a A Serval and Bus time limit per test 1 second memory li
  • A. Serval and Bus

    outputstandard output It is raining heavily But this is the first day for Serval who just became 3 years old to go to th
  • Failed to get D-Bus connection: Operation not permitted

    docker容器centos7中 xff0c 通过systemctl start service出现下错误 Failed to get D Bus connection Operation not permitted docker中的容器启
  • px4驱动linux,S.Bus Driver for Linux

    用于 Linux 的 S Bus 驱动 S Bus Driver for Linux 允许基于 Linux 的无人机通过串行端口从 Futaba S Bus 接收机 访问多达 16 个通道 驱动程序还应该与使用 S Bus 协议的其他接收器
  • WSL的CentOS7报错Failed to get D-Bus connection: Operation not permitted解决办法

    WSL的CentOS7使用systemctl和service命令时报错Failed to get D Bus connection Operation not permitted 解决办法是更换systemctl文件 首先备份systemc
  • SpringCloud(十一)Bus消息总线、Stream消息驱动

    一 Bus消息总线 需求 xff1a 分布式自动刷新配置功能 xff1b 解决 xff1a SpringCloud Bus配合Spring cloud Config使用可以实现配置的动态刷新 1 概述 定义 xff1a Spring Clo
  • 总线学习(BUS)

    1 总线的概念 总线是指计算机设备和设备之间传输信息的公共数据通道 总线是连接计算机硬件系统内多种设备的通信线路 xff0c 一个重要特征是由总线上的所有设备共享 xff0c 可以将计算机系统的多种设备连接到总线上 如果是某两个设备或设备之
  • ESP8266解析S-BUS协议

    Talk is cheap show you code 编译平台 xff1a Arduino IDE span class token comment 功能 xff1a 软件串口读取S BUS数据 xff1b 解析 xff1b 串口打印 s
  • 计算机组成.零件之间的通信.总线BUS

    总线干嘛的 xff1f 说白了就是用来传输数据的 xff0c 在计算机的各个部件之间 比如我主存里存的数据CPU要用 xff0c 需要一条线路传过去吧 xff0c CPU内部各个寄存器之间 寄存器与ALU CU与各个部件之间等等等等很多地方
  • simulink bus总线创建方法

    在simulink中创建bus总线 xff0c 主要包含2种方法 xff1a 基于模块创建总线对象 使用模块 xff0c 根据输入信号创建总线 基于 MATLAB 数据创建总线对象 可以使用 Simulink Bus cellToObjec
  • linux-kernel, bus总线数据结构分析

    设备模型中的三大组件是 xff1a 总线 xff0c 驱动 xff0c 设备 bus driver device 数据结构总览 总线除了一些物理总线的抽象 xff0c 还代表一些虚拟的总线 xff0c 如platform xff0c 所以在
  • 从零开始学JetsonTX2----can bus开发

    step by step implementation 搞硬件开发 xff0c 先把技术手册搞到手 这个网页把几乎Jetson tx2的开发资料都汇总了一下 找教程开始配置can所需要系统环境 NIVIDA社区的教程 xff1a https
  • RS232/RS485/CAN_BUS 通信原理总结与通信波形分析

    分析一 xff1a 232串口信号 要点 xff1a RS232 xff0c 全双工 xff0c 采用三线制传输分别为TXD RXD GND xff0c 其中TXD为发送信号 xff0c RXD为接收信号 在RS232中任何一条信号线的电压
  • Google-Guava-EventBus源码解读

    Guava是Google开源的一个Java基础类库 它在Google内部被广泛使用 Guava提供了很多功能模块比如 集合 并发库 缓存等 EventBus是其中的一个module 本篇结合EventBus源码来谈谈它的设计与实现 概要 首
  • vue 兄弟组件之间传值之bus

    有时候两个组件也需要通信 非父子关系 当然Vue2 0提供了Vuex 但在简单的场景下 可以使用一个空的Vue实例作为中央事件总线 参考 http blog csdn net u013034014 article details 54574
  • 【PCIe】3: PCIe BDF(Bus,Device,Function)

    目录 1 概述 2 BUS 总线号 3 Device 设备号 4 Function 功能号 1 概述 PCIe总线中的每一个功能都有一个唯一的标识符与之对应 这个标识符就是BDF Bus Device Function
  • 在原子变量的上下文中什么是总线锁定?

    我使用 C 很长时间了 现在我开始学习汇编并了解处理器的工作原理 不仅仅是为了好玩 而且我必须将其作为测试程序的一部分 在学习汇编时 我开始听到一些在讨论多线程时到处听到的术语 因为我在科学计算中进行了大量的多线程处理 我正在努力了解全貌
  • 是否有通用 I2C 命令来查看设备是否仍然存在于总线上?

    是否有通用的 I2C 命令来查看设备在初始化一次后是否仍然存在于总线上 例如 OLED 显示器 我问这个的原因是为了避免主程序由于库代码中存在无限循环而冻结 当设备断开连接时 例如 Wire 库 在 MCU 启动时 我想检查设备是否可用 并
  • 我正在使用 SQL 设计公交车时刻表。每条巴士路线都有多个站点,我是否需要为每条路线准备不同的表?

    我正在尝试提出尽可能最有效的数据库 我的巴士路线大约有 10 个站点 巴士从一号站出发 直到到达第十站 然后再返回 这个循环每天发生3次 我真的很困惑如何有效地生成公交车的时间以及应该在哪里存储站点 如果我将所有停靠点放在一个字段中 将时间

随机推荐