天天看點

Android藍牙序列槽程式開發

本文主要介紹了針對android的藍牙序列槽上位機開發。

程式下載下傳位址:點選打開連結

一、幀定義

androidclient依照一定的資料幀格式通過藍牙序列槽發送資料到連接配接到MCU的藍牙從機。MCU接收到資料後。依照幀格式的定義,接收資料幀。并解析資料幀,得到須要的資料。

androidclient依照下面幀格式來發送和接收資料。

Android藍牙序列槽程式開發
Android藍牙序列槽程式開發

1.1client發送的資料幀内容

發送頻率:10Hz

Android藍牙序列槽程式開發
Android藍牙序列槽程式開發

幀校驗的和是從幀長開始到幀校驗前全部資料的和對256取餘。

即sum%256。

pitch roll yaw資料各16位,由高低8位組成。MCU接收資料時須要将其再複合成一個16位資料。

0x5A:幀頭

14:針長度

0xA1:幀功能,标明這幀資料是pitch yaw roll内容。

pitch_set_H:pitch高8位

pitch_set_L:pitch低8位

...

幀校驗:(幀長+幀功能+資料)%256

0xA5:幀尾。

(注:幀是這麼定義的,但實際上編寫接收程式的時候。我将幀尾0xA5當作了一幀資料的幀頭。

這樣幀頭就變成了 0xA5 0x5A。此時就不存在幀尾了)

以下是androidclient發送位元組資訊的程式:

<span style="white-space:pre">	</span>b[0] = (byte)0XA5;  //幀頭
         b[1] = (byte)14;     //幀長
         b[2] = (byte)0xA1;   //幀功能
        
         b[3] = (byte)(pitchSet>>8);     //資料
         b[4] = (byte)(pitchSet);
         b[5] = (byte)(rollSet>>8);
         b[6] = (byte)(rollSet);
         b[7] = (byte)(yawSet>>8);
         b[8] = (byte)(yawSet);
         b[9] = (byte)0;
         b[10] = (byte)0;
         b[11] = (byte)0;
         b[12] = (byte)0;
        
         int temp = 0;
         for(int j=1;j<13;j++)
         {
         temp = temp+b[j];
         }
         b[13] = (byte)(temp%256);  //校驗     
        b[14] = (byte)0x5A;     //幀結束
      

1.2MCU接收幀資料

因為序列槽是依照一個一個位元組的格式發送資料,是以MCU接收資料時,要依照client發送的幀格式的定義。找到一幀資料的開始與結束,确認一幀資料接收無誤後,再将當中的資料解析出來。

使用一個為來标志(狀态機)接收程式對一陣資料的接收狀态。

編寫的DSP2808接收程式例如以下:

定義資料類型

typedef struct
{
	int status;   //data status
	int Rx_Data;	 //the receivced data
	int data[15];	//
	int rx_buf[13];
	int buf_index;
	int sum;
	int yawSet;
	int pitchSet;
	int rollSet;
}Sci_Data;
Sci_Data sci_data;
      
interrupt void SCIB_RX_ISR()          //以中斷的方式接收資料
{
//接收程式
	sci_data.Rx_Data = ScibRegs.SCIRXBUF.all;        
	ScibRegs.SCIFFRX.bit.RXFFOVRCLR = 1;  //clear overflow flag
	ScibRegs.SCIFFRX.bit.RXFFINTCLR = 1;   //clear the interrupt flag
	PieCtrlRegs.PIEACK.all |= PIEACK_GROUP9;  //enable more interrupt from PIE group 9
	Decode_Frame(sci_data.Rx_Data);          //資料幀解碼
}

void Decode_Frame(int rx_data)
{
	if(sci_data.status==0 && rx_data == 0x5A)   //推斷幀尾 假設找到幀尾,status=1
	{
		sci_data.status = 1;
	}
	else if(sci_data.status == 1 &&rx_data == 0xA5)      //幀尾下一個字元是幀頭。status=2

	{
		sci_data.status = 2;
	}
	else if(sci_data.status ==2) //幀頭後是13個位元組資料 從幀長到幀校驗
	{
		if(sci_data.buf_index<13)
		{
			
			sci_data.rx_buf[sci_data.buf_index] = rx_data;        //  0-12 to save data length function data... sum		
			if(sci_data.buf_index<12) //求取校驗和
			{
				sci_data.sum += sci_data.rx_buf[sci_data.buf_index];
			}

			sci_data.buf_index++;
		}
		
		if(sci_data.buf_index >= 13)
		{
			if(sci_data.rx_buf[12] == sci_data.sum%256)
			{
				int j=0;
				for(j=0;j<10;j++)
				{
					sci_data.data[j] = sci_data.rx_buf[j+2];    //save data to the data buf
					
				
				}
				sci_data.pitchSet = sci_data.data[0]<<8|sci_data.data[1];

			}
			sci_data.buf_index = 0;
			sci_data.status = 0;
			sci_data.sum = 0;
		}
	}
	else 
	{
		sci_data.buf_index = 0;
		sci_data.status = 0;
		sci_data.sum = 0;
	}
}
      

這樣DSP2808就接收到了從client發送來的資料。儲存在sci_data.pitchSet、sci_data.rollSet、sci_data.yawSet三個變量中。 

二、androidclient開發流程

問題:檢測藍牙的連接配接狀态

android藍牙序列槽程式狀态機

在程式中,通過broadcast來檢測藍牙的連接配接狀态,根絕藍牙的連接配接狀态來決定操作。

打開藍牙---掃描裝置---選擇裝置---連接配接裝置---連接配接正常---發送資料---