不清楚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]
0x0f0x00

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=3 8;
ch10=6 5;
ch11=1 8 2;
ch12=4 7;
ch13=7 4;
ch14= 2 8 1;
ch15=5 6;
ch16=8 3;

4、取反问题

用stm32中给px4发时,需要取反,并且是硬件取反,软件取反是无效的;硬件取反的电路图如下。
在这里插入图片描述

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个通道;

解析函数,frame为25个u8位数据:

  • void sbus_decode(unsigned char *frame);

Courtesy costs nothing. 礼多人不怪。

  • 34
    点赞
  • 152
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 47
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 47
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

振华OPPO

你的鼓励是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值