博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[C#] 编程控制笔记本蓝牙与外部蓝牙设备通信
阅读量:5355 次
发布时间:2019-06-15

本文共 12709 字,大约阅读时间需要 42 分钟。

原文:

 

一、蓝牙模块XLBT232‐D01介绍(外部设备蓝牙)

1.1、蓝牙模块简介

XLBT232-D0101蓝牙模块采用CSR BlueCore 芯片,配置6-8Mbit 的软件存储空间,

支持AT 指令,用户可根据需要更改SPP 角色(主、从模式)以及串口波特率、
设备名称、配对密码等参数,使用灵活。

 

1.2、模块功能介绍

1.2.1、特性

  •  蓝牙协议:Bluetooth Specification V2.1+EDR、V2.0+EDR、V2.1、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.2、模块接线原理图

PS:当然也能用USB转TTL模块进行连接在电脑上调试,毕竟大多数笔记本已经没有串口啦!

 

1.3、使用说明

[图:蓝牙模块]

>_<" KEY为输入管脚,短按控制,或者输入约100ms 的高电平单次脉冲,可以

实现以下功能:

  • 模块设置为SPP 主机模式时:

    未连接状态时:清除配对信息(若存在配对设备信息)

    已连接状态时:主动发起断开连接,延时150ms 后重启,重新搜索

  连接从设备; 在断开连接时:重新搜索连接从设备。

  • 模块设置为SPP 从机时:

    在已连接状态时:主动发起断开连接,延时150ms 后重启,重新进入被搜

     索状态,等待主机配对和连接

    在断开连接时:延时150ms 后重启,重新进入被搜索状态,等待主机配对

     和连接。

>_<" 显示模块当前工作状态:

  • 待机状态慢闪——重复2s 脉冲;
  • 连接状态长亮——高电平。

 

1.4、AT指令集

蓝牙模块出厂默认的串口配置为:波特率9600,无校验,数据位8,停止位1。

PS:接下来说明以上位机为电脑,模块参数为出厂设置时进行配置说明。
>_<" 将模块通过USB电平转换板连接到电脑USB口(USB转TTL),使用串口调试助手,按
照 9600,N,8,1 进行配置,打开串口后,发送 AT(无\r\n),若返回 OK,说明配置
成功。
PS:设置 AT 指令必须在蓝牙模块未连接或断开 SPP 链接时才可以(上电或配对
后都可以,如果连接 SPP,串口输入的数据将会直接发送到远端蓝牙设备串口)

1.4.1、测试指令:

1.4.2、查询\设置波特率指令:

1.4.3、查询\设置设备名称指令:

1.4.4、恢复默认设置指令:

1.4.5、模块复位\重启指令:

1.4.6、查询\设置主从模式:

1.4.7、查询\设置配对密码:

1.4.8、查询\设置是否需要密码鉴权:

PS:为方便使用,默认为不用密码鉴权连接,搜索到蓝牙串口之后,直接连接

可。有安全考虑的客户请选择需要密码鉴权。
PS:此指令只有在从设备时才有效;主设备时不接受此指令,发送此指令没
有回复,也不执行

1.4.9、清除主设备配对信息指令:

PS:此指令只有在主设备时才有效;从设备时不接受此指令,发送此指令

没有回复,也不执行。

1.4.10、搜索并连接新的蓝牙串口从设备(*)指令:

PS:此指令只有在主设备时才有效;从设备时不接受此指令,发送此指令没

有回复,也不执行。

1.4.11、连接最后一次连接的蓝牙串口从设备(*)指令:

PS:此指令只有在主设备时才有效;从设备时不接受此指令,发送此指令没

有回复,也不执行。

1.4.12、连接指定蓝牙地址的从设备(*)指令:

PS:此指令只有在主设备时才有效;从设备时不接受此指令,发送此指令没

有回复,也不执行。

1.4.13、查询、设置软件版本指令:

1.4.14、系统帮助指令:

1.4.15、查询本机MAC 地址指令:

>_<: 1:所有参数设置后存储在模块内,下次启动时无需再次设置

         2:AT 指令后标注*号的,表示目前未应用的AT 指令

 

 

二、蓝牙模块配置与笔记本电脑相连

2.1.1、蓝牙初始化配置:

将蓝牙模块通过TTL转USB模块连接到笔记本,打开串口助手,通过上述AT指令设置为从设备,波特率为9600,然后重启

[图:USB转TTL模块]

[图:串口助手]

2.1.2、电脑为主设备搜索建立连接:

点击笔记本蓝牙标志的小图标,添加蓝牙设备:

然后要等一会,笔记本正在装驱动:

然后右击蓝牙图标,查看蓝牙设备,可见我们的设备已经被电脑发现并添加:

查看该设备属性,此时笔记本为该设备提供一个串口,就是笔记本蓝牙和设备蓝牙通信的通道,要记住这个一会编程的时候会用到:

PS:这个COM15也可以在设备管理器中修改为其他通道

 

 

三、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 message16     if (length == 3 && data[0] == 255 && data[1] == 255 && data[2] == 255)17     {18         //Stop19         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 }

 

 

四、PC和51单片机通过蓝牙连接展示

4.1.1、51单片机部分程序

一定要用11.0952Mhz的晶振,我用12Mhz结果出现帧丢失!其实这里采用的是52单片机,在此处区别不是很大~

将蓝牙模块的RXD连接单片机的RXD(P3.0),TXD连接单片机的TXD(P3.1),然后就像以前操作串口一样操作就行啦~

1 #include 
2 #include
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 
7 #include
//Keil library 8 #include
//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
main.c

因为我还在P1.0和P1.1连接一个陀螺仪MPU6050所以上面的代码有点烦,其实可以参考一下我以前发的51单片机串口通信~

 

4.1.2、没有51单片机的情况

可以将蓝牙模块连接在USB转TTL上,用串口助手和你写的C#程序相互通信。

4.1.3、运行C#程序进行连接通信

[选择刚才的那个蓝牙端口点击连接]

[第一次蓝牙图标会给出一个验证提示:在验证框内输入AT指令配置时的你设置的验证码]

[然后就可以通信啦,如下:]

 

PS:相关代码及资料

C#蓝牙工程代码:

51蓝牙工程代码:

蓝牙模块说明书:

C#蓝牙相关博客链接:

 

posted on
2014-08-02 23:14 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/3887631.html

你可能感兴趣的文章
【iOS开发-68】APP下载案例:利用tableView自带的cell布局+缓存池cell复用时注意button状态的检查...
查看>>
《Genesis-3D开源游戏引擎-FQA常见问题解答》2014年01月10号版本
查看>>
Java 编程下实现随机无重复数字功能
查看>>
Android 编程下的代码混淆
查看>>
animation属性
查看>>
页内的模块和组件抽象规划经验
查看>>
安全-分析深圳电信的新型HTTP劫持方式
查看>>
将Centos的yum源更换为国内的阿里云源
查看>>
git diff 的用法
查看>>
一段sql的优化
查看>>
十进制与十六进制的相互转换
查看>>
在Flex中用Validator检测数字、字符串、Email.
查看>>
[leetcode]4Sum
查看>>
POJ1062 昂贵的聘礼
查看>>
【零基础学习iOS开发】【02-C语言】08-基本运算
查看>>
雷林鹏分享Node.js JXcore 打包
查看>>
常见错误总结
查看>>
BZOJ3545&3551[ONTAK2010]Peaks——kruskal重构树+主席树+dfs序+树上倍增
查看>>
Django框架(十九)--Django rest_framework-认证组件
查看>>
我的MFC/C++学习笔记 http://blog.bccn.net/CrystalFan/6909
查看>>