不清楚SBUS,这份SBUS协议详解请收藏

简介: 不清楚SBUS,这份SBUS协议详解请收藏

1、简介

SBUS,全称Serial Bus,即串行通信总线。本质上是一种串口通信协议,采用100K的波特率,8位数据位,2位停止位,偶效验,即8E2的串口通信。


2、串口配置

100k波特率,8位数据位(在stm32中要选择9位),偶校验(EVEN),2位停止位,无控流,25个字节。


3、协议格式

[startbyte] [data1][data2]…[data22][flags][endbyte]


startbyte=0x0f;

endbyte=0x00;


flags标志位是用来检测控制器与px4是否断开的标志位:

flags=1:控制器与接收器保持连接;

flags=0:控制器与接收器断开(失控),px4会控制电机停转。


data1…data22:对应16个通道(ch1-ch16),每个通道11bit(22X8=16X11=176)

数据范围在0-2047之间,基本上是282~1722,中值为1002;


ch1的11位=data2的低3位+data1的8位;

例如:data1=00110110,data2=11001111;

这时ch1=111 00110110=1846;通道1 的值就为1846;

ch2=data3的低6位+data2的高5位;

ch3=data5的低1位+data4的8位+data3的高2位;

ch4=4 7;

ch5=7 4;

ch6=2 8 1;

ch7=5 6;

ch8=8 3;

ch9=1 8;

ch10=4 7;

ch11=7 4;

ch12=2 8 1;

ch13=5 6;

ch14=8 3;

ch15=3 8;

ch16=8 5;


4、取反问题

用stm32中给px4发时,需要取反,并且是硬件取反,软件取反是无效的;硬件取反的电路图如下。

image.png


5、间隔问题

它分两种模式(高速模式和普通模式)

高速模式:每隔7ms一帧数据,因为两帧的间隔只有超过3ms,才会被接受;

而根据波特率计算一下,发送25字节需要的时间+3~4ms=7ms

普通模式:每隔14ms一帧数据;


6、数据解析与合并

#include "Sbus.h"
#include "bsp_usart1.h"
#include "string.h"
uint16_t values[16]={0};
void sbus_out(uint16_t num_values)
{
  int i=0;
  uint16_t value=0;
  uint8_t byteindex = 1;
  uint8_t offset = 0;
  uint8_t oframe[25] = { 0 };
  memset(oframe,0,25);
  oframe[0]=0x0f;
  oframe[24]=0x00;
  for (i = 0; (i < num_values) && (i < 16); ++i)
  {
    value = (unsigned short)(((values[i] - SBUS_SCALE_OFFSET) / SBUS_SCALE_FACTOR) + .5f);
    if (value > 0x07ff)
    {
      value = 0x07ff;
    }
    while (offset >= 8)
    {
      ++byteindex;
      offset -= 8;
    }
    oframe[byteindex] |= (value << (offset)) & 0xff;
    oframe[byteindex + 1] |= (value >> (8 - offset)) & 0xff;
    oframe[byteindex + 2] |= (value >> (16 - offset)) & 0xff;
    offset += 11;
  }
  for (i=0;i<25;i++)
  {
    while(USART_GetFlagStatus(USART1,USART_FLAG_TC) == RESET);
    USART_SendData(USART1, (uint16_t)oframe[i]);     
  }
}
void sbus_decode(unsigned char *frame)
{
  unsigned int pick=0,channel=0,value1=0,piece=0;
  const struct sbus_bit_pick *decode;
  for (channel = 0; channel < 16; channel++) 
  {
    value1 = 0;
    for (pick = 0; pick < 3; pick++) 
    {
      decode = &sbus_decoder[channel][pick];
      if (decode->mask != 0) 
      {
        piece = frame[1 + decode->byte];
        piece >>= decode->rshift;
        piece &= decode->mask;
        piece <<= decode->lshift;
        piece &= 0x07ff;
        value1 |= piece;
      }
    }
    values[channel] = (uint16_t)(value1 * SBUS_SCALE_FACTOR + .5f) + SBUS_SCALE_OFFSET;
    if(channel==1)
    {
      values[channel]=3029-values[channel];
    }
  }
}

合成函数:

void sbus_out(uint16_t num_values);

//参数为通道数;

values[16]就是对应的16个通道;

解析函数:

void sbus_decode(unsigned char *frame);

//frame为25个u8位数据;

目录
相关文章
|
Ubuntu Linux 网络安全
RK3588 开发板上根文件系统导出并制作img镜像
RK3588 开发板上根文件系统导出并制作img镜像
6103 1
|
监控 Java Linux
Jetson 学习笔记(十二):CSI摄像头实现rtsp流的传输并对动态获取多路流进行探索
本文是关于如何在Jetson设备上使用CSI摄像头实现RTSP流传输的详细教程,包括安装依赖、编译gst-rtsp-server、测试、源代码介绍以及如何动态获取多路流的RTSP服务器。
1809 2
Jetson 学习笔记(十二):CSI摄像头实现rtsp流的传输并对动态获取多路流进行探索
|
Ubuntu 开发工具 git
ESP32-C3 VScode开发环境搭建(基于ESP-IDF—Windows和Ubuntu双环境)
对于ESP32-C3开发,自己对Arduino环境使用起来很是不习惯,既然乐鑫官方都出对应的环境,还是来试试官方环境
5487 0
ESP32-C3 VScode开发环境搭建(基于ESP-IDF—Windows和Ubuntu双环境)
|
中间件 编译器 调度
STM32cubemx对FreeRTOS的适配(工程模板配置)
STM32cubemx对FreeRTOS的适配(工程模板配置)
1822 0
|
Linux 网络安全 数据安全/隐私保护
Jetson 学习笔记(十三):SSH远程登录控制(终端控制和图形界面)-成功通过
这篇文章介绍了如何通过SSH命令行和VNC图形界面远程登录和控制NVIDIA Jetson Nano设备。
3592 0
Jetson 学习笔记(十三):SSH远程登录控制(终端控制和图形界面)-成功通过
ly~
|
Ubuntu Linux C语言
SDL 图形库安装常见错误及解决方法
SDL(Simple DirectMedia Layer)图形库安装过程中可能会遇到编译错误、运行时错误、依赖库缺失等问题。本文总结了在 Linux 和 Windows 系统上常见的错误及解决方法,包括检查和安装依赖库、配置 SDL 子系统、处理 X11 错误等,帮助用户顺利完成 SDL 的安装和配置。
ly~
3690 8
关于流控RTS/CTS ,DTR/DSR的说明
关于流控RTS/CTS ,DTR/DSR的说明
5093 0
|
移动开发 网络协议 数据格式
【VOFA+速成】半小时入门VOFA+简明教程之基础认识(一)
【VOFA+速成】半小时入门VOFA+简明教程(一)
stm32f407探索者开发板(十五)——NVIC中断优先级管理
stm32f407探索者开发板(十五)——NVIC中断优先级管理
2038 0

热门文章

最新文章