目录
1 前言
在自己学习SBUS协议的过程中到处翻资料,看了很多也走了许多弯路,所以把这些记录下来供大家学习。
2 简介
SUBS协议,全称Serial Bus,即串行通信总线。本质上是一种串口通信协议,采用100K的波特率,8位数据位,2位停止位,偶效验的模式
SBUS协议通常使用在用于接收飞控遥控器的接收器上,如果这样使用,需要在硬件电路中加入反相器,进行硬件电路取反,软件取反是没用的
本实验中我们采用两块stm32f1开发板进行发送与接收,所以并不需要取反电路。
3 协议规则
3.1协议格式
一帧数据发送25个字节
总共发送16个通道的数据,每个通道用11位bit表示,即 11bit*16/8 = 22byte
Byte0 | Byte1–Byte22 | Byte23 | Byte24 |
---|---|---|---|
0x0F | Data | 0x00 | 0x00 |
起始字节 | 数据字节 | 标志位 | 结束字节 |
标志位:1字节,高四位从高到低依次表示:
bit7:CH17数字通道
bit6:CH16数字通道
bit5:帧丢失(Frame lost)
bit4:安全保护(Failsafe):失控保护激活位(0x10)判断飞机是否失控
bit3~bit0:低四位不用
3.2 协议发送
- 高速模式:每隔7ms一帧数据,因为两帧的间隔只有超过3ms,才会被接受;而根据波特率计算一下,发送25字节需要的时间+3~4ms=7ms
- 普通模式:每隔14ms一帧数据;
4 数据编码
4.1 串口发送初始化配置
注意:在stm32中使用校验位,数据字长选择USART_WordLength_9b
void USART1_SBUS_init(u32 bound)
{
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4 ;//抢占优先级
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_9b;//字长为9位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_2;//两个停止位
USART_InitStructure.USART_Parity = USART_Parity_Even;//偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART1, ENABLE); //使能串口1
}
4.2 协议编码
数组SBUS_Data[25]为我们串口发送的数组,数组ChValue[16]为我们具体要发送的每个通道值,最大为11bit,所以赋值在0-2047之间
SBUS_Data[0] = 0x0F;
// 16 ChValue of 11 bit data
SBUS_Data[1] = (unsigned char) ((ChValue[0] & 0x07FF));
SBUS_Data[2] = (unsigned char) ((ChValue[0] & 0x07FF)>>8 | (ChValue[1] & 0x07FF)<<3);
SBUS_Data[3] = (unsigned char) ((ChValue[1] & 0x07FF)>>5 | (ChValue[2] & 0x07FF)<<6);
SBUS_Data[4] = (unsigned char) ((ChValue[2] & 0x07FF)>>2);
SBUS_Data[5] = (