1、藍牙模塊XLBT232‐D01介紹(外部設備藍牙)html
1.一、藍牙模塊簡介編程
XLBT232-D0101藍牙模塊採用CSR BlueCore 芯片,配置6-8Mbit 的軟件存儲空間,
支持AT 指令,用戶可根據須要更改SPP 角色(主、從模式)以及串口波特率、
設備名稱、配對密碼等參數,使用靈活。安全
1.二、模塊功能介紹併發
1.2.一、特性ide
1.2.二、模塊接線原理圖函數
PS:固然也能用USB轉TTL模塊進行鏈接在電腦上調試,畢竟大多數筆記本已經沒有串口啦!測試
1.三、使用說明ui
[圖:藍牙模塊]spa
>_<" KEY爲輸入管腳,短按控制,或者輸入約100ms 的高電平單次脈衝,能夠
實現如下功能:3d
未鏈接狀態時:清除配對信息(若存在配對設備信息)
已鏈接狀態時:主動發起斷開鏈接,延時150ms 後重啓,從新搜索
鏈接從設備; 在斷開鏈接時:從新搜索鏈接從設備。
在已鏈接狀態時:主動發起斷開鏈接,延時150ms 後重啓,從新進入被搜
索狀態,等待主機配對和鏈接
在斷開鏈接時:延時150ms 後重啓,從新進入被搜索狀態,等待主機配對
和鏈接。
>_<" 顯示模塊當前工做狀態:
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 }
[發送數據函數]
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 }
[定時器函數:用於刷新狀態欄,和接收數據顯示]
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 }
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 }
由於我還在P1.0和P1.1鏈接一個陀螺儀MPU6050因此上面的代碼有點煩,其實能夠參考一下我之前發的51單片機串口通訊~
http://www.cnblogs.com/zjutlitao/p/3788696.htm
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