ATK-HC05蓝牙模块的详细说明

前段时间买了个ATK的HC05蓝牙模块。HC05模块是一款高性能主从一体蓝牙串口模块,能够不用知道太多蓝牙相关知识就能够很好的上手。说白了,只是个蓝牙转串口的设备,你只要知道串口怎么编程使用,就能够了, 实现了所谓的透明传输。
ATK-HC05的外观以下图所示:
ATK-HC05蓝牙模块的详细说明 - ziye334 - ziye334的博客

从左到右的引脚分布式是:
一、VCC:固然这个引脚是接电源的正极,电压的范围为3.3v到5.0v,在应用的时候,作好不要直接接电源,而是经过一个PNP三极管,三极管的基极接单片机的引脚,集电极经过一个电阻接地,发射级直接接电源,而VCC引脚则接在集电极上,其实就是个最简单的三极管开关电路,以下图所示:
ATK-HC05蓝牙模块的详细说明 - ziye334 - ziye334的博客

 
二、GND:这个没什么好说的,直接接地就行了
三、TXD:模块串口发送引脚(TTL电平,不能直接接RS232电平),可直接接单片机的RXD引脚
四、RXD:模块串口接收引脚(TTL电平,不能直接接RS232电平),可直接接单片机的TXD引脚
五、KEY:用于进入AT状态:高电平有效(悬空默认为低电平),在应用中,该引脚应该受单片机的引脚控制,当单片机的引脚有上拉电阻式,能够直接接KEY引脚,若是没有,就要像VCC引脚同样,经过一个三极管间接控制:以下图
ATK-HC05蓝牙模块的详细说明 - ziye334 - ziye334的博客

六、LED:这个引脚是用来检测蓝牙模块是否已经链接上了其余蓝牙设备的,链接成功输出高电平,没有链接上输出低电平,能够用单片机的引脚来检测是否链接上,在应用程序中有很重要的做用,固然也能够接一个上拉过的LED灯,这样就能够观察到蓝牙模块是否链接。

模块自带了一个状态指示灯STA,该灯有3种状态,分别为:
一、在模块上电的同时(也能够是以前),将 KEY 设置为高电平(接 VCC),此时 STA慢闪(1秒亮1次),模块进入AT状态,且此时波特率固定为38400.
二、在模块上电的时候,将KEY悬空或接GND,此时STA快闪(1秒2次),表示模块进入可配对状态。若是此时将KEY在拉高,模块也会进入AT状态,可是STA依旧保持快闪。
3模块链接成功,此时STA双闪(1秒2下,2秒1次)

模块的相关资料,你们参考 http://www.openedv.com/posts/list/0/12486.htm ,关于模块的一些细节的东西就不说了!!!

接下去主要是结合蓝牙模块的AT指令,讲些应用,不少是手册不会讲的,都是鄙人实验出来的, 这里说些重要的AT指令。
1 、AT+RESET:该指令顾名思义,是复位HC05蓝牙设备的,蓝牙模块复位后,固然原来链接也就断开了,模块处于INITIALIZED状态,还须要注意的是,若是在用MCU的串口给蓝牙模块发送复位命令,必定要注意发送复位命令1s后才能继续发送其余命令,由于若是你1s内发送其余命令,此时蓝牙模块可能还在复位中,无法响应命令。固然,若是你是用串口工具发送,通常发送两个命令的间隔不会过短。
>AT+RESET\r\n
OK

二、AT+INIT:该指令初始化SPP规范库,所谓的SPP就是蓝牙串口端口协议,总之,没有初始化SPP库就没发扫描周围的蓝牙设备,没有与摸个蓝牙设备链接。,因此,在应用程序中,必定要初始化SPP库,没有初始化SPP库,就发送扫描指令或链接指令,蓝牙模块会返回ERROR:(16)错误,表示没有初始化SPP库。还有个要注意的是,若是发送屡次该指令,蓝牙模块会放回ERROR:(17)重复初始化错误。还有,每次断电后再上电或蓝牙模块复位后,都要从新初始化SPP库。
>AT+INIT\r\n
OK         //正确
FALL //失败
ERROR:(17) //重复初始化

三、AT+ROLE:该指令用于选择HC05蓝牙模块的角色,总共有三种角色:master,slave,loop-slave.
AT+ROLE=0\r\n  将蓝牙模块设置成从角色,只能被动链接
AT+ROLE=1\r\n  将蓝牙模块设置成主角色,能够查询周围SPP蓝牙从设备,并发送链接
AT+ROLE=2\r\n  将蓝牙模块设置成回环角色,被动链接,接收远程蓝牙模块主设备数据并将数据原样返回给远程蓝牙设备
       这几个指令用在不一样的场合,当设置蓝牙模块为从设备的时候,能够用手机的相关蓝牙装串口软件链接该设备,进行通信;当设置成主角色的时候,能够搜索周遭的蓝牙从设备,并链接,这种模式在应用中很经常使用;回环角色不少时候都是用来作测试用的。
>AT+ROLE=1\r\n
OK

四、AT+PSWD:这个指令时设置蓝牙模块的配对密码,蓝牙模块在作从模块的时候,若是用手机要链接该蓝牙设备,就要键入蓝牙的配对密码才能链接,好比说HC05默认的配对密码是1234,那么就要在手机的输入该配对密码1234才能链接咱们的HC05;若是咱们的HC05作主模块扫到周围有个蓝牙从设备,这时候想链接该蓝牙从设备该怎么办呢?这个问题也曾经困扰过我好久,由于我一直觉得,我用AT+LINK=蓝牙地址  该命令去链接蓝牙从设备,从设备就会发送一些数据叫你键入配对密码,而HC05的AT指令没有发送配对密码的指令,结果搞得我一头雾水,最后都咨询到厂家那里去了,厂家的技术人员终于给了正解。原来你要链接某个蓝牙从设备,就要把本身的蓝牙模块的配对密码设置成蓝牙从设备的配对密码配置成同样。举例说我两块HC05蓝牙模块,蓝牙A设置成主机,蓝牙B设置成从机,原来蓝牙A的配对密码是1234,而蓝牙B的配对密码是2345,此时你就要将蓝牙A的配置密码设置成2345才能链接上蓝牙B.
>AT+PSWD=1234\r\n
OK
 
五、AT_UART:这个指令是设置串口的参数,指令的格式以下:
AT+UART=<Param>,<Param1>,<Param2>\r\n
Param:波特率,一些经常使用的波特率均可以设置
Param1:中止位,通常设置成0,表示为1个中止位
Param2:校验位,一帮设置为0,表示不用校验
该指令是设置蓝牙模块与蓝牙模块之间通信时,蓝牙模块的串口参数。HC05模块在默认的配置下是设置成9600,也就是说,在AT模式下,咱们用38400与HC05通信,而在HC05与某蓝牙模块通信时,则咱们用9600的波特率接收HC05从蓝牙模块的接收到的数据。这里建议将波特率改成38400,这是由于,当用串口调试工具链接HC05时,AT模式是用38400波特率,而链接后默认是9600,这样的不断的切换串口调试工具的波特率,会很麻烦,因此设置成38400后,就方便调试了。
>AT+UART=38400,0,0\r\n
OK

六、AT+INQM:设置或查询访问模式,格式如此:
AT+INQM=<Param>,<Param1>,<Param2>\r]n
Param:0——inquiry_mode_standard,1——inquiry_mode_rssi,表示标准查询仍是带信号强度的查询。
Param1:最多蓝牙设备响应的数量
Param2:最大查询时间(1~48,折合成时间,1,28s~61.44s)
将这个指令是为扫描指令作铺垫,根据本身的实际状况调整。
>AT+INQM=1,1,15
OK

七、AT+INQ:查询蓝牙设备,返回的格式以下:
+INQ:<Param>,<Param1>,<Param>....
Param:蓝牙地址
Param1:设备类
Param2:RSSI信号强度
举个例子:+INQ:98D3:31:500DF8,1F00,7FFF,
98D3:31:500DF8表示蓝牙的地址,这里有须要补充下蓝牙的相关知识,蓝牙地址的由NAP(24位地址低端部分):UAP(8为地址高端部分):LAP(16为无心义地址部分),因此该地址:98D3表示LAP,31表示UAP,500DF8表示LAP
>AT+INQ 
+INQ:98D3:31:500DF8,1F00,7FFF //有的话列出 
OK
 
八、AT+RNAME:这个指令得到远端蓝牙设备的名字,咱们手机上看到的就是这个名字,而不会直接给出蓝牙设备地址
>AT+RNAME? 98D3,31,500DF8   //主要这里是逗号,而不是冒号
+RNAME:EST527
OK

九、AT+LINK:这个命令链接远程设备蓝牙,其实没有什么好说的,链接上后,LED引脚输出高电平,若是该引脚有接上拉LED灯,则会发现LED灭了。
>AT+LINK=98D3,31,500DF8
OK


十、AT+STATE:这个指令用来查询蓝牙模块当前的状态,状态种类以下:
INITIALIZED——初始化状态
READY——准备状态
PAIRABLE——可配对状态
PAIRED——配对状态
INQUIRING——查询状态
CONNECTING——正在链接状态
CONNECTED——链接状态
DISCONNECTED——断开链接
UNKNOW————位置状态

>AT+STATE
+STATE:INITIALIZED
OK

+STATE:PAIRED
OK

十一、AT+CMODE:这个指令其实很重要。
AT+CMODE=0\r\n  指定蓝牙地址链接模式(指定蓝牙地址呦绑定指令设置)
AT+CMODE=1\r\n  任意蓝牙地址链接模式(不受绑定指令的设置地址约束)
AT+CMODE=2\r\n  回环角色
        为0时,该指令设置模块为指定地址配对,若是先设置模块为任意地址,而后配对,接下去使用该指令,则模块会记忆最后一次配对的地址,下次上电会一直搜索该地址的模块,直到搜索到为止。
为1时,该指令设置模块能够对任意地址的蓝牙模块进行配对,只要有模块的配对秘钥跟本身的同样的就能自动连上。
AT+CMODE=1\r\n
OK


最后想讲讲关于这些蓝牙装串口模块或WIFI转串口模块的编程。
准备好工程,已经设置好了串口配置,最好能有两个串口,串口1用来发送AT指令,串口2则用来打印一些调试信息信息,还有配置一个定时器。
串口1的波特率设置成38400,1个中止位,没有校验位,编写发送函数,好比我以stm32为例:
 

void USART1SendStr(char *str) { while(*str!='\0') { USART_SendData(USART1,*str); while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);/*等待发送完成*/ str++; } }编程

最好在某个头文件里定义下  #define ATSendCmd(x) USART1SendStr(x)  用 ATSendCmd()来发送AT指令
        串口2最为调试用,链接上标准库,而后使用printf函数发送调试信息!
 
 

/*----------------------跟编译器相关,链接标准C库----------------------*/ #ifdef __GNUC__ #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif并发

/******************************************************** 函数:PUTCHAR_PROTOTYPE 描述:链接标准C库的printf函数 参数:无 返回:无 ********************************************************/ PUTCHAR_PROTOTYPE { USART_SendData(USART2, (uint8_t) ch); while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET){} return ch; }分布式

如上,这样就能使用printf函数了,要学会在编程时候常使用printf函数,显示函数的状况与进程,当发生错误时,这样就能很精准的定位错误位置了。最好还要定义一个宏定义 #define DEBUG     在写printf时最好以下写法:
 
 

#ifdef DEBUG函数

printf("xxxxxxxxxxxxx");工具

#endifoop

这样的写法,就起了一个宏开关的做用,只要屏蔽#define DEBUG 就能关闭调试信息了。

由于像蓝牙装串口模块这样的独立模块,咱们单片机发送配置指令时,必须收到配置成功相关回应是,才能接下去发送命令,可是若是咱们单片机发送命令,结果蓝牙模块没有回应,咱们程序就废了,要么无限等待,要么继续发送可能没有响应的指令。因此,咱们必须设置一个重传机制,和一个超时机制。重传机制用在,咱们给蓝牙模块发送命令,结果蓝牙有响应,可是回来的响应错误,这是就要重传指令;而超时机制则是,咱们单片机给蓝牙模块发送命令,而蓝牙模块没有响应,咱们等超时时间到了以后,再从新发送命令,若是连续好几回失败,则须要程序复位下了!!!
因此咱们还须要一个定时器,定时时间这里设置为1s,要写个设置超时时间的函数:
 
 

u16 timeCnt=0; extern u8 timeOut;post

/******************************************************** 函数:SetTimeOut() 描述:设置超时时间 参数:无 返回:无 ********************************************************/ void SetTimeOut(u16 timeout) { timeCnt=timeout; timeOut=0; TIM_Cmd(TIM2,ENABLE); }性能

还要写个定时器中断服务函数:
 
 

void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)//检测是否发生溢出更新事件 { //清除TIM2的中断待处理位 TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update); LED1_Toggle(); if(timeCnt!=0) { timeOut=0; printf("."); timeCnt--; } else { timeOut=1; printf("\r\n定时时间到!\r\n"); TIM_Cmd(TIM2,DISABLE); } } }测试

在中断服务程序中,一旦超时时间到了,就要关闭定时器,等待下一次设置超时时间再打开。
接下去就是指令的发送函数了,我以发送reset命令为例:
 
 

/******************************************************** 函数:HC05_Reset 描述:复位蓝牙模块 参数:无 返回:无 ********************************************************/ void HC05_Reset(void) { ATSendCmd("AT+RESET\r\n"); curStat=CRESET; //当前状态设置为CRESET SetTimeOut(6); //设置定时时间为4s while(curStat!=NOCMD) //等待蓝牙模块响应 { if(tryAgain || timeOut)//从新发送命令 { printf("蓝牙模块复位失败,重试中!\r\n"); tryAgain=0; ATSendCmd("AT+RESET\r\n"); SetTimeOut(6); //从新设置定时时间为4s } } CloseTimer(); //关闭定时器 Delay_ms(1000); printf("蓝牙模块复位成功!\r\n"); }ui

 这里的curStat的状态是在串口接收程序程序里改变的,若是接收正确curStat=NOCMD,若是接收失败,则tryAgain置1,。