├── README.md ├── img ├── 1.jpg └── 2.png ├── sbus_decoder.c └── sbus_decoder.h /README.md: -------------------------------------------------------------------------------- 1 | 2 | # 一、概述和s-bus简介 3 | 4 | 这是遥控器sbus的解码库,用于把s-bus数据还原成遥控器数据。 5 | 6 | 简单来说s-bus就是用数字信号传输多通道遥控器数据,而且很方便的一点是它的硬件就是基于uart,这使得单片机读取其数据非常方便。 7 | 不同的是其电平和uart相反。 8 | 9 | 10 | ## 数据协议简介 11 | 12 | * 大约14ms一帧数据 13 | * 每帧数据25字节,具体格式如下: 14 | \ \ \ ... \ \ \ 15 | 其中: 16 | * \一定是0x0F,\一定是0x00。 17 | * \到\共22字节,表示16个通道的数值,每个通道11位(0-2047)。具体格式这里不介绍,看解码的代码。 18 | * \这里不讨论,解码时也不关心。 19 | 20 | # 二、使用方法 21 | 22 | ## 1、硬件 23 | 24 | 接收机一般电压是5v,输出的s-bus信号电平也是5v。 25 | 注意!!s-bus的电平和uart串口电平相反,一般加下面这个反相器可同时完成反相和电平转换 26 | : 27 | 28 | ![1.jpg](https://github.com/nicekwell/sbus-decoder/raw/master/img/1.jpg) 29 | 30 | ## 2、串口配置 31 | 32 | s-bus的uart采用:100k波特率,8位数据位,偶校验,2位停止位,无流控。 33 | stm32cubemx里配置如下: 34 | 35 | ![2.png](https://github.com/nicekwell/sbus-decoder/raw/master/img/2.png) 36 | 37 | ## 解码库的使用 38 | 39 | 见代码注释: 40 | 41 | ```c 42 | 使用方法: 43 | 1、把s-bus输出通过反相器后连接到uart接收端。 44 | 1、通过uart接收s-bus数据,uart使用格式为: 45 | 100k波特率,8位数据位,偶校验(Even),2位停止位。 46 | 2、uart接收到的数据通过sbus_decoder_get_byte()函数或者sbus_decoder_get_buf()函数传给此模块。 47 | 模块会解析数据,当解析到数据后会把数据保存在rc_data.rawdata(数据范围0-2047) 和 rc_data.percent(数据范围0-100)中。 48 | 3、数据返回方式采用全局变量,一般只要用一个进程不断读取uart数据并往sbus_decoder模块里送,模块就会不断刷新rc_data, 49 | 在需要获取遥控器数据的地方直接取变量 rc_data.rawdata[i] 或 rc_data.percent[i] 即可。 50 | 说明: 51 | 对于我的天地飞遥控器,rawdata范围是 340-1740,计算percent方式也是按照这个范围计算的,如果其他遥控器范围不同的话则计算方式也不同。 52 | ``` 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /img/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicekwell/sbus-decoder/aa1c360c74e2cf37c0ab235ab060dea8d196445b/img/1.jpg -------------------------------------------------------------------------------- /img/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nicekwell/sbus-decoder/aa1c360c74e2cf37c0ab235ab060dea8d196445b/img/2.png -------------------------------------------------------------------------------- /sbus_decoder.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | rc_data_t rc_data; 6 | 7 | static void sbus_decoder_get_frame(uint8_t* buf) //传入一帧数据,解析成各个通道数据,一帧长度必然是25字节 8 | { 9 | rc_data.rawdata[0] = ((buf[1]| buf[2]<<8) & 0x07FF); 10 | rc_data.rawdata[1] = ((buf[2]>>3 |buf[3]<<5) & 0x07FF); 11 | rc_data.rawdata[2] = ((buf[3]>>6 |buf[4]<<2 |buf[5]<<10) & 0x07FF); 12 | rc_data.rawdata[3] = ((buf[5]>>1 |buf[6]<<7) & 0x07FF); 13 | rc_data.rawdata[4] = ((buf[6]>>4 |buf[7]<<4) & 0x07FF); 14 | rc_data.rawdata[5] = ((buf[7]>>7 |buf[8]<<1 |buf[9]<<9) & 0x07FF); 15 | rc_data.rawdata[6] = ((buf[9]>>2 |buf[10]<<6) & 0x07FF); 16 | rc_data.rawdata[7] = ((buf[10]>>5|buf[11]<<3) & 0x07FF); 17 | rc_data.rawdata[8] = ((buf[12] |buf[13]<<8) & 0x07FF); 18 | rc_data.rawdata[9] = ((buf[13]>>3|buf[14]<<5) & 0x07FF); 19 | rc_data.rawdata[10] = ((buf[14]>>6|buf[15]<<2|buf[16]<<10) & 0x07FF); 20 | rc_data.rawdata[11] = ((buf[16]>>1|buf[17]<<7) & 0x07FF); 21 | rc_data.rawdata[12] = ((buf[17]>>4|buf[18]<<4) & 0x07FF); 22 | rc_data.rawdata[13] = ((buf[18]>>7|buf[19]<<1|buf[20]<<9) & 0x07FF); 23 | rc_data.rawdata[14] = ((buf[20]>>2|buf[21]<<6) & 0x07FF); 24 | rc_data.rawdata[15] = ((buf[21]>>5|buf[22]<<3) & 0x07FF); 25 | uint8_t i; 26 | for(i=0;i<16;i++) { 27 | rc_data.percent[i] = (rc_data.rawdata[i]-340)*100/(1704-340); 28 | } 29 | rc_data.flag_refresh = 1; 30 | } 31 | 32 | static uint8_t buf[25]={0}; //保存一帧数据 33 | static int8_t p = 0; //指向下个字节将要保存的位置 34 | void sbus_decoder_get_byte(uint8_t data) 35 | { 36 | int8_t q; 37 | buf[p] = data; 38 | //判断当前缓存是否满足一帧的格式 39 | q = p+1; 40 | if(q == 25) { 41 | q = 0; 42 | } 43 | if(buf[p] == 0x00 && buf[q] == 0x0f) { //当前缓存数据满足0x0f开头且0x00结尾 44 | uint8_t buf_frame[25] = {0}; 45 | memcpy(buf_frame, buf+q, 25-q); 46 | memcpy(buf_frame+25-q, buf, q); 47 | sbus_decoder_get_frame(buf_frame); 48 | } 49 | 50 | p++; 51 | if(p == 25) { 52 | p = 0; 53 | } 54 | } 55 | 56 | void sbus_decoder_get_buf(uint8_t* buf, uint16_t len) 57 | { 58 | uint16_t i; 59 | for(i=0;i //stm32 cubemx框架头文件 18 | #include 19 | 20 | typedef struct { 21 | uint16_t rawdata[16]; //根据sbus协议,一帧包含16通道,每通道11位(0-2047) 22 | uint8_t percent[16]; //我的天地飞遥控器实际rawdata范围是340-1704,中间值1024,这里还原遥控器的百分比 23 | uint8_t flag_refresh; //解析代码每次成功解析数据都会将此变量设为1,选择使用 24 | } rc_data_t; 25 | extern rc_data_t rc_data; 26 | 27 | /* 28 | 把串口获取到的数据送给下面函数,该函数会解析数据包,把获取到的数据放到rc_data里。 29 | */ 30 | void sbus_decoder_get_byte(uint8_t data); 31 | 32 | /* 33 | 功能和sbus_decoder_get_byte相同,这里直接传入的是buf。 34 | */ 35 | void sbus_decoder_get_buf(uint8_t* buf, uint16_t len); 36 | 37 | #endif 38 | --------------------------------------------------------------------------------