[C#] 編程控制筆記本藍牙與外部藍牙設備通訊

 

1、藍牙模塊XLBT232‐D01介紹(外部設備藍牙)html

1.一、藍牙模塊簡介編程

XLBT232-D0101藍牙模塊採用CSR BlueCore 芯片,配置6-8Mbit 的軟件存儲空間,
支持AT 指令,用戶可根據須要更改SPP 角色(主、從模式)以及串口波特率、
設備名稱、配對密碼等參數,使用靈活。安全

 

1.二、模塊功能介紹併發

1.2.一、特性ide

  •  藍牙協議:Bluetooth Specification V2.1+EDR、V2.0+EDR、V2.一、V2.0 V1.2
  • — 工做頻率:2.4GHz ISM band
  • — 調製方式:GFSK(Gaussian Frequency Shift Keying)
  • — 發射 率:≤4dBm, Class 2
  • — 靈 敏 度:≤-84dBm at 0.1% BER
  • — 傳輸速率:Asynchronous: 2.1Mbps(Max) / 160 kbpsSynchronous: 1Mbps/1Mbps
  • — 安全特性:Authentication and encryption
  • — 支持服務:Bluetooth SPP(主模式& 從模式)
  • — 供電電源:+3.3VDC 50mA
  • — 工做溫度:-5 ~ +65 Centigrade
  • — 外觀尺寸:26.9mm x 13mm x 2.2 mm

1.2.二、模塊接線原理圖函數

PS:固然也能用USB轉TTL模塊進行鏈接在電腦上調試,畢竟大多數筆記本已經沒有串口啦!測試

 

1.三、使用說明ui

[圖:藍牙模塊]spa

>_<" KEY爲輸入管腳,短按控制,或者輸入約100ms 的高電平單次脈衝,能夠
實現如下功能:3d

  • 模塊設置爲SPP 主機模式時:

    未鏈接狀態時:清除配對信息(若存在配對設備信息)

    已鏈接狀態時:主動發起斷開鏈接,延時150ms 後重啓,從新搜索
  鏈接從設備; 在斷開鏈接時:從新搜索鏈接從設備。

  • 模塊設置爲SPP 從機時:

    在已鏈接狀態時:主動發起斷開鏈接,延時150ms 後重啓,從新進入被搜
     索狀態,等待主機配對和鏈接

    在斷開鏈接時:延時150ms 後重啓,從新進入被搜索狀態,等待主機配對
     和鏈接。

>_<" 顯示模塊當前工做狀態:

  • 待機狀態慢閃——重複2s 脈衝;
  • 鏈接狀態長亮——高電平。

 

1.四、AT指令集

藍牙模塊出廠默認的串口配置爲:波特率9600,無校驗,數據位8,中止位1。
PS:接下來講明以上位機爲電腦,模塊參數爲出廠設置時進行配置說明。
>_<" 將模塊經過USB電平轉換板鏈接到電腦USB口(USB轉TTL),使用串口調試助手,按
照 9600,N,8,1 進行配置,打開串口後,發送 AT(無\r\n),若返回 OK,說明配置
成功。
PS:設置 AT 指令必須在藍牙模塊未鏈接或斷開 SPP 連接時才能夠(上電或配對
後均可以,若是鏈接 SPP,串口輸入的數據將會直接發送到遠端藍牙設備串口)

1.4.一、測試指令:

1.4.二、查詢\設置波特率指令:

1.4.三、查詢\設置設備名稱指令:

1.4.四、恢復默認設置指令:

1.4.五、模塊復位\重啓指令:

1.4.六、查詢\設置主從模式:

1.4.七、查詢\設置配對密碼:

1.4.八、查詢\設置是否須要密碼鑑權:

PS:爲方便使用,默認爲不用密碼鑑權鏈接,搜索到藍牙串口以後,直接鏈接
可。有安全考慮的客戶請選擇須要密碼鑑權。
PS:此指令只有在從設備時纔有效;主設備時不接受此指令,發送此指令沒
有回覆,也不執行

1.4.九、清除主設備配對信息指令:

PS:此指令只有在主設備時纔有效;從設備時不接受此指令,發送此指令
沒有回覆,也不執行。

1.4.十、搜索並鏈接新的藍牙串口從設備(*)指令:

PS:此指令只有在主設備時纔有效;從設備時不接受此指令,發送此指令沒
有回覆,也不執行。

1.4.十一、鏈接最後一次鏈接的藍牙串口從設備(*)指令:

PS:此指令只有在主設備時纔有效;從設備時不接受此指令,發送此指令沒
有回覆,也不執行。

1.4.十二、鏈接指定藍牙地址的從設備(*)指令:

PS:此指令只有在主設備時纔有效;從設備時不接受此指令,發送此指令沒
有回覆,也不執行。

1.4.1三、查詢、設置軟件版本指令:

1.4.1四、系統幫助指令:

1.4.1五、查詢本機MAC 地址指令:

>_<: 1:全部參數設置後存儲在模塊內,下次啓動時無需再次設置
         2:AT 指令後標註*號的,表示目前未應用的AT 指令

 

 

2、藍牙模塊配置與筆記本電腦相連

2.1.一、藍牙初始化配置:

將藍牙模塊經過TTL轉USB模塊鏈接到筆記本,打開串口助手,經過上述AT指令設置爲從設備,波特率爲9600,而後重啓

[圖:USB轉TTL模塊]

[圖:串口助手]

2.1.二、電腦爲主設備搜索創建鏈接:

點擊筆記本藍牙標誌的小圖標,添加藍牙設備:

而後要等一會,筆記本正在裝驅動:

而後右擊藍牙圖標,查看藍牙設備,可見咱們的設備已經被電腦發現並添加:

查看該設備屬性,此時筆記本爲該設備提供一個串口,就是筆記本藍牙和設備藍牙通訊的通道,要記住這個一會編程的時候會用到:

PS:這個COM15也能夠在設備管理器中修改成其餘通道

 

 

3、C#編程使筆記本藍牙和外部設備藍牙通訊:

其實配對之後,藍牙就被模擬成了一個端口,咱們能夠用最簡單的端口通信來收發信息。首先,在每次啓動時,須要鏈接端口:

[FORM初始化時獲取全部的COM口,並加入下拉列表]

 1 public Form1()
 2 {
 3     InitializeComponent();
 4 
 5     //Get all port list for selection
 6     //得到全部的端口列表,並顯示在列表內
 7     PortList.Items.Clear();
 8     string[] Ports = SerialPort.GetPortNames();
 9 
10     for (int i = 0; i < Ports.Length; i++)
11     {
12         string s = Ports[i].ToUpper();
13         Regex reg = new Regex("[^COM\\d]", RegexOptions.IgnoreCase | RegexOptions.Multiline);
14         s = reg.Replace(s, "");
15 
16         PortList.Items.Add(s);
17     }
18     if (Ports.Length > 1) PortList.SelectedIndex = 1;
19 }

[鏈接按鈕事件:選中list中的被選中的COM口進行鏈接,若是鏈接成功就在狀態欄顯示藍牙鏈接成功]

 1 private void ConnectButton_Click(object sender, EventArgs e)
 2 {
 3     if (!BluetoothConnection.IsOpen)
 4     {
 5         //Start
 6         Status = "正在鏈接藍牙設備";
 7         BluetoothConnection = new SerialPort();
 8         ConnectButton.Enabled = false;
 9         BluetoothConnection.PortName = PortList.SelectedItem.ToString();
10         BluetoothConnection.Open();
11         BluetoothConnection.ReadTimeout = 10000;
12         BluetoothConnection.DataReceived += new SerialDataReceivedEventHandler(BlueToothDataReceived);
13         Status = "藍牙鏈接成功";
14     }
15 }

[藍牙接收數據事件響應函數,在按鈕鏈接事件中聲明的該事件,用於響應藍牙數據接收]

 1 private void BlueToothDataReceived(object o, SerialDataReceivedEventArgs e)
 2 {
 3     //int length = BluetoothConnection.ReadByte();
 4     Thread.Sleep(1000);
 5     int length = 13;
 6     BlueToothReceivedData = DateTime.Now.ToLongTimeString() + "\r\n";
 7     BlueToothReceivedData += "收到字節數:" + length + "\r\n";
 8 
 9     byte[] data = new byte[length];
10     BluetoothConnection.Read(data,0,length);
11     for (int i = 0; i < length; i++)
12     {
13         BlueToothReceivedData += string.Format("data[{0}] = {1}\r\n", i, data[i]);
14     }
15     //receive close message
16     if (length == 3 && data[0] == 255 && data[1] == 255 && data[2] == 255)
17     {
18         //Stop
19         Status = "正在斷開藍牙設備";
20         BluetoothConnection.Close();
21         BluetoothConnection.Dispose();
22         BluetoothConnection = null;
23         ConnectButton.Enabled = true;
24         Status = "藍牙斷開成功";
25     }
26 }
  • 這裏第4行讓程序休息1是由於延時等待從設備把數據發送徹底。
  • 這裏爲了方便我嚴格控制讓發送數據爲13Byte。
  • 從設備發送的13Byte數據送至緩衝區,PC端C#程序經過read()函數將緩衝區數據接收到data中,下面是格式輸出一下數據。

[發送數據函數]

 1 private void BlueToothDataSend(byte[] data)
 2 {
 3     //int length = data.Length;
 4     //byte[] readData = new byte[length + 2];
 5     //readData[0] = (byte)(length % 255);
 6     //readData[1] = (byte)(length / 255);
 7     //for (int i = 0; i < length; i++)
 8     //{
 9     //    readData[i + 2] = data[i];
10     //}
11     //BluetoothConnection.Write(readData, 0, length + 2);
12     BluetoothConnection.Write(data, 0, 1);
13     //Status = "發送數據字節數:" + length;
14 }
  • 原本是將data[]數據發送出去,由於我從設備設置爲只要有數據發送過來就作出響應發送13Byte數據,因此就直接將data的第一byte發送出去了。

[定時器函數:用於刷新狀態欄,和接收數據顯示]

1 private void MonitorTimer_Tick(object sender, EventArgs e)
2 {
3     StatusMessage.Text = Status;
4     BlueToothMessage.Text = BlueToothReceivedData;
5 }

[發送數據按鈕:將SendMessage中的數據得到發送出去]

1 private void SendButton_Click(object sender, EventArgs e)
2 {
3     byte n;
4     byte.TryParse(SendMessage.Text, out n);
5 
6     BlueToothDataSend(new byte[] { n });
7 }

 

 

4、PC和51單片機經過藍牙鏈接展現

4.1.一、51單片機部分程序

必定要用11.0952Mhz的晶振,我用12Mhz結果出現幀丟失!其實這裏採用的是52單片機,在此處區別不是很大~

將藍牙模塊的RXD鏈接單片機的RXD(P3.0),TXD鏈接單片機的TXD(P3.1),而後就像之前操做串口同樣操做就行啦~

  1 #include <REG52.H>
  2 #include <INTRINS.H>
  3 typedef unsigned char  uchar;
  4 typedef unsigned short ushort;
  5 typedef unsigned int   uint;
  6     
  7 sbit    SCL=P1^0;            //IIC時鐘引腳定義
  8 sbit    SDA=P1^1;            //IIC數據引腳定義
  9 
 10 #define    SlaveAddress    0xD0    //IIC寫入時的地址字節數據,+1爲讀取
 11 //**************************************
 12 //延時5微秒(STC90C52RC@12M)
 13 //不一樣的工做環境,須要調整此函數
 14 //當改用1T的MCU時,請調整此延時函數
 15 //**************************************
 16 void Delay5us()
 17 {
 18     _nop_();_nop_();_nop_();_nop_();
 19     _nop_();_nop_();_nop_();_nop_();
 20     _nop_();_nop_();_nop_();_nop_();
 21     _nop_();_nop_();_nop_();_nop_();
 22     _nop_();_nop_();_nop_();_nop_();
 23     _nop_();_nop_();_nop_();_nop_();
 24 }
 25 //**************************************
 26 //I2C起始信號
 27 //**************************************
 28 void I2C_Start()
 29 {
 30     SDA = 1;                    //拉高數據線
 31     SCL = 1;                    //拉高時鐘線
 32     Delay5us();                 //延時
 33     SDA = 0;                    //產生降低沿
 34     Delay5us();                 //延時
 35     SCL = 0;                    //拉低時鐘線
 36 }
 37 //**************************************
 38 //I2C中止信號
 39 //**************************************
 40 void I2C_Stop()
 41 {
 42     SDA = 0;                    //拉低數據線
 43     SCL = 1;                    //拉高時鐘線
 44     Delay5us();                 //延時
 45     SDA = 1;                    //產生上升沿
 46     Delay5us();                 //延時
 47 }
 48 //**************************************
 49 //I2C發送應答信號
 50 //入口參數:ack (0:ACK 1:NAK)
 51 //**************************************
 52 void I2C_SendACK(bit ack)
 53 {
 54     SDA = ack;                  //寫應答信號
 55     SCL = 1;                    //拉高時鐘線
 56     Delay5us();                 //延時
 57     SCL = 0;                    //拉低時鐘線
 58     Delay5us();                 //延時
 59 }
 60 //**************************************
 61 //I2C接收應答信號
 62 //**************************************
 63 bit I2C_RecvACK()
 64 {
 65     SCL = 1;                    //拉高時鐘線
 66     Delay5us();                 //延時
 67     CY = SDA;                   //讀應答信號
 68     SCL = 0;                    //拉低時鐘線
 69     Delay5us();                 //延時
 70     return CY;
 71 }
 72 //**************************************
 73 //向I2C總線發送一個字節數據
 74 //**************************************
 75 void I2C_SendByte(uchar dat)
 76 {
 77     uchar i;
 78     for (i=0; i<8; i++)         //8位計數器
 79     {
 80         dat <<= 1;              //移出數據的最高位
 81         SDA = CY;               //送數據口
 82         SCL = 1;                //拉高時鐘線
 83         Delay5us();             //延時
 84         SCL = 0;                //拉低時鐘線
 85         Delay5us();             //延時
 86     }
 87     I2C_RecvACK();
 88 }
 89 //**************************************
 90 //從I2C總線接收一個字節數據
 91 //**************************************
 92 uchar I2C_RecvByte()
 93 {
 94     uchar i;
 95     uchar dat = 0;
 96     SDA = 1;                    //使能內部上拉,準備讀取數據,
 97     for (i=0; i<8; i++)         //8位計數器
 98     {
 99         dat <<= 1;
100         SCL = 1;                //拉高時鐘線
101         Delay5us();             //延時
102         dat |= SDA;             //讀數據               
103         SCL = 0;                //拉低時鐘線
104         Delay5us();             //延時
105     }
106     return dat;
107 }
108 //**************************************
109 //向I2C設備寫入一個字節數據
110 //**************************************
111 void Single_WriteI2C(uchar REG_Address,uchar REG_data)
112 {
113     I2C_Start();                  //起始信號
114     I2C_SendByte(SlaveAddress);   //發送設備地址+寫信號
115     I2C_SendByte(REG_Address);    //內部寄存器地址,
116     I2C_SendByte(REG_data);       //內部寄存器數據,
117     I2C_Stop();                   //發送中止信號
118 }
119 //**************************************
120 //從I2C設備讀取一個字節數據
121 //**************************************
122 uchar Single_ReadI2C(uchar REG_Address)
123 {
124     uchar REG_data;
125     I2C_Start();                   //起始信號
126     I2C_SendByte(SlaveAddress);    //發送設備地址+寫信號
127     I2C_SendByte(REG_Address);     //發送存儲單元地址,從0開始    
128     I2C_Start();                   //起始信號
129     I2C_SendByte(SlaveAddress+1);  //發送設備地址+讀信號
130     REG_data=I2C_RecvByte();       //讀出寄存器數據
131     I2C_SendACK(1);                //接收應答信號
132     I2C_Stop();                    //中止信號
133     return REG_data;
134 }
I2C.c
  1 // GY-52 MPU6050 IIC測試程序
  2 // 使用單片機STC89C51 
  3 // 晶振:11.0592M
  4 // 編譯環境 Keil uVision2
  5 
  6 #include <REG52.H>    
  7 #include <math.h>    //Keil library  
  8 #include <stdio.h>   //Keil library    
  9 
 10 typedef unsigned char  uchar;
 11 typedef unsigned short ushort;
 12 typedef unsigned int   uint;
 13 
 14 uchar usart_flag,receive_data;//串口中斷接收標誌和串口接收數據
 15 //****************************************
 16 // 定義MPU6050內部地址
 17 //****************************************
 18 #define    SMPLRT_DIV        0x19    //陀螺儀採樣率,典型值:0x07(125Hz)
 19 #define    CONFIG            0x1A    //低通濾波頻率,典型值:0x06(5Hz)
 20 #define    GYRO_CONFIG        0x1B    //陀螺儀自檢及測量範圍,典型值:0x18(不自檢,2000deg/s)
 21 #define    ACCEL_CONFIG    0x1C    //加速計自檢、測量範圍及高通濾波頻率,典型值:0x01(不自檢,2G,5Hz)
 22 #define    ACCEL_XOUT_H    0x3B
 23 #define    ACCEL_XOUT_L    0x3C
 24 #define    ACCEL_YOUT_H    0x3D
 25 #define    ACCEL_YOUT_L    0x3E
 26 #define    ACCEL_ZOUT_H    0x3F
 27 #define    ACCEL_ZOUT_L    0x40
 28 #define    TEMP_OUT_H        0x41
 29 #define    TEMP_OUT_L        0x42
 30 #define    GYRO_XOUT_H        0x43
 31 #define    GYRO_XOUT_L        0x44    
 32 #define    GYRO_YOUT_H        0x45
 33 #define    GYRO_YOUT_L        0x46
 34 #define    GYRO_ZOUT_H        0x47
 35 #define    GYRO_ZOUT_L        0x48
 36 #define    PWR_MGMT_1        0x6B    //電源管理,典型值:0x00(正常啓用)
 37 #define    WHO_AM_I        0x75    //IIC地址寄存器(默認數值0x68,只讀)
 38 
 39 
 40 //****************************************
 41 //函數聲明
 42 //****************************************
 43 void  delay(unsigned int k);                                        //延時                        
 44 void  SeriPushSend(uchar send_data);                                  //串口發送函數
 45 void  InitMPU6050();                                                //陀螺儀初始化
 46 int   GetData(uchar REG_Address);                                    //合成數據併發送原數據
 47 void  init_uart();                                                    //串口初始化
 48 void  SeriPushSend(uchar send_data);                                //串口發送函數
 49 
 50 extern uchar Single_ReadI2C(uchar REG_Address);                        //讀取I2C數據
 51 extern void  Single_WriteI2C(uchar REG_Address,uchar REG_data);        //向I2C寫入數據
 52 
 53 
 54 //****************************************
 55 //延時
 56 //****************************************
 57 void delay(unsigned int k)    
 58 {                        
 59     unsigned int i,j;                
 60     for(i=0;i<k;i++)
 61     {            
 62         for(j=0;j<121;j++);
 63     }                        
 64 }
 65 //**************************************
 66 //初始化MPU6050
 67 //**************************************
 68 void InitMPU6050()
 69 {
 70     Single_WriteI2C(PWR_MGMT_1, 0x00);    //解除休眠狀態
 71     Single_WriteI2C(SMPLRT_DIV, 0x07);
 72     Single_WriteI2C(CONFIG, 0x06);
 73     Single_WriteI2C(GYRO_CONFIG, 0x18);
 74     Single_WriteI2C(ACCEL_CONFIG, 0x01);
 75 }
 76 //**************************************
 77 //合成數據併發送原數據
 78 //**************************************
 79 int GetData(uchar REG_Address)
 80 {
 81     uchar H,L;
 82     H=Single_ReadI2C(REG_Address);
 83     L=Single_ReadI2C(REG_Address+1);
 84     SeriPushSend(H);//發送出去
 85     SeriPushSend(L);
 86     return (H<<8)+L;   //合成數據
 87 }
 88 //**************************************
 89 //串口初始化
 90 //**************************************
 91 void init_uart()
 92 {
 93     TMOD=0x20;    //設置T1定時器工做方式2                
 94     TH1=0xfd;     //T1裝初值                
 95     TL1=0xfd;        
 96     TR1=1;        //啓動T1定時器    
 97     REN=1;        //容許串口中斷接收
 98     SM0=0;        //設置串口工做方式
 99     SM1=1;
100     EA=1;        //開總中斷
101     ES=1;        //開串口中斷
102 }
103 //****************************************
104 //串口發送函數
105 //****************************************
106 void  SeriPushSend(uchar send_data)
107 {
108     SBUF=send_data;  
109     while(!TI);TI=0;      
110 }
111 //****************************************
112 //串口接收函數
113 //****************************************
114 void ser()interrupt 4
115 {
116     RI=0;
117     receive_data=SBUF;
118     usart_flag=1;
119 }
120 //*********************************************************
121 //主程序
122 //*********************************************************
123 void main()
124 { 
125     delay(500);                        //上電延時        
126     init_uart();
127     InitMPU6050();                    //初始化MPU6050
128     delay(150);
129     while(1)
130     {
131         if(usart_flag==1)            //有數據傳過來
132         {
133             ES=0;                    //關閉串口中斷
134             SeriPushSend(0xff);
135             GetData(ACCEL_XOUT_H);    //發送X軸加速度
136             GetData(ACCEL_YOUT_H);    //發送Y軸加速度
137             GetData(ACCEL_ZOUT_H);    //發送Z軸加速度
138             GetData(GYRO_XOUT_H);    //發送X軸角速度
139             GetData(GYRO_YOUT_H);    //發送Y軸角速度
140             GetData(GYRO_ZOUT_H);    //發送Z軸角速度
141      
142             ES=1;
143             usart_flag=0;
144         }
145     }
146 }
main.c

由於我還在P1.0和P1.1鏈接一個陀螺儀MPU6050因此上面的代碼有點煩,其實能夠參考一下我之前發的51單片機串口通訊~

http://www.cnblogs.com/zjutlitao/p/3788696.htm

l 

4.1.二、沒有51單片機的狀況

能夠將藍牙模塊鏈接在USB轉TTL上,用串口助手和你寫的C#程序相互通訊。

4.1.三、運行C#程序進行鏈接通訊

[選擇剛纔的那個藍牙端口點擊鏈接]

[第一次藍牙圖標會給出一個驗證提示:在驗證框內輸入AT指令配置時的你設置的驗證碼]

[而後就能夠通訊啦,以下:]

 

PS:相關代碼及資料

C#藍牙工程代碼:http://pan.baidu.com/s/1hqHwG4W

51藍牙工程代碼:http://pan.baidu.com/s/1dDqywVZ

藍牙模塊說明書:http://pan.baidu.com/s/1kT61nx1

C#藍牙相關博客連接:http://www.diy-robots.com/?p=410%20%E8%93%9D%E7%89%99

相關文章
相關標籤/搜索