Parsing SBUS package source code sharing

/************************************************* 
* @copyright: 
* @author:Xupeng
* @date:2022-11-03
* @description: 
**************************************************/  
#include "sbus.h"


#define DBG_TAG    "sbus"
#define DBG_LVL    DBG_LOG
#include <rtdbg.h>


#define SBUS_UART_NAME       "uart6"      /* 串口设备名称 */

/* 用于接收消息的信号量 */

static rt_device_t sbusSerial;


static rt_uint8_t recBuf[50];
static rt_uint8_t recCnt = 0;

#define INIT_VALUE 992//遥控器中间值

rt_uint16_t sbusVal[SBUS_CH_MAX] = {
    
    INIT_VALUE,INIT_VALUE,INIT_VALUE,INIT_VALUE,INIT_VALUE,INIT_VALUE,INIT_VALUE,INIT_VALUE,\
									INIT_VALUE,INIT_VALUE,INIT_VALUE,INIT_VALUE,INIT_VALUE,INIT_VALUE,INIT_VALUE,INIT_VALUE};
rt_uint8_t sbusIsOk = 0;
static bool findPackageHead = true;//包出错时重新开始寻找包头
/************************************************* 
* @function:static rt_err_t uart_input(rt_device_t dev, rt_size_t size)       
* @description: 接收数据
* @calls:          
* @input:                    
* @return:       
* @others:       
*************************************************/ 
static rt_err_t sbus_input(rt_device_t dev, rt_size_t size)
{
    
    
	uint8_t readLen; 
	readLen = rt_device_read(sbusSerial, 0, &recBuf[recCnt], size);//读取一个字节
	
	if(findPackageHead && recBuf[0] == 0x0f)//判断是不是包头
	{
    
    
		recCnt += readLen;
	}
	
	if(!findPackageHead && recBuf[0] == 0x00)//判断是不是重新开始寻找包头
		findPackageHead = true;
	
    if(recCnt >= 25)
    {
    
    
        if(recBuf[0] != 0x0f || recBuf[23] !=0)//数据帧格式错误
        {
    
    
            recCnt = 0;   
			recBuf[0] = 0x00;	
			findPackageHead = false;	//重新开始寻找包头
        }
        else
        {
    
    
			sbusVal[0] 	 = ((rt_uint16_t)recBuf[ 1] >> 0 | ((rt_uint16_t)recBuf[ 2] << 8 )) & 0x07FF;
			sbusVal[1]   = ((rt_uint16_t)recBuf[ 2] >> 3 | ((rt_uint16_t)recBuf[ 3] << 5 )) & 0x07FF;
			sbusVal[2]   = ((rt_uint16_t)recBuf[ 3] >> 6 | ((rt_uint16_t)recBuf[ 4] << 2 ) | (rt_uint16_t)recBuf[ 5] << 10 ) & 0x07FF;
			sbusVal[3]   = ((rt_uint16_t)recBuf[ 5] >> 1 | ((rt_uint16_t)recBuf[ 6] << 7 )) & 0x07FF;
			sbusVal[4]   = ((rt_uint16_t)recBuf[ 6] >> 4 | ((rt_uint16_t)recBuf[ 7] << 4 )) & 0x07FF;
			sbusVal[5]   = ((rt_uint16_t)recBuf[ 7] >> 7 | ((rt_uint16_t)recBuf[ 8] << 1 ) | (rt_uint16_t)recBuf[9] << 9 ) & 0x07FF;
			sbusVal[6]   = ((rt_uint16_t)recBuf[ 9] >> 2 | ((rt_uint16_t)recBuf[10] << 6 )) & 0x07FF;
			sbusVal[7]   = ((rt_uint16_t)recBuf[10] >> 5 | ((rt_uint16_t)recBuf[11] << 3 )) & 0x07FF;
			sbusVal[8]   = ((rt_uint16_t)recBuf[12] << 0 | ((rt_uint16_t)recBuf[13] << 8 )) & 0x07FF;
			sbusVal[9]   = ((rt_uint16_t)recBuf[13] >> 3 | ((rt_uint16_t)recBuf[14] << 5 )) & 0x07FF;
			sbusVal[10]  = ((rt_uint16_t)recBuf[14] >> 6 | ((rt_uint16_t)recBuf[15] << 2 ) | (rt_uint16_t)recBuf[16] << 10 ) & 0x07FF;
			sbusVal[11]  = ((rt_uint16_t)recBuf[16] >> 1 | ((rt_uint16_t)recBuf[17] << 7 )) & 0x07FF;
			sbusVal[12]  = ((rt_uint16_t)recBuf[17] >> 4 | ((rt_uint16_t)recBuf[18] << 4 )) & 0x07FF;
			sbusVal[13]  = ((rt_uint16_t)recBuf[18] >> 7 | ((rt_uint16_t)recBuf[19] << 1 ) | (rt_uint16_t)recBuf[20] << 9 ) & 0x07FF;
			sbusVal[14]  = ((rt_uint16_t)recBuf[20] >> 2 | ((rt_uint16_t)recBuf[21] << 6 )) & 0x07FF;
			sbusVal[15]  = ((rt_uint16_t)recBuf[21] >> 5 | ((rt_uint16_t)recBuf[22] << 3 )) & 0x07FF;
			sbusIsOk ++;
			recCnt = 0;
			recBuf[0] = 0x00;
        }
    }

    return RT_EOK;
}


/************************************************* 
* @function:void sbus_init()        
* @description: 初始化SBUS 
* @calls:          
* @input:                    
* @return:       
* @others:       
*************************************************/ 
int sbus_init()
{
    
    	
	
	struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;  /* 初始化配置参数 */
	rt_err_t res;
	
	sbusSerial = rt_device_find(SBUS_UART_NAME);
	if (!sbusSerial)
    {
    
    
        LOG_E("find %s failed!", SBUS_UART_NAME);
        return RT_ERROR;
    }
	config.baud_rate = BAUD_RATE_100000;      //修改波特率为 100000
	config.data_bits = DATA_BITS_9;           //数据位 9
	config.stop_bits = STOP_BITS_1;           //停止位 1
	config.bufsz     = 128;                   //修改缓冲区 buff size 为 128
	config.parity    = PARITY_EVEN;            //偶校验位


	res = rt_device_control(sbusSerial, RT_DEVICE_CTRL_CONFIG, &config);	
	if(res != RT_EOK)
	{
    
    
		LOG_E("commit control err!");
        return RT_ERROR;
	}
	
	res = rt_device_open(sbusSerial, RT_DEVICE_OFLAG_RDONLY|RT_DEVICE_FLAG_INT_RX);
	if(res != RT_EOK)
	{
    
    
		LOG_E("commit open err!");
        return RT_ERROR;
	}	
	res = rt_device_set_rx_indicate(sbusSerial, sbus_input);
	if(res != RT_EOK)
	{
    
    
		LOG_E("commit set indicate err!");
        return RT_ERROR;
	}	

	return RT_EOK;
}

INIT_PREV_EXPORT(sbus_init);

Note
1. The initialization
baud rate is 100Kbit,
the data bit is 9 bits,
the stop bit is 1 bit (initialization of STM32), and the parity
bit is PARITY_EVEN
. 2. When the data format is wrong, be sure to start looking for the packet header 0x0f again, otherwise the data will always be wrong. The implementation method is to wait for the end of the packet to be 0x00, and start looking for the header again after the end of the packet, because any channel data cannot be 0x00.
3. Different remote controllers have different output value ranges. The following is my data:
insert image description here

Guess you like

Origin blog.csdn.net/qq_15181569/article/details/129265239