STM32 Futaba SBUS协议解析
STM32 Futaba SBUS協議解析
- 1. S.BUS
- 1.1 協議介紹
- 1.2 協議解析
- 2. 硬件設計
- 2.1 硬件參數
- 2.2 反相電路
- 3.程序設計
- 3.1 數據接收
- 3.2 數據處理
- 4. 最后
1. S.BUS
1.1 協議介紹
S.BUS是FUTABA提出的舵機控制總線,全稱Serial Bus,別名S-BUS或SBUS,也稱 Futaba S.BUS。
S.BUS是一個串行通信協議,也是一個數字串行通信接口(單線),適合與飛控連接。它可以連接很多設備,每個設備通過一個HUB與它相連,得到各自的控制信息。
S.BUS可以傳輸16個比例通道和2個數字(bool)通道。其硬件上基于RS232協議,采用TTL電平,但高位取反(負邏輯,低電平為“1”,高電平為“0”),通信波特率為100K(不兼容波特率115200)。
1.2 協議解析
| 類型 | 開始字節 | 通道數據字節(含16個脈寬通道) | 標志位字節(含2個數字通道) | 結束字節 |
| 數據 | 0x0F | 通道數據范圍11Bits = [0,2047] | 2個數字通道位+2個狀態位 | 0x00 |
byte1:
startbyte = 0000 1111b (0x0F)
byte2-23:
databytes = 22bytes = 22 x 8Bits = 16 x 11Bits(CH1-16)
通道數據低位在前,高位在后,每個數據取11位,具體協議如下:
讀取的databyte值:
| 內容 | 12345678 | 12345678 | 12345678 | 12345678 | 12345678 | 12345678 | etc |
轉化后的通道值:
| 內容 | 67812345678 | 34567812345 | 81234567812 | 56781234567 | etc |
byte24:
| 含義 | 數字通道CH17 | 數字通道CH18 | 幀丟失位 | 故障保護激活位 | N/A | N/A | N/A | N/A |
byte25:
endbyte = 0000 0000b (0x00)
2. 硬件設計
2.1 硬件參數
2.2 反相電路
由于此芯片串口不帶反相器,我們需要外部搭建反相電路。如果芯片串口內部帶反相器,可以省略此步。反相電路設計如下圖:
3.程序設計
3.1 數據接收
分析一:根據 1.2 的協議解析,開始字節(0x0F)和結束字節(0x00)都是數據字節中很容易出現的字節,所以不能完全作為數據幀接收開始和結束的標志。
分析二:每個數據幀之間的間隔至少4ms,則可以利用這個空閑時間來接收數據幀。(需要設計一個系統時鐘)
分析三:STM32 USART或UART有空閑中斷,即檢測到總線空閑(無數據傳輸),就產生中斷。
接收程序設計:綜上,利用USART2接收中斷(RXNE)來接收每個字節,利用USART2空閑中斷(IDLE)來判斷數據幀是否接收完畢。
USART2 初始化函數代碼如下:
/*** @name SBUS_Configuration* @brief Configure SBUS(Usart2) clock, gpio and nvic:* SBUS_RX USART2_RX PD6* @param None* @retval None*/ void SBUS_Configuration(void) {GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOD, &GPIO_InitStructure);GPIO_PinRemapConfig(GPIO_Remap_USART2, ENABLE);// 波特率100000 8個數據位 偶校驗位 2個停止位USART_InitStructure.USART_BaudRate = 100000;USART_InitStructure.USART_WordLength = USART_WordLength_8b;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_Init(USART2, &USART_InitStructure);NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);USART_Cmd(USART2, ENABLE); }USART2 中斷函數代碼如下:
uint8_t USART2_RX_BUF[26];/*** @name USART2_IRQHandler* @brief This function handles USART2 Handler* @param None* @retval None*/ void USART2_IRQHandler(void) {uint8_t res;uint8_t clear = 0;static uint8_t Rx_Sta = 1;if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET){res =USART2->DR;USART2_RX_BUF[Rx_Sta++] = res;}else if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET){clear = USART2->SR;clear = USART2->DR;USART2_RX_BUF[0] = Rx_Sta - 1;Rx_Sta = 1;} }3.2 數據處理
直接上代碼:
uint16_t CH[18]; // 通道值 uint8_t rc_flag = 0;void Sbus_Data_Count(uint8_t *buf) {CH[ 0] = ((int16_t)buf[ 2] >> 0 | ((int16_t)buf[ 3] << 8 )) & 0x07FF;CH[ 1] = ((int16_t)buf[ 3] >> 3 | ((int16_t)buf[ 4] << 5 )) & 0x07FF;CH[ 2] = ((int16_t)buf[ 4] >> 6 | ((int16_t)buf[ 5] << 2 ) | (int16_t)buf[ 6] << 10 ) & 0x07FF;CH[ 3] = ((int16_t)buf[ 6] >> 1 | ((int16_t)buf[ 7] << 7 )) & 0x07FF;CH[ 4] = ((int16_t)buf[ 7] >> 4 | ((int16_t)buf[ 8] << 4 )) & 0x07FF;CH[ 5] = ((int16_t)buf[ 8] >> 7 | ((int16_t)buf[ 9] << 1 ) | (int16_t)buf[10] << 9 ) & 0x07FF;CH[ 6] = ((int16_t)buf[10] >> 2 | ((int16_t)buf[11] << 6 )) & 0x07FF;CH[ 7] = ((int16_t)buf[11] >> 5 | ((int16_t)buf[12] << 3 )) & 0x07FF;CH[ 8] = ((int16_t)buf[13] << 0 | ((int16_t)buf[14] << 8 )) & 0x07FF;CH[ 9] = ((int16_t)buf[14] >> 3 | ((int16_t)buf[15] << 5 )) & 0x07FF;CH[10] = ((int16_t)buf[15] >> 6 | ((int16_t)buf[16] << 2 ) | (int16_t)buf[17] << 10 ) & 0x07FF;CH[11] = ((int16_t)buf[17] >> 1 | ((int16_t)buf[18] << 7 )) & 0x07FF;CH[12] = ((int16_t)buf[18] >> 4 | ((int16_t)buf[19] << 4 )) & 0x07FF;CH[13] = ((int16_t)buf[19] >> 7 | ((int16_t)buf[20] << 1 ) | (int16_t)buf[21] << 9 ) & 0x07FF;CH[14] = ((int16_t)buf[21] >> 2 | ((int16_t)buf[22] << 6 )) & 0x07FF;CH[15] = ((int16_t)buf[22] >> 5 | ((int16_t)buf[23] << 3 )) & 0x07FF; }接收到的報文和解析出來的數據如下:
RX:0F E0 03 1F 58 C0 07 16 B0 80 05 2C 60 01 0B F8 C0 07 00 00 00 00 00 03 00
CH: 992 992 352 992 352 352 352 352 352 352 992 992 000 000 000 000
RX:0F 60 01 0B 58 C0 07 66 30 83 19 7C 60 06 1F F8 C0 07 00 00 00 00 00 03 00
CH: 352 352 352 992 1632 1632 1632 992 1632 992 992 992 000 000 000 000
4. 最后
????本教程由 Brendon Tan 原創發布,版權所有。該文檔僅供個人學習交流使用,不得用于其他用途,禁止商用, 轉載或公開使用請聯系作者授權。
????此教程由本人獨立整理,如有不當之處,歡迎指正。
該協議解析參考Futaba S-BUS controlled by mbed[Uwe Gartmann,Created 07 Mar 2012,Last updated 09 Mar 2012] ??
某貓鏈接walkera RX-SBUS[Copied May 2012] ??
總結
以上是生活随笔為你收集整理的STM32 Futaba SBUS协议解析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: svn回退到指定版本idea版
- 下一篇: Datawhale组队-Pandas(下