SBUS信号例程详解

  • 1. SBUS信号简介
    • 1.硬件标准
    • 2.软件标准
      • 1.串口配置:
      • 2.协议格式:
      • 3.数据范围
      • 4、间隔问题
  • 2. STM32F4_Sbus (DMA+串口 )
    • (1) 串口配置
    • (2) 串口中断接收
    • (3) 信号解析
    • (4) DMA初始化

1. SBUS信号简介

SBUS全称serial-bus,是一种串口通信协议,广泛应用于航模遥控器(接收机)中。只用一根信号线就能传输多达16通道的数据,比多路PWM捕获高效且省资源。

1.硬件标准

  • TTL电平即3.3V。 使用负逻辑,即低电平为“1”,高电平为“0”。
  • 波特率:100000(100k)
  • 负逻辑必须加硬件反相器

硬件反相器电路如下:

2.软件标准

1.串口配置:

100k波特率,8位数据位(stm32-选择9位),2位停止位,偶校验(EVEN),无控流,25个字节。

2.协议格式:

接收器和遥控器支持多少个通道就有多少个

[startbyte] [data1] [data2] [data10] [flags] [endbyte]
0xf0(起始字节) Flags 0x00

每个通道数据占 11bit (低位在前一字节、高位在后一字节)

3.数据范围

航模遥控器输出的PWM值是1000~2000,中值为1500,sbus输出的会不一样,每个遥控器厂家各有不同。

注意Sbus 速率比较快,且满速传输。容易产生串口ORE错误,例程中有解决方法

参考这篇文章:STM32常见错误-持续更新

4、间隔问题

它分两种模式(高速模式和普通模式)
高速模式:每隔7ms一帧数据,因为两帧的间隔只有超过3ms,才会被接受;而根据波特率计算一下,发送25字节需要的时间+3~4ms=7ms
普通模式:每隔14ms一帧数

据;

2. STM32F4_Sbus (DMA+串口 )

(1) 串口配置

void uart4_sbus_init(void)//串口2初始化
{NVIC_InitTypeDef NVIC_InitStructure ;//定义中断结构体GPIO_InitTypeDef GPIO_InitStructure;//定义IO初始化结构体USART_InitTypeDef USART_InitStructure;//定义串口结构体//设置IO口和串口4时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);//打开串口对应的外设时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_UART4); //GPIOC10复用为UART4GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_UART4); //GPIOC10复用为UART4GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; //管脚指定GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;    //管脚模式:输出口GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //类型:推挽模式GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;   //上拉下拉设置GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化// 1 初始化串口及参数指定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_InitStructure.USART_BaudRate = 100000;USART_Init(UART4, &USART_InitStructure);// 2 配置中断优先级并使能NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;               //通道设置为串口中断NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;       //中断占先等级NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;              //中断响应优先级NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                 //打开中断NVIC_Init(&NVIC_InitStructure);// 3 配置进入中断方式USART_ITConfig(UART4, USART_IT_IDLE, ENABLE); //接收到一帧数据就进入中断USART_ITConfig(UART4, USART_IT_ERR, ENABLE);// 4 使能串口的DMA接收USART_DMACmd(UART4, USART_DMAReq_Rx, ENABLE);// 5 开启串口USART_Cmd(UART4, ENABLE);
}

(2) 串口中断接收

串口中断函数,在中断函数里面接收数据,进行SBUS信号解析。

void UART4_IRQHandler(void) //串口2中断服务函数
{if (USART_GetFlagStatus(UART4, USART_FLAG_FE) != RESET) {watch_usart4_fe_cnt++;USART_ReceiveData(UART4); USART_ClearFlag(UART4, USART_FLAG_FE);}if(USART_GetFlagStatus(UART4, USART_FLAG_PE) != RESET)         {watch_usart4_pe_cnt++;USART_ReceiveData(UART4);  USART_ClearFlag(UART4, USART_FLAG_PE);                } UART4_IRQHandler_cnt++;// USART_FLAG_OREif(USART_GetFlagStatus(UART4, USART_FLAG_ORE) != RESET){watch_usart4_ore_cnt++;USART_ReceiveData(UART4);}int i = 0;if(USART_GetITStatus(UART4, USART_IT_IDLE) != RESET)  //接收中断,若为1则表示已经接收到数据{//先读SR,再读DR,清除IDLE中断标志i = UART4->SR;                                                        //读SR寄存器i = UART4->DR;DMA_Cmd(DMA1_Stream2, DISABLE);rx_len = sbus_data_len - DMA_GetCurrDataCounter(DMA1_Stream2);if(rx_len != 0 && rec_sbus_data[0] == 0x0f) //判断数据长度并丢掉无用数据{for(i = 0; i < rx_len; i++){sbus_data[i] = 0;}for(i = 0; i < rx_len; i++){get_sbus_data(rec_sbus_data);//保存接收到的数据}for(i = 0; i < rx_len; i++)                                          //将数据缓存区清零{rec_sbus_data[i] = 0; //清空缓存}}DMA_ClearFlag(DMA1_Stream2, DMA_FLAG_TCIF2 );DMA_SetCurrDataCounter(DMA1_Stream2, sbus_data_len);                       //设置DMA接收单元的长度DMA_Cmd(DMA1_Stream2, ENABLE);                                         //打开DMA}
}

(3) 信号解析

上面中断函数里面有一个update_sbus函数,原型为u8 update_sbus(u8 *buf),解析subs信号全靠它了!!新建一个sbus.c文件,输入如下代码

#include "sbus.h"SBUS_CH_Struct SBUS_CH;//将sbus信号转化为通道值
u8 update_sbus(u8 *buf)
{int i;if (buf[23] == 0){SBUS_CH.ConnectState = 1;SBUS_CH.CH1 = ((int16_t)buf[ 1] >> 0 | ((int16_t)buf[ 2] << 8 )) & 0x07FF;SBUS_CH.CH2 = ((int16_t)buf[ 2] >> 3 | ((int16_t)buf[ 3] << 5 )) & 0x07FF;SBUS_CH.CH3 = ((int16_t)buf[ 3] >> 6 | ((int16_t)buf[ 4] << 2 ) | (int16_t)buf[ 5] << 10 ) & 0x07FF;SBUS_CH.CH4 = ((int16_t)buf[ 5] >> 1 | ((int16_t)buf[ 6] << 7 )) & 0x07FF;SBUS_CH.CH5 = ((int16_t)buf[ 6] >> 4 | ((int16_t)buf[ 7] << 4 )) & 0x07FF;SBUS_CH.CH6 = ((int16_t)buf[ 7] >> 7 | ((int16_t)buf[ 8] << 1 ) | (int16_t)buf[9] << 9 ) & 0x07FF;SBUS_CH.CH7 = ((int16_t)buf[ 9] >> 2 | ((int16_t)buf[10] << 6 )) & 0x07FF;SBUS_CH.CH8 = ((int16_t)buf[10] >> 5 | ((int16_t)buf[11] << 3 )) & 0x07FF;SBUS_CH.CH9 = ((int16_t)buf[12] << 0 | ((int16_t)buf[13] << 8 )) & 0x07FF;SBUS_CH.CH10 = ((int16_t)buf[13] >> 3 | ((int16_t)buf[14] << 5 )) & 0x07FF;SBUS_CH.CH11 = ((int16_t)buf[14] >> 6 | ((int16_t)buf[15] << 2 ) | (int16_t)buf[16] << 10 ) & 0x07FF;SBUS_CH.CH12 = ((int16_t)buf[16] >> 1 | ((int16_t)buf[17] << 7 )) & 0x07FF;SBUS_CH.CH13 = ((int16_t)buf[17] >> 4 | ((int16_t)buf[18] << 4 )) & 0x07FF;SBUS_CH.CH14 = ((int16_t)buf[18] >> 7 | ((int16_t)buf[19] << 1 ) | (int16_t)buf[20] << 9 ) & 0x07FF;SBUS_CH.CH15 = ((int16_t)buf[20] >> 2 | ((int16_t)buf[21] << 6 )) & 0x07FF;SBUS_CH.CH16 = ((int16_t)buf[21] >> 5 | ((int16_t)buf[22] << 3 )) & 0x07FF;return 1;}else {SBUS_CH.ConnectState = 0;return 0;}
}

上面定义了一个SBUS_CH_Struct 结构体类型的变量SBUS_CH,该结构体在sbus.h中定义

typedef struct
{uint16_t CH1;//通道1数值uint16_t CH2;//通道2数值uint16_t CH3;//通道3数值uint16_t CH4;//通道4数值uint16_t CH5;//通道5数值uint16_t CH6;//通道6数值uint16_t CH7;//通道7数值uint16_t CH8;//通道8数值uint16_t CH9;//通道9数值uint16_t CH10;//通道10数值uint16_t CH11;//通道11数值uint16_t CH12;//通道12数值uint16_t CH13;//通道13数值uint16_t CH14;//通道14数值uint16_t CH15;//通道15数值uint16_t CH16;//通道16数值uint8_t ConnectState;//遥控器与接收器连接状态 0=未连接,1=正常连接
}SBUS_CH_Struct;

(4) DMA初始化


void DMA1_SBUS_Init(void)
{DMA_InitTypeDef DMA_InitStructure;//定义DMA结构体//启动DMA时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);//DMA通道配置//DMA通道配置DMA_DeInit(DMA1_Stream2);while (DMA_GetCmdStatus(DMA1_Stream2) != DISABLE);DMA_InitStructure.DMA_Channel = DMA_Channel_4;DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&UART4->DR);//外设地址DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)rec_sbus_data;//内存地址DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;//dma传输方向DMA_InitStructure.DMA_BufferSize = sbus_data_len;//设置DMA在传输时缓冲区的长度DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//设置DMA的外设一个外设DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//设置DMA的内存递增模式DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据字长DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//内存数据字长DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//设置DMA的传输模式DMA_InitStructure.DMA_Priority = DMA_Priority_High;//设置DMA的优先级别DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;//存储器突发单次传输DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;//外设突发单次传输//配置DMA2的通道DMA_Init(DMA1_Stream2, &DMA_InitStructure);//使能DMA通道DMA_Cmd(DMA1_Stream2, ENABLE);
}

参考:振华OPPO

SBUS协议介绍和标准例程相关推荐

  1. SBUS协议(20200210)

    最近看到很多sbus协议,就专门搜集了一些资料学习一下. 1.介绍 SBUS是一个接收机串行总线输出,通过这根总线,可以获得遥控器上所有通道的数据.目前很多模型及无人机电子设备都支持SBUS总线的接入 ...

  2. SNMP协议介绍和操作截图

    第一章 SNMP协议介绍 SNMP协议 基于TCP/IP的网络管理包含3个组成部分: 1) 一个管理信息库MIB(Management Information Base).管理信息库包含所有代理进程的 ...

  3. SBUS协议转换芯片,SBUS转UART,sbus转rs232,sbus解码IC,zr003

    sbus 协议比较复杂.16通道一共用了22字节.每个通道占11bit.所以会存在拼字节错位的问题.需要转化成一个整形的数据.这对一般的主控还是有压力,开销不少.今天跟大家分享一个专用的sbus解码芯 ...

  4. AMBA协议介绍(1)——APB协议

    系列文章目录 AMBA协议介绍(1)--APB协议 AMBA协议介绍(2)--AHB协议 AMBA协议介绍(3)--AXI协议 目录 AMBA协议介绍 AMBA协议介绍(1)--APB协议 前言 一. ...

  5. 深度解析FUTABA的SBUS协议(/天地飞遥控器的WBUS协议/Robomaster接收机的DBUS协议)到底是啥?

    写在前面: 无论是SBUS(日本FUTABA,所以航模,车模爱好者都知道的公司,一个好点遥控器近万了),还是WBUS(天地飞遥控器接收机用),亦或者DBUS(Robomaster官方接收机用). 划重 ...

  6. Z-Wave技术的五大协议介绍(ZWave中心)

    Z-Wave技术的五大协议介绍 Z-Wave协议是一个低带宽半双工传输协议,它为高可靠性的低功耗网状网络的无线通信而设计.协议的主要目的是在控制单元和一个或多个节点单元之间可靠地传输较短的控制信息. ...

  7. MPSOC DP协议介绍

    一 DP介绍 1.1 DP介绍 DP协议(DisplayPort)是一种数字视频传输协议,用于连接计算机或其他设备与显示器或电视等显示设备.DP协议由VESA(Video Electronics St ...

  8. Wi-Fi Display协议介绍

    Wi-Fi Display协议介绍 Wi-Fi Display协议介绍 1.WFD架构 2.Source/Sink端 3.AV数据流模型 4.Session模型 5.WFD连接拓扑结构 5.1 WiF ...

  9. USB-IF介绍及标准下载

    USB-IF介绍及标准资料下载  USB Implementers Forum, Inc(USB-IF). 是一家非营利性公司,由开发通用串行总线规范的公司集团创立. USB-IF 的成立是为了为通用 ...

最新文章

  1. PyTorch 51.BatchNorm和Dropout层的不协调现象
  2. php连接oracle10g,php连接Oracle Database 10g Express Edition
  3. 比特币现金BCH今日事件
  4. java string 后几位_java中String占几个位元组
  5. 2、SQL的基本书写规则
  6. AuxreRP教学网站创始人郑建国:发挥Axure和原型真正的价值
  7. Android(3_2)-----模仿微信界面:通讯录页面
  8. The type sun.management.ManagementFactory is not visible
  9. asp.net winform 实现复制,粘贴,剪切功能
  10. Keras:Transfer learning
  11. Python_类的特殊成员方法
  12. EVENT:10218 dump uba of applied undo
  13. Repeater OnItemCommand 失效
  14. 32.卷1(套接字联网API)---IPv4,IPv6,ICMPv4 和 ICMPv6
  15. unity3d 挂载脚本_Unity3D加载资源的四种方式
  16. C语言编程题如何提交源程序,c语言课后习题源程序.doc
  17. 打造知识服务市场 知乎的变现之路
  18. python填充三角形颜色怎么输入_用Python填充三角形(海龟)
  19. POJ 1035 拼写检查
  20. bochs上网镜像怎么上网_bochs win7镜像可上网版-bochs WIN7 IMG镜像文件下载 v1.0完整版...

热门文章

  1. 江湖再见:毫米波雷达开发手册之行为识别应用
  2. 约瑟夫环运行结果截图 c语言,C语言单链表实现约瑟夫环
  3. Linux设备驱动程序学习(13)
  4. 计算机机房电气技术要求,机房UPS具体技术指标要求.doc
  5. Python 基础入门大合集,新手小白必看!
  6. 计算机网络实验环境介绍与基本操作,清华大学出版社-图书详情-《计算机网络实验教程》...
  7. 软件设计师备考 易错知识点(网络信息安全 法律法规)
  8. 《MOOC大学结束课程网址抓取小工具》
  9. Java毕设项目软考在线题库系统(java+VUE+Mybatis+Maven+Mysql)
  10. jasperreports的com.lowagie:itext:pom:2.1.7.js9找不到包问题解决