SBus协议的编解码C语言

简介

SBUS本质是一种串口通信协议,采用100K的波特率,8位数据位,两位停止位,偶效验。
值得注意的有三点:
1.SBUS采用负逻辑,所以无论接收还是发送都要进行硬件取反(注意,一定要硬件取反),电路如下
在这里插入图片描述

这是我在网上看资料时看到的电路,实际上我用的是7404电路

2.SBUS有两种模式,
a.高速模式:每4ms发送一次
b.低速模式:每14ms发送一次
就是说每间隔4或者14ms这个串口就发送25个字节的数据,这25个字节的数据最多可以包含16个信息

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

具体协议的格式如下

[数据头] [第一个字节] [第二个字节] …[第二十二的字节] [标志位] [数据尾]
数据头、标志位、数据尾 不携带信息,而且数据头和数据尾是固定的,数据头=0x0f; 数据尾=0x00;
数据头(1字节)+数据(22字节)+标志位(1字节)+数据尾(1字节)

编解码C语言源码

编码原理
一个信息是二进制的11bit,比如1111 1111 111就可以表示一个信息,一共16个这样的信息,按照顺序将这16个信息依次排成一串,得到一个176bit(11 *16)的数据,也就是22字节(176 / 8 = 22)的数据,再加上数据头数据尾校验位就组成了一个要通过串口传送的信息。每隔4或者14ms就传送一个这样的信息。
所以这16个信息每一个所能表示的最大值是2^11 = 2048,也就是他的精度。
标志位
标志位的高四位有特殊含义,第四位并没有使用,依照我的理解,第七位和第六位表示两个数字通道(通道17和18)信息(就是只有高低电平的通道,一般用来控制通断或者某个电机简单的启动或者停止,比如1表示启动电机0表示停止电机),第五位表示帧丢失,接收机红色LED亮起,我的理解是,如果这一位为1,表示这一帧信号出问题了,接收机红色LED亮起。第四位表示故障保护激活,意思应该是说如果这一位为1,激活接受方故障保护。
解码代码:
void PauseSBusData(char *data)
{
sRecvChanelData[ 0 ] = ( (data[ 2] & 0x07) << 8 ) + ((data[ 1] >> 0) & 0xFF);
sRecvChanelData[ 1 ] = ( (data[ 3] & 0x3F) << 5 ) + ((data[ 2] >> 3) & 0x1F);
sRecvChanelData[ 2 ] = ( (data[ 5] & 0x01) << 10) + ((data[ 4] & 0xFF) << 2) + ((data[ 3] >> 6) & 0x03);
sRecvChanelData[ 3 ] = ( (data[ 6] & 0x0F) << 7 ) + ((data[ 5] >> 1) & 0x7F);
sRecvChanelData[ 4 ] = ( (data[ 7] & 0x7F) << 4 ) + ((data[ 6] >> 4) & 0x0F);
sRecvChanelData[ 5 ] = ( (data[ 9] & 0x03) << 9 ) + ((data[ 8] & 0xFF) << 1 ) + ((data[ 7] >> 7) & 0x01);
sRecvChanelData[ 6 ] = ( (data[10] & 0x1F) << 6 ) + ((data[ 9] >> 2) & 0x3F);
sRecvChanelData[ 7 ] = ( (data[11] & 0xFF) << 3 ) + ((data[10] >> 5) & 0x07);
sRecvChanelData[ 8 ] = ( (data[13] & 0x07) << 8 ) + ((data[12] >> 0) & 0xFF);
sRecvChanelData[ 9 ] = ( (data[14] & 0x3F) << 5 ) + ((data[13] >> 3) & 0x1F);
sRecvChanelData[ 10 ] = ( (data[16] & 0x01) << 10) + ((data[15] & 0xFF) << 2) + ((data[14] >> 6) & 0x03);
sRecvChanelData[ 11 ] = ( (data[17] & 0x0F) << 7 ) + ((data[16] >> 1) & 0x7F);
sRecvChanelData[ 12 ] = ( (data[18] & 0x7F) << 4 ) + ((data[17] >> 4) & 0x0F);
sRecvChanelData[ 13 ] = ( (data[20] & 0x03) << 9 ) + ((data[19] & 0xFF) << 1 ) + ((data[18] >> 7) & 0x01);
sRecvChanelData[ 14 ] = ( (data[21] & 0x1F) << 6 ) + ((data[20] >> 2) & 0x3F);
sRecvChanelData[ 15 ] = ( (data[22] & 0xFF) << 3 ) + ((data[21] >> 5) & 0x07);
}
编码代码:
void SendSBusData(char *data)
{
data[0] = 0x0F;
data[1] = sSendChanelData[0] & 0xFF;
data[2] = ((sSendChanelData[1] << 3) & 0xFC) | (sSendChanelData[0] >> 8 & 0x03);
data[3] = ((sSendChanelData[1] >> 5) & 0x3F) | ((sSendChanelData[2] << 6) & 0xC0);
data[4] = ((sSendChanelData[2] >> 2) & 0xFF);
data[5] = ((sSendChanelData[2] >> 10) & 0x01) | ((sSendChanelData[3] << 1) & 0xFE);
data[6] = ((sSendChanelData[3] >> 7) & 0x0F) | ((sSendChanelData[4] << 4) & 0xF0);
data[7] = ((sSendChanelData[4] >> 4) & 0x7F) | ((sSendChanelData[5] << 7) & 0xF0);
data[8] = ((sSendChanelData[5] >> 1) & 0xFF);
data[9] = ((sSendChanelData[5] >> 9) & 0x03) | ((sSendChanelData[6] << 2) & 0xFC);
data[10] = ((sSendChanelData[6] >> 6) & 0x1F) | ((sSendChanelData[7] << 5) & 0xE0);
data[11] = ((sSendChanelData[7] >> 3) & 0xFF);
data[12] = sSendChanelData[8] & 0xFF;
data[13] = ((sSendChanelData[9] << 3) & 0xFC) | (sSendChanelData[8] >> 8 & 0x03);
data[14] = ((sSendChanelData[9] >> 5) & 0x3F) | ((sSendChanelData[10] << 6) & 0xC0);
data[15] = ((sSendChanelData[10] >> 2) & 0xFF);
data[16] = ((sSendChanelData[10] >> 10) & 0x01) | ((sSendChanelData[11] << 1) & 0xFE);
data[17] = ((sSendChanelData[11] >> 7) & 0x0F) | ((sSendChanelData[12] << 4) & 0xF0);
data[18] = ((sSendChanelData[12] >> 4) & 0x7F) | ((sSendChanelData[13] << 7) & 0xF0);
data[19] = ((sSendChanelData[13] >> 1) & 0xFF);
data[20] = ((sSendChanelData[13] >> 9) & 0x03) | ((sSendChanelData[14] << 2) & 0xFC);
data[21] = ((sSendChanelData[14] >> 6) & 0x1F) | ((sSendChanelData[15] << 5) & 0xE0);
data[22] = ((sSendChanelData[15] >> 3) & 0xFF);
data[23] = 0x0;
data[24] = 0x0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值