打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
关于SBUS信号在单片机中的一些个人理解

最近一直在弄关于SBUS的编码与解码这方面的内容,虽然网上资料很多,但是网上资料太杂,我找的一些资料可能是我理解的问题,所以我摒弃了一些骚操作,对于一些单片机学得不精的人来说,有些地方是值得注意的。

对于SBUS的探索,首先我个人是使用51芯片的遥控器通过NRF24L01发送遥控器PWM模拟量到一块STM32F030的接收机,在接收机内进行PWM转SBUS的操作,之后通过串口发送出SBUS信号,用F4飞控来连接串口发送出来的SBUS信号,并检验信号是否正确。(虽然这样挺麻烦的,但是检验起来很方便)

1.九位数据位、偶校验

SBUS本质是一种串口通信协议,采用100K的波特率,8位数据位,两位停止位,偶效验,即8E2的串口通信。

这里对于单片机学得不精的人来说特别容易搞混,波特率100000,两位停止位没什么问题。问题在于8位数据位,偶校验,这段话在单片机中却需要这样子表达9位数据位、偶校验对没有错是9位数据位、偶校验。刚开始编码的时候我就一直卡在了这里,F4的飞控一直识别不了我编码的SBUS信号。原因如下:

/*  如果需要8位数据,无奇偶校验,则数据长度=8

        如果需要8位数据,有奇偶校验,则数据长度=9*/

所以,关于串口端的设置,代码如下: 

  1. USART_InitTypeDef USART_InitStructure;
  2.   USART_InitStructure.USART_BaudRate = 100000;                       //设定传输速率
  3.   USART_InitStructure.USART_WordLength = USART_WordLength_9b;        //设定传输数据位数
  4.   USART_InitStructure.USART_StopBits = USART_StopBits_2;             //设定停止位个数——2位
  5.   USART_InitStructure.USART_Parity = USART_Parity_Even ;               //偶校验
  6.   USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不用流量控制
  7.   USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //使用接收和发送功能
  8.   USART_Init(USART1, &USART_InitStructure);                          //初始化USART1
  9.   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);                     //使能USART1接收中断
  10.   USART_Cmd(USART1, ENABLE);                                         //使能USART1

2.SBUS采用负逻辑

所以需要硬件取反才能识别出来,软件取反试过通过示波器观察与硬件取反并不是一致的(起始电平),具体解决方法和原因我没深查。所以需要输出SBUS信号必须硬件取反

电路如下,三极管使用8050就行

3.SBUS的两种工作模式

      高速模式:每4ms发送一次

      低速模式:每14ms发送一次

   就是说每间隔4或者14ms这个串口就发送25个字节的数据,高低速模式并不影响F4飞控对于SBUS信号的识别,所以只需设置多一个定时器定时发送SBUS信号即可。

100K的波特率不是标准波特率可以用单片机读取。我用F4飞控来识别单片机发出的SBUS信号之后在电脑端通过Betaflight Configurator来观察SBUS信号情况,能很直观的反映出SBUS信号是否正常

4.SBUS编码

帧格式【参考https://mbed.org/users/Digixx/notebook/futaba-s-bus-controlled-by-mbed/ 】

每帧25个字节,关于每帧的帧格式,我的理解就是第一帧为识别帧固定为:0x0F,然后最后两帧都为0x00

编码代码如下:

  1. uint8_t sbus_data[25]={0x0f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  2. uint16_t ChValue[16]//通道数据,即遥控器发送过来的PWM
  3. //PWM转SBUS
  4.     // SBUS header
  5.     sbus_data[0] = 0x0F;
  6.     // 16 ChValue of 11 bit data
  7.     sbus_data[1]  = (unsigned char) ((ChValue[0] & 0x07FF));
  8.     sbus_data[2]  = (unsigned char) ((ChValue[0] & 0x07FF)>>8   | (ChValue[1] & 0x07FF)<<3);
  9.     sbus_data[3]  = (unsigned char) ((ChValue[1] & 0x07FF)>>5   | (ChValue[2] & 0x07FF)<<6);
  10.     sbus_data[4]  = (unsigned char) ((ChValue[2] & 0x07FF)>>2);
  11.     sbus_data[5]  = (unsigned char) ((ChValue[2] & 0x07FF)>>10  | (ChValue[3] & 0x07FF)<<1);
  12.     sbus_data[6]  = (unsigned char) ((ChValue[3] & 0x07FF)>>7   | (ChValue[4] & 0x07FF)<<4);
  13.     sbus_data[7]  = (unsigned char) ((ChValue[4] & 0x07FF)>>4   | (ChValue[5] & 0x07FF)<<7);
  14.     sbus_data[8]  = (unsigned char) ((ChValue[5] & 0x07FF)>>1);
  15.     sbus_data[9]  = (unsigned char) ((ChValue[5] & 0x07FF)>>9   | (ChValue[6] & 0x07FF)<<2);
  16.     sbus_data[10] = (unsigned char) ((ChValue[6] & 0x07FF)>>6   | (ChValue[7] & 0x07FF)<<5);
  17.     sbus_data[11] = (unsigned char) ((ChValue[7] & 0x07FF)>>3);
  18.     sbus_data[12] = (unsigned char) ((ChValue[8] & 0x07FF));
  19.     sbus_data[13] = (unsigned char) ((ChValue[8] & 0x07FF)>>8   | (ChValue[9] & 0x07FF)<<3);
  20.     sbus_data[14] = (unsigned char) ((ChValue[9] & 0x07FF)>>5   | (ChValue[10] & 0x07FF)<<6); 
  21.     sbus_data[15] = (unsigned char) ((ChValue[10] & 0x07FF)>>2);
  22.     sbus_data[16] = (unsigned char) ((ChValue[10] & 0x07FF)>>10 | (ChValue[11] & 0x07FF)<<1);
  23.     sbus_data[17] = (unsigned char) ((ChValue[11] & 0x07FF)>>7  | (ChValue[12] & 0x07FF)<<4);
  24.     sbus_data[18] = (unsigned char) ((ChValue[12] & 0x07FF)>>4  | (ChValue[13] & 0x07FF)<<7);
  25.     sbus_data[19] = (unsigned char) ((ChValue[13] & 0x07FF)>>1);
  26.     sbus_data[20] = (unsigned char) ((ChValue[13] & 0x07FF)>>9  | (ChValue[14] & 0x07FF)<<2);
  27.     sbus_data[21] = (unsigned char) ((ChValue[14] & 0x07FF)>>6  | (ChValue[15] & 0x07FF)<<5);
  28.     sbus_data[22] = (unsigned char) ((ChValue[15] & 0x07FF)>>3);
  29.     // flags
  30.     sbus_data[23] = 0x00;
  31.     // footer
  32. sbus_data[24] = 0X00;

对于编码之后校验的方面,我是通过编码之后串口发送出去,用F4飞控来接收发送出来的SBUS信号,然后通过Betaflight Configurator来观察SBUS信号是否规范

5.SBUS解码

解码代码,经过修改并验证后,SBUS信号发出后,用硬件取反接回单片机,接收配置上面有说过,值得注意的就是接收的数组不一定是从第一位开始的,所以需要简单处理一下接收到的数据。检验的说固定遥控器发送的PWM值,然后发送过来解码验证看是否一样即可。解码代码如下:

  1. u16 buffer[25],channels[16];
  2. channels[0]  = ((buffer[1]    |buffer[2]<<8)                 & 0x07FF);
  3.     channels[1]  = ((buffer[2]>>3 |buffer[3]<<5)                 & 0x07FF);
  4.     channels[2]  = ((buffer[3]>>6 |buffer[4]<<2 |buffer[5]<<10)  & 0x07FF);
  5.     channels[3]  = ((buffer[5]>>1 |buffer[6]<<7)                 & 0x07FF);
  6.     channels[4]  = ((buffer[6]>>4 |buffer[7]<<4)                 & 0x07FF);
  7.     channels[5]  = ((buffer[7]>>7 |buffer[8]<<1 |buffer[9]<<9)   & 0x07FF);
  8.     channels[6]  = ((buffer[9]>>2 |buffer[10]<<6)                & 0x07FF);
  9.     channels[7]  = ((buffer[10]>>5|buffer[11]<<3)                & 0x07FF);
  10.     channels[8]  = ((buffer[12]   |buffer[13]<<8)                & 0x07FF);
  11.     channels[9]  = ((buffer[13]>>3|buffer[14]<<5)                & 0x07FF);
  12.     channels[10] = ((buffer[14]>>6|buffer[15]<<2|buffer[16]<<10) & 0x07FF);
  13.     channels[11] = ((buffer[16]>>1|buffer[17]<<7)                & 0x07FF);
  14.     channels[12] = ((buffer[17]>>4|buffer[18]<<4)                & 0x07FF);
  15.     channels[13] = ((buffer[18]>>7|buffer[19]<<1|buffer[20]<<9)  & 0x07FF);
  16.     channels[14] = ((buffer[20]>>2|buffer[21]<<6)                & 0x07FF);
  17.     channels[15] = ((buffer[21]>>5|buffer[22]<<3)                & 0x07FF);

感谢来自wsptrhttps://blog.csdn.net/wsptr/article/details/53795458

以及 Bluish Whitehttps://blog.csdn.net/qq_31232793/article/details/80244211

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
利用单片机通过ESP8266把DHT11温湿度数据进行从发主机接收信息
基于STM32单片机开发光学指纹识别模块(FPM10A)全教程
STM32 串口读写迪文屏8位、16位、32位数据(应用层实现)
例子 | 环形队列来实现串口数据接收
STM32串口发送数据和接收数据方式总结
纯手工打造摇摆LED时钟(2)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服