关于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*/
所以,關于串口端的設置,代碼如下:?
USART_InitTypeDef USART_InitStructure;USART_InitStructure.USART_BaudRate = 100000;?????????????????????? //設定傳輸速率USART_InitStructure.USART_WordLength = USART_WordLength_9b;??????? //設定傳輸數據位數USART_InitStructure.USART_StopBits = USART_StopBits_2;???????????? //設定停止位個數——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);????????????????????????? //初始化USART1USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);???????????????????? //使能USART1接收中斷USART_Cmd(USART1, ENABLE);???????????????????????????????????????? //使能USART12.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
編碼代碼如下:
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}; uint16_t ChValue[16]//通道數據,即遙控器發送過來的PWM //PWM轉SBUS// SBUS headersbus_data[0] = 0x0F;// 16 ChValue of 11 bit datasbus_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]? = (unsigned char) ((ChValue[2] & 0x07FF)>>10? | (ChValue[3] & 0x07FF)<<1);sbus_data[6]? = (unsigned char) ((ChValue[3] & 0x07FF)>>7?? | (ChValue[4] & 0x07FF)<<4);sbus_data[7]? = (unsigned char) ((ChValue[4] & 0x07FF)>>4?? | (ChValue[5] & 0x07FF)<<7);sbus_data[8]? = (unsigned char) ((ChValue[5] & 0x07FF)>>1);sbus_data[9]? = (unsigned char) ((ChValue[5] & 0x07FF)>>9?? | (ChValue[6] & 0x07FF)<<2);sbus_data[10] = (unsigned char) ((ChValue[6] & 0x07FF)>>6?? | (ChValue[7] & 0x07FF)<<5);sbus_data[11] = (unsigned char) ((ChValue[7] & 0x07FF)>>3);sbus_data[12] = (unsigned char) ((ChValue[8] & 0x07FF));sbus_data[13] = (unsigned char) ((ChValue[8] & 0x07FF)>>8?? | (ChValue[9] & 0x07FF)<<3);sbus_data[14] = (unsigned char) ((ChValue[9] & 0x07FF)>>5?? | (ChValue[10] & 0x07FF)<<6);?sbus_data[15] = (unsigned char) ((ChValue[10] & 0x07FF)>>2);sbus_data[16] = (unsigned char) ((ChValue[10] & 0x07FF)>>10 | (ChValue[11] & 0x07FF)<<1);sbus_data[17] = (unsigned char) ((ChValue[11] & 0x07FF)>>7? | (ChValue[12] & 0x07FF)<<4);sbus_data[18] = (unsigned char) ((ChValue[12] & 0x07FF)>>4? | (ChValue[13] & 0x07FF)<<7);sbus_data[19] = (unsigned char) ((ChValue[13] & 0x07FF)>>1);sbus_data[20] = (unsigned char) ((ChValue[13] & 0x07FF)>>9? | (ChValue[14] & 0x07FF)<<2);sbus_data[21] = (unsigned char) ((ChValue[14] & 0x07FF)>>6? | (ChValue[15] & 0x07FF)<<5);sbus_data[22] = (unsigned char) ((ChValue[15] & 0x07FF)>>3);// flagssbus_data[23] = 0x00;// footer sbus_data[24] = 0X00;對于編碼之后校驗的方面,我是通過編碼之后串口發送出去,用F4飛控來接收發送出來的SBUS信號,然后通過Betaflight Configurator來觀察SBUS信號是否規范
5.SBUS解碼
解碼代碼,經過修改并驗證后,SBUS信號發出后,用硬件取反接回單片機,接收配置上面有說過,值得注意的就是接收的數組不一定是從第一位開始的,所以需要簡單處理一下接收到的數據。檢驗的說固定遙控器發送的PWM值,然后發送過來解碼驗證看是否一樣即可。解碼代碼如下:
u16 buffer[25],channels[16];channels[0]? = ((buffer[1]??? |buffer[2]<<8)???????????????? & 0x07FF);channels[1]? = ((buffer[2]>>3 |buffer[3]<<5)???????????????? & 0x07FF);channels[2]? = ((buffer[3]>>6 |buffer[4]<<2 |buffer[5]<<10)? & 0x07FF);channels[3]? = ((buffer[5]>>1 |buffer[6]<<7)???????????????? & 0x07FF);channels[4]? = ((buffer[6]>>4 |buffer[7]<<4)???????????????? & 0x07FF);channels[5]? = ((buffer[7]>>7 |buffer[8]<<1 |buffer[9]<<9)?? & 0x07FF);channels[6]? = ((buffer[9]>>2 |buffer[10]<<6)??????????????? & 0x07FF);channels[7]? = ((buffer[10]>>5|buffer[11]<<3)??????????????? & 0x07FF);channels[8]? = ((buffer[12]?? |buffer[13]<<8)??????????????? & 0x07FF);channels[9]? = ((buffer[13]>>3|buffer[14]<<5)??????????????? & 0x07FF);channels[10] = ((buffer[14]>>6|buffer[15]<<2|buffer[16]<<10) & 0x07FF);channels[11] = ((buffer[16]>>1|buffer[17]<<7)??????????????? & 0x07FF);channels[12] = ((buffer[17]>>4|buffer[18]<<4)??????????????? & 0x07FF);channels[13] = ((buffer[18]>>7|buffer[19]<<1|buffer[20]<<9)? & 0x07FF);channels[14] = ((buffer[20]>>2|buffer[21]<<6)??????????????? & 0x07FF);channels[15] = ((buffer[21]>>5|buffer[22]<<3)??????????????? & 0x07FF);感謝來自wsptr【https://blog.csdn.net/wsptr/article/details/53795458】
以及?Bluish White【https://blog.csdn.net/qq_31232793/article/details/80244211】
總結
以上是生活随笔為你收集整理的关于SBUS信号在单片机中的一些个人理解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript——文档对象模型
- 下一篇: php三级栏目调用,织梦当前栏目调用二级