解析SBUS包源代码分享

/************************************************* 
* @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);

注意
一、初始化
波特率为100Kbit
数据位为9位
停止位为1位(STM32的初始化)
校验位为PARITY_EVEN
二、数据格式错误时一定要重新开始寻找包头0x0f,否则数据会一直错误。实现方法为等包尾0x00,等到包尾后重新开始寻找包头,因为任何通道数据都不可能为0x00。
三、不同遥控器输出值范围不一样,下面是我的数据:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_15181569/article/details/129265239
今日推荐