SIYI AK28 遥控器接收机的SBUS口与STM32通讯
SBUS介紹
SBUS是Futaba公司定義的一種串口通信協議,Futaba的產品應用越來越廣泛,不論是航模,無人機,還是機器人,遙控車,總能有它的身影。SBUS是一個接收機串行總線輸出,通過這根總線,可以獲得遙控器上所有通道的數據。目前很多模型及無人機電子設備都支持SBUS總線的接入。使用SBUS總線獲取通道數據,效率高的,而且節省硬件資源,只需要一根線即可獲取所有通道的數據。
官網網址:
硬件介紹
和TTL串口信號相比,sbus的邏輯電平是反的,并且是硬件取反,軟件取反是無效的;硬件取反的電路圖如下:
協議介紹
串口配置為波特率100kbps,8位數據,偶校驗(even),2位停止位,無流控。
鏈接https://mbed.org/users/Digixx/notebook/futaba-s-bus-controlled-by-mbed/說明了S-bus幀格式。每幀25個字節,按照如下順序排列:
[startbyte] [data1] [data2] … [data22] [flags][endbyte]
起始字節startbyte = 11110000b (0xF0),但實際上STM32(ARM核)收到的是0x0F。中間22個字節就是16個通道的數據了,為什么是16個通道?因為22x8=11x16,每個通道用11bit表示,范圍是0-2047。波形圖如下:
基本而言,data1為ch1的低8位,data2的低3位為ch1的高三位,data2的高5位是ch2的低5位,data3的低6位是ch2的高6位,以此類推,如下圖所示:
代碼介紹
sbus.c#include "sbus.h"==說明:我所用的遙控器通過推動搖桿得到的最小值是193、中間值是993、最大值是1793==#define RC_CHANNEL_MIN (-800)#define RC_CHANNEL_MAX 800#define SBUS_MIN_OFFSET 193#define SBUS_MID_OFFSET 993#define SBUS_MAX_OFFSET 1793/***@brief 這是一個C語言版的MAP函數(映射函數)*@param val:實際通道值; I_Min:輸入最小值; I_Max:輸入最大值;O_Min:輸出最小值;O_Max:輸出最大值*@retval 實際輸出值;*@note none*/int output[16]={0};float map(float val, float I_Min, float I_Max, float O_Min, float O_Max){return(((val-I_Min)*((O_Max-O_Min)/(I_Max-I_Min)))+O_Min);}/***@brief 協議轉換*@param none*@retval none*@note none*/void sbusPreparePacket(void){uint16_t SBUS_channels[16]={0};if(Usart6_rx_buffer[0]==0x0f&& Usart6_rx_buffer[24]==0x00) //校驗收到的數據是否正確{SBUS_channels[0] = (( Usart6_rx_buffer[1]| Usart6_rx_buffer[2]<<8) & 0x07FF);SBUS_channels[1] = (( Usart6_rx_buffer[2]>>3 | Usart6_rx_buffer[3]<<5) & 0x07FF);SBUS_channels[2] = (( Usart6_rx_buffer[3]>>6 | Usart6_rx_buffer[4]<<2 | Usart6_rx_buffer[5]<<10) & 0x07FF);SBUS_channels[3] = (( Usart6_rx_buffer[5]>>1 | Usart6_rx_buffer[6]<<7) & 0x07FF);SBUS_channels[4] = (( Usart6_rx_buffer[6]>>4 | Usart6_rx_buffer[7]<<4) & 0x07FF);SBUS_channels[5] = (( Usart6_rx_buffer[7]>>7 | Usart6_rx_buffer[8]<<1 | Usart6_rx_buffer[9]<<9) & 0x07FF) ;SBUS_channels[6] = (( Usart6_rx_buffer[9]>>2 | Usart6_rx_buffer[10]<<6) & 0x07FF) ;SBUS_channels[7] = (( Usart6_rx_buffer[10]>>5| Usart6_rx_buffer[11]<<3) & 0x07FF) ;SBUS_channels[8] = (( Usart6_rx_buffer[12] | Usart6_rx_buffer[13]<<8) & 0x07FF) ;SBUS_channels[9] = (( Usart6_rx_buffer[13]>>3| Usart6_rx_buffer[14]<<5) & 0x07FF) ;SBUS_channels[10] = (( Usart6_rx_buffer[14]>>6| Usart6_rx_buffer[15]<<2| Usart6_rx_buffer[16]<<10) & 0x07FF) ;SBUS_channels[11] = (( Usart6_rx_buffer[16]>>1| Usart6_rx_buffer[17]<<7) & 0x07FF) ;SBUS_channels[12] = (( Usart6_rx_buffer[17]>>4| Usart6_rx_buffer[18]<<4) & 0x07FF) ;SBUS_channels[13] = (( Usart6_rx_buffer[18]>>7| Usart6_rx_buffer[19]<<1| Usart6_rx_buffer[20]<<9) & 0x07FF) ;SBUS_channels[14] = (( Usart6_rx_buffer[20]>>2| Usart6_rx_buffer[21]<<6) & 0x07FF) ;SBUS_channels[15] = (( Usart6_rx_buffer[21]>>5| Usart6_rx_buffer[22]<<3) & 0x07FF) ;}else {SBUS_channels[2]=993;SBUS_channels[3]=993; }for(char i=0;i<16;i++){output[i]=map(SBUS_channels[i],SBUS_MIN_OFFSET,SBUS_MAX_OFFSET, RC_CHANNEL_MIN, RC_CHANNEL_MAX); //具體到通道值}}/***@brief 輸出PWM(混控)*@param offset_y:實際通道1的值;offset_x:實際通道2的值;c:給定常數*@retval none*@note none*///應用到具體的通道 實現pwm輸出//以通道3為y軸,通道4為x軸int a,b, pwm1_channels[2]={0};void PWM_Out(int offset_y,int offset_x,float c ){ sbusPreparePacket();if(offset_y>=0){a=(c*offset_y*offset_y+800*offset_x)/(800+c*offset_y); //電機1b=(c*offset_y*offset_y-800*offset_x)/(800+c*offset_y); //電機2pwm1_channels[0]=map(a,0,800,1500,2000);pwm1_channels[1]=map(b,0,800,1500,2000);}if(offset_y<0){a=(1-2*0.25)*offset_y-0.25*(100+offset_x);b=(1-2*0.25)*offset_y-0.25*(100-offset_x);pwm1_channels[0]=map(a,-800,0,1000,1500);pwm1_channels[1]=map(b,-800,0,1000,1500);}pwm_out1( pwm1_channels[0]);pwm_out2( pwm1_channels[1]);} sbus.h#ifndef __SBUS_H#define __SBUS_H#include "main.h"#include "usart.h"#include "tim.h"#include <stdbool.h>extern int output[16];#define pwm_out1(pwm) __HAL_TIM_SET_COMPARE(&htim15,TIM_CHANNEL_1,pwm)#define pwm_out2(pwm) __HAL_TIM_SET_COMPARE(&htim15,TIM_CHANNEL_2,pwm) uint16_t PWM_OUT1(uint16_t pwm_channel);uint16_t PWM_OUT2(uint16_t pwm_channel);float map(float val, float I_Min, float I_Max, float O_Min, float O_Max);void sbusPreparePacket(void);void GET_SBUSDATA(void);void sbus_control(void);void PWM_Out(int offset_y,int offset_x,float c );#endif完結
總結
以上是生活随笔為你收集整理的SIYI AK28 遥控器接收机的SBUS口与STM32通讯的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python决策树id3算法_pytho
- 下一篇: NILMTK——因子隐马尔可夫之隐马尔可