目录
文章目录
摘要
本节主要记录自己学习SBUS协议的过程,欢迎批评指正!!!这里参考下面这个博客:sbus协议解析
1.什么是SBUS协议
SBUS是一个接收机串行总线输出,通过这根总线,可以获得遥控器上所有通道的数据。目前很多模型及无人机电子设备都支持SBUS总线的接入。使用SBUS总线获取通道数据,效率高的,而且节省硬件资源,只需要一根线即可获取所有通道的数据。
- 特点1:SBUS总线使用的是TTL电平的反向电平,即标准TTL中的1取反为0,而0则取反为1,串口波特率为100000,数据位为8位,2个停止位,偶校验。
- 特点2:SBUS一帧数据的长度为25个字节,其中第"0"个字节为帧头:0x0f;第24个字节为帧尾:0x00;从第1个字节到第22个字节为1-16号比例通道的数据字节;第23字节中,第7位为数字开关通道17通道,第6位为数字开关通道18通道。第5位为帧状态标志为(判断是否丢帧),用于控制接收机上的LED的状态,第4位为失控保护激活标志位,此位为1时,表示接收机进入失控保护状态。
- 特点3:SBUS为什么是16个通道?因为22x8=11x16,每个通道用11bit表示,范围是0-2047。两帧之间的时间间隔4ms(高速模式),约7ms一帧。
具体的SBUS介绍,可以参考官网信息sbus协议官网地址
2. STM32 解析 SBUS协议
2.1初始化串口接收
void Sbus_Init(uint32_t bound)
{
//GPIO¶Ë¿ÚÉèÖÃ
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //ʹÄÜUSART3ʱÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //ʹÄÜGPIOBʱÖÓ
//USART3_RX GPIOB.11³õʼ»¯
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PB11
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//¸¡¿ÕÊäÈë
GPIO_Init(GPIOB, &GPIO_InitStructure);//³õʼ»¯GPIOB11
//USART3_RX NVIC ÅäÖÃ
NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//ÇÀÕ¼ÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //×ÓÓÅÏȼ¶0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀʹÄÜ
NVIC_Init(&NVIC_InitStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷
//USART3 ³õʼ»¯ÉèÖÃ
USART_InitStructure.USART_BaudRate = bound;//´®¿Ú²¨ÌØÂÊ
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//×Ö³¤Îª8λÊý¾Ý¸ñʽ
USART_InitStructure.USART_StopBits = USART_StopBits_1;//Ò»¸öֹͣλ
USART_InitStructure.USART_Parity = USART_Parity_No;//ÎÞÆæÅ¼Ð£Ñéλ
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ÎÞÓ²¼þÊý¾ÝÁ÷¿ØÖÆ
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //ÊÕ·¢Ä£Ê½
USART_Init(USART3, &USART_InitStructure); //³õʼ»¯´®¿Ú3
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);//¿ªÆô´®¿Ú½ÓÊÜÖжÏ
USART_ITConfig(USART3, USART_IT_IDLE, ENABLE);
USART_Cmd(USART3, ENABLE); //ʹÄÜ´®¿Ú3
}
2.2配置串口中断服务函数
void USART3_IRQHandler(void)
{
uint8_t res;
uint8_t clear = 0;
static uint8_t Rx_Sta = 1;
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)
{
res =USART3->DR;
USART3_RX_BUF[Rx_Sta++] = res;
}
else if(USART_GetITStatus(USART3, USART_IT_IDLE) != RESET)
{
clear = USART3->SR;
clear = USART3->DR;
USART3_RX_BUF[0] = Rx_Sta - 1;
Rx_Sta = 1;
}
}
2.3进行SBUS数据解析
void Sbus_Data_Count(uint8_t *buf)
{
sbus_ch[ 0] = ((int16_t)buf[ 2] >> 0 | ((int16_t)buf[ 3] << 8 )) & 0x07FF;
sbus_ch[ 1] = ((int16_t)buf[ 3] >> 3 | ((int16_t)buf[ 4] << 5 )) & 0x07FF;
sbus_ch[ 2] = ((int16_t)buf[ 4] >> 6 | ((int16_t)buf[ 5] << 2 ) | (int16_t)buf[ 6] << 10 ) & 0x07FF;
sbus_ch[ 3] = ((int16_t)buf[ 6] >> 1 | ((int16_t)buf[ 7] << 7 )) & 0x07FF;
sbus_ch[ 4] = ((int16_t)buf[ 7] >> 4 | ((int16_t)buf[ 8] << 4 )) & 0x07FF;
sbus_ch[ 5] = ((int16_t)buf[ 8] >> 7 | ((int16_t)buf[ 9] << 1 ) | (int16_t)buf[10] << 9 ) & 0x07FF;
sbus_ch[ 6] = ((int16_t)buf[10] >> 2 | ((int16_t)buf[11] << 6 )) & 0x07FF;
sbus_ch[ 7] = ((int16_t)buf[11] >> 5 | ((int16_t)buf[12] << 3 )) & 0x07FF;
sbus_ch[ 8] = ((int16_t)buf[13] << 0 | ((int16_t)buf[14] << 8 )) & 0x07FF;
sbus_ch[ 9] = ((int16_t)buf[14] >> 3 | ((int16_t)buf[15] << 5 )) & 0x07FF;
sbus_ch[10] = ((int16_t)buf[15] >> 6 | ((int16_t)buf[16] << 2 ) | (int16_t)buf[17] << 10 ) & 0x07FF;
sbus_ch[11] = ((int16_t)buf[17] >> 1 | ((int16_t)buf[18] << 7 )) & 0x07FF;
sbus_ch[12] = ((int16_t)buf[18] >> 4 | ((int16_t)buf[19] << 4 )) & 0x07FF;
sbus_ch[13] = ((int16_t)buf[19] >> 7 | ((int16_t)buf[20] << 1 ) | (int16_t)buf[21] << 9 ) & 0x07FF;
sbus_ch[14] = ((int16_t)buf[21] >> 2 | ((int16_t)buf[22] << 6 )) & 0x07FF;
sbus_ch[15] = ((int16_t)buf[22] >> 5 | ((int16_t)buf[23] << 3 )) & 0x07FF;
}
2.4在任务中调用
void Loop_Task_5ms(void)
{
Sbus_Data_Count(USART3_RX_BUF);
}
2.5相关变量和定义
uint8_t USART3_RX_BUF[26];
uint16_t sbus_ch[18]; //ͨµÀÊý¾Ý
uint8_t sbus_rc_flag = 0;
#ifndef __SBUS__H__
#define __SBUS__H__
#include "uart.h"
extern uint8_t USART3_RX_BUF[26];
extern uint16_t sbus_ch[18]; //ͨµÀÊý¾Ý
extern uint8_t sbus_rc_flag ;
void Sbus_Init(uint32_t bound);
void Sbus_Data_Count(uint8_t *buf);
#endif
3.获取数据