51单片机与蓝牙模块链接

不久前开始学习使用蓝牙模块,在模块与51单片机链接的过程当中出现了很是多的问题,我想应该也是不少新手和我同样会遇到这样的问题,所以特意写这篇文章,想分享下在学习过程当中遇到的问题以及解决方法。网络


这次学习用到模块是HC-06蓝牙模块,以下图:学习

该模块某宝有售,价格约为20RMB。某宝上的HC-06有两种,分别是带引脚不带引脚的,建议新手购买带引脚的。我从试验开始到成功,一共使用了四块蓝牙模块。第一次买的是带引脚的,可是模块自己是坏的;第二次买的是不带引脚的,可是因为自身的焊功有限,致使模块损坏,没法使用;第三次是朋友送的蓝牙4.0,因为某些缘由没法使用,在此也特别感谢朋友送我蓝牙;第四次购买,就是上图所示的蓝牙,才最终完成了试验。测试

总结:在某宝购买时,最好货比三家,虽然模块不值钱,可是在购买过程遇到问题会耽误时间,影响开发,很是麻烦。spa

单片机用了两个,分别是新手经常使用的开发板还有一个单片机最小模块,二者有什么区别我稍后会说明。3d

开发板:调试


单片机最小模块:code


我特别标注了二者的晶振,分别为12MHZ11.0594MHZ,就是晶振的不一样致使我在学习中问题的发生。如下是学习试验过程。blog


蓝牙模块的调试:图片

接线,蓝牙模块的RX接转换模块的TX蓝牙模块的TX接转换模块的RX,以下图所示:开发


接入电脑,在PC端下载好串口调试助手,软件自搜,此处再也不赘述。

附可能会用到的驱动:连接:https://pan.baidu.com/s/1bpYLfCr 密码:yabv

进入到调试助手,其实基本不怎么用调参数了,蓝牙模块基本都默认设置好波特率为9600,所以直接启动软件调试便可。具体调参数的方法能够自行百度其余文章,都有很详细的介绍。

启动串口,成功后左下角显示成功:


发送AT指令,返回OK:


代表串口正常,此时用手机链接蓝牙模块。手机端也是用到调试助手,请自行下载。

搜索蓝牙模块:

备注:个人蓝牙模块此前已经被我更名为Ezio,未更名前默认为HC06。


链接成功:


尝试发送消息hello:


此时在PC端的串口助手上,能够收到来自手机端发送的消息:


在此说明一点,在蓝牙模块上电之后,模块上的LED灯为闪烁状态,此时处于从机模式,与手机成功链接后,LED灯会变为常亮。自此,蓝牙模块调试成功,能够与单片机链接进行试验


蓝牙模块与51单片机接线:

和链接转换模块同样,蓝牙模块的RX链接单片机的TX,蓝牙模块的TX链接单片机的RX,此处说明单片机的RX和TX引脚分别为P3.0和P3.1,如图(图片来自网络):


正确接线后,向单片机中写入程序,程序以下:

#include <reg52.h>

sbit P1_0 = P1^0;	//测试口,可用可不用
sbit P1_3 = P1^3;	//输出口

unsigned char tempbuf;	//存储接收到的信息

/*初始化串口*/
void BlueteethInit()
{
	SCON = 0x50;	//串口模式1,容许接收
	TMOD = 0x20;	//T1工做模式为2,自动重装
	PCON = 0x00;	//波特率不倍增

	REN = 1;

	TH1 = 0xfd;		//设置波特率为9600
	TL1 = 0xfd;

	RI = 0;

	EA = 1;
	ES = 1;

	TR1 = 1;
}

void main()
{
	BlueteethInit();
	P1_0 = 0;
	P1_3 = 0;
	TI = 0;
	while(1)
	{
		if(tempbuf == 0x31)	//可使用
			P1_3 = 1;
		if(tempbuf == 0)	//不可使用
			P1_3 = 0;
		if(tempbuf == 'A')	//可使用
			P1_3 = 1;
		if(tempbuf == 'B')	//可使用
			P1_3 = 0;
	}
}

void Serial(void) interrupt 4
{
	tempbuf = SBUF;
	RI = 0;	//读标志清零
	SBUF = tempbuf;	//将内容返回到手机端,可在手机查看发送的内容
	while(!TI);
	TI = 0;	//写标志清零
}

该程序为最简单的测试程序,利用蓝牙接收手机发来的信息,控制P1.3口输出高或者低电平,以测试是否正确接收到信息。


第一步,用蓝牙模块与开发板接线,并成功用手机与蓝牙模块链接,尝试发送信息,过程如图所示:


不管是发送数字或者是其余字符,均可以看见返回的是乱码,所以能够知道,单片机接收的也是乱码,故程序中的判断:

while(1)
	{
		if(tempbuf == 0x31)	//可使用
			P1_3 = 1;
		if(tempbuf == 0)	//不可使用
			P1_3 = 0;
		if(tempbuf == 'A')	//可使用
			P1_3 = 1;
		if(tempbuf == 'B')	//可使用
			P1_3 = 0;
	}

没法正确执行,P1.3口天然也没法根据须要来输出高或者低电平。

第二步,用蓝牙模块与单片机最小模块接线,成功用手机链接收尝试发送信息,以下图所示:


可见,此时返回的内容与发出的内容相同,经测试此时程序也能够正确执行,使用万用表能够检查出P1.3口输出电平的变化,代表此时蓝牙模块能够正常使用。

特别说明:

if(tempbuf == 0x31)	//可使用
	P1_3 = 1;
if(tempbuf == 0)	//不可使用
	P1_3 = 0;

当发送数字消息时,应为十六进制,所以在判断时,如接收到1,应判断是否等于0x31,而不是判断是否等于1。此处通过测试,发送1时,判断tempbuf == 0x31,该判断有效;当发送0时,判断tempbuf == 0,判断无效。判断字符加单引号便可。

第三步,为何使用两个相同的单片机会致使结果不一样?这也是困扰了我好久的问题,后来通过检查,才知道原来就是晶振的问题。此处PO一下大神关于晶振的说明,暂时未看懂:https://www.zhihu.com/question/30930577

但能够得出的结论就是,若是使用串口通讯,应使用的晶振为11.0594MHZ,不然可能出现乱码的状况。

另附:开发板上的晶振如图:


是能够更换的,某宝也有售,能够根据须要的晶振购买。