R9DS接收機SMBUS數據解析

1常見模型控制信號

模型遙控器接收機輸出的信號常見有三種:PWM、PPM、SBUS。

PWM信號優點是模型都有成熟的PWM控制的配套模塊,如舵機、電調大部分都是PWM接口的,同樣也存在很明顯的缺點,第一是連線較多,每個通道至少需要1根線,第二是PWM信號是以高電平的時間作爲控制信號,電平邊沿容易受到干擾,造成錯誤的控制。

PPM可以理解成在一根線輸出多組PWM信號,缺點顯而易見和PWM信號一樣,優點是少了不少線。

SBUS是兩線制通信,需要信號線和地線即可,本質還是串口,此文重點介紹SBUS信號的電路、協議。

2 SBUS電路

SBUS電平本質是串口TTL電平,實質呢,電平和串口TTL是相反的,Futaba制定這個協議的時候有可能是爲了規避專利,也有可能是爲了裝X……,給我們帶來的問題就是需要電平轉換電路,可以用2個電阻1個三極管實現,還用更簡單的用1片74系列的單路反向芯片,本例中用的是三極管電阻方式,沒有現成的板子臨時搭個電路實驗,本文以R9DS接收機、STM32F1XX測試,電路圖、實物圖如下:

       

                          電路原理圖                                                  電路實物                                               反向效果圖

OK,電路問題解決了,下面開始讀取數據

3 接收數據

Futaba官網說的很清楚:

The protocol is 25 Byte long and is send every 14ms (analog mode) or 7ms (highspeed mode).
One Byte = 1 startbit + 8 databit + 1 paritybit + 2 stopbit (8E2), baudrate = 100'000 bit/s
The highest bit is send first. The logic is inverted (Level High = 1)

翻譯出來是這樣的:一幀數據由25個字節構成,低速模式週期爲14ms,高速模式週期爲7ms,1個字節有1個起始位8個數據位1個校驗位2個停止位構成,波特率爲100K,高位在前低位在後,注意:電平是反的。

串口配置如下:

  Uart_Init(COMM1,100000,USART_WordLength_8b, USART_Parity_Even);  

串口接收中斷:

void SBUS_RX_ISR(void)

{
  INT8U res;
  static INT8U Rx_Sta = 0;

  if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)
  {
    res =USART_ReceiveData(USART1);
    SbusRxBuf[Rx_Sta++] = res;
  }
  else if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)
  {
    USART_ReceiveData(USART1);
    Rx_Sta = 0;
  }
}

調試數據可以接收:

4數據解析

接收的數據和通道值是怎麼個對應關係呢,Futaba官網接收如下:

[startbyte] [data1] [data2] .... [data22] [flags][endbyte]

startbyte = 11110000b (0xF0)

data 1-22 = [ch1, 11bit][ch2, 11bit] .... [ch16, 11bit] (ch# = 0 bis 2047)
channel 1 uses 8 bits from data1 and 3 bits from data2
channel 2 uses last 5 bits from data2 and 6 bits from data3
etc.

flags = bit7 = ch17 = digital channel (0x80)
bit6 = ch18 = digital channel (0x40)
bit5 = Frame lost, equivalent red LED on receiver (0x20)
bit4 = failsafe activated (0x10)
bit3 = n/a
bit2 = n/a
bit1 = n/a
bit0 = n/a

endbyte = 00000000b

一幀數據由1字節起始字節0xf0,22字節的通道數據,1字節標誌位,1字節結束字節構成,總共25個字節,22個字節可以傳輸22*8/11=16通道數據,數據範圍爲0-2047。標誌位的用R9DS沒測試出Futaba協議中介紹的含義,有可能協議不兼容。

,遙控器關閉沒信號時候,SbusRxBuf[24]接收數據位0xc0,,打開遙控器有信號時,SbusRxBuf[24]字節爲0x00,可以用來做失控判斷。

16通道數據解析如下:

void Sbus_Data_Count(INT8U *buf)
{
  SbusCh[ 0] = ((INT16U)buf[ 1] >> 0 | ((INT16U)buf[ 2] << 8 )) & 0x07FF;
  SbusCh[ 1] = ((INT16U)buf[ 2] >> 3 | ((INT16U)buf[ 3] << 5 )) & 0x07FF;
  SbusCh[ 2] = ((INT16U)buf[ 3] >> 6 | ((INT16U)buf[ 4] << 2 )  | (INT16U)buf[ 5] << 10 ) & 0x07FF;
  SbusCh[ 3] = ((INT16U)buf[ 5] >> 1 | ((INT16U)buf[ 6] << 7 )) & 0x07FF;
  SbusCh[ 4] = ((INT16U)buf[ 6] >> 4 | ((INT16U)buf[ 7] << 4 )) & 0x07FF;
  SbusCh[ 5] = ((INT16U)buf[ 7] >> 7 | ((INT16U)buf[ 8] << 1 )  | (INT16U)buf[9] <<  9 ) & 0x07FF;
  SbusCh[ 6] = ((INT16U)buf[9] >> 2 | ((INT16U)buf[10] << 6 )) & 0x07FF;
  SbusCh[ 7] = ((INT16U)buf[10] >> 5 | ((INT16U)buf[11] << 3 )) & 0x07FF;
  SbusCh[ 8] = ((INT16U)buf[12] << 0 | ((INT16U)buf[13] << 8 )) & 0x07FF;
  SbusCh[ 9] = ((INT16U)buf[13] >> 3 | ((INT16U)buf[14] << 5 )) & 0x07FF;
  SbusCh[10] = ((INT16U)buf[14] >> 6 | ((INT16U)buf[15] << 2 )  | (INT16U)buf[17] << 10 ) & 0x07FF;
  SbusCh[11] = ((INT16U)buf[16] >> 1 | ((INT16U)buf[17] << 7 )) & 0x07FF;
  SbusCh[12] = ((INT16U)buf[17] >> 4 | ((INT16U)buf[18] << 4 )) & 0x07FF;
  SbusCh[13] = ((INT16U)buf[18] >> 7 | ((INT16U)buf[19] << 1 )  | (INT16U)buf[21] <<  9 ) & 0x07FF;
  SbusCh[14] = ((INT16U)buf[20] >> 2 | ((INT16U)buf[21] << 6 )) & 0x07FF;
  SbusCh[15] = ((INT16U)buf[21] >> 5 | ((INT16U)buf[22] << 3 )) & 0x07FF;
  yy = (INT16U)(0.6056*SbusCh[0]+895);
}

yy = (INT16U)(0.6056*SbusCh[0]+895);是y=ax+b的形式,實現SBUS數據與PWM脈寬的轉換,轉向係數a、b根據程序實際讀到的數據和示波器讀到的脈寬計算出來,就是個2點直線方程。

在10ms定時器中調用Sbus_Data_Count(SbusRxBuf);就可以計算出16個通道的數據,R9DS只能支持收到10個通道數據。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章