STM32F1驱动HC05蓝牙模块进行数据传输

HC05蓝牙数据传输灯控实验

一、 实验简介

蓝牙是一种短距离无线通信技术,目前已经应用到各个领域中,我们身边的大多数设备也已经集成了蓝牙模块,比如手机,运动手表,车载音箱,耳机等等。在智能家居中蓝牙应用的也是比较多的,蓝牙已成为接入物联网(IOT)的主要技术之一。蓝牙技术持续更新,从3.0到4.0,目前已经进入蓝牙5.0,功耗更低,速度更快,覆盖范围更广。在物联网快速发展的大背景下,蓝牙技术的应用场景更加广阔。

在这个实验中,通过STM32开发板驱动HC05模块,设置蓝牙模块的工作模式,串口参数等,实现蓝牙模块与蓝牙调试助手APP的连接,并通过蓝牙调试助手下发控制命令,无线控制LED的亮灭。

二、实验环境及设备

  • PC一台(Windows x64);

  • 远程设备:STM32开发板、HC05蓝牙模块、LED灯

    引脚连线:

    STM32开发板HC05模块
    3V3VCC
    GNDGND
    PB10RXD
    PB11TXD
    PA5EN
    STM32开发板LED灯
    3V3VCC
    GNDGND
    PA4IN

蓝牙技术

蓝牙技术由蓝牙技术联盟( Bluetooth Special Interest Group,BSIG)组织研发。该组织成立于1998年,成员包括爱立信、IBM、Intel、东芝和诺基亚等国际通信巨头。1998年3月,IEEE为蓝牙技术制定IEEE 802.15.1标准。蓝牙技术的物理层采用跳频扩频结合的调制技术,频段范围是2.402到2.480GHz,通信速率一般能达到1Mb/s左右。蓝牙通信中的设备有两种角色一中心设备( central)和外围设备( peripheral)。同一个蓝牙设备可以在这两种角色之间转换。一个中心设备最多可以同时和7个外围设备通信。在任意时刻,中心设备单元可以向任何一一个外围 设备单元发送信息,也可以用广播方式同时向多个外围设备发送信息。截至2020年1月,蓝牙技术联盟推出了不同的技术版本,如V1.1/1 .2/2.0/2.1/3.0/4.0/5。

蓝牙技术特点:
  1. 蓝牙模块体积很小、便于集成:由于个人移动设备的体积较小,嵌入其内部的蓝牙芯片体积就应该更小。

  2. 低功耗:蓝牙设备在通信连接状态下,有四种工作模式——激活模式、呼吸模式、保持模式和休眠模式Active模式是正常的工作状态,另外三种模式是为了节能所规定的低功耗模式。

  3. 全球范围适用:蓝牙工作在2.4GHz的ISM频段,全球大多数国家ISM频段的范围是2.4~2.4835GHz,使用该频段无需向各国的无线电资源管理部门申请许可证。

  4. 同时可传输语音和数据:蓝牙采用电路交换和分组交换技术,支持异步数据信道、三路语音信道以及异步数据与同步语音同时传输的信道。每个语音信道数据速率为64kbit/s,语音信号编码采用脉冲编码调制(PCM)或连续可变斜率增量调制(CVSD)方法。当采用非对称信道传输数据时,速率最高为721kbit/s,反向为57.6kbit/s;当采用对称信道传输数据时,速率最高为342.6kbit/s。蓝牙有两种链路类型:异步无连接链路和同步面向连接链路

  5. 具有很好的抗干扰能力:工作在ISM频段的无线电设备有很多种,如家用微波炉、无线局域网和HomeRF等产品,为了很好地抵抗来自这些设备的干扰,蓝牙采用了跳频方式来扩展频谱,将2.402~2.48GHz频段分成79个频点,相邻频点间隔1MHz。蓝牙设备在某个频点发送数据之后,再跳到另一个频点发送,而频点的排列顺序则是伪随机的,每秒钟频率改变1600次,每个频率持续625u s。

  6. 可以建立临时性的对等连接:根据蓝牙设备在网络中的角色.可分为主设备与从设备。主设备是组网连接主动发起连接请求的蓝牙设备,几个蓝牙设备连接成一个微微网时,其中只有一个主设备,其余的均为从设备。微微网是蓝牙最基本的一种网络形式,最简单的微微网是一个主设备和一个从设备组成的点对点的通信连接。通过时分复用技术,一个蓝牙设备便可以同时与几个不同的微微网保持同步,具体来说,就是该设备按照一定的时间顺序参与不同的微微网,即某一时刻参与某一微微网,而下一时刻参与另一个微微网。

  7. 成本低:随着市场需求的扩大,各个供应商纷纷推出自己的蓝牙芯片和模块,蓝牙产品价格飞速下降。

  8. 开放的接口标准:SIG为了推广蓝牙技术的使用,将蓝牙的技术标准全部公开,全世界范围内的在何单位和个人都可以进行蓝牙产品的并发,只要最终通过SIG的蓝牙产品兼容性测试,就可以推向市场。

蓝牙模块HC05简介

HC-05 嵌入式蓝牙串口通讯模块具有两种工作模式:命令响应工作模式和自动连接工作模式,在自动连接工作模式下模块又可分为主(Master)、从(Slave) 和回环(Loopback)三种工作角色。当模块处于自动连接工作模式时,将自动根据事先设定的方式连接,进行数据传输;当模块处于命令响应工作模式时,用户可向模块发送各种 AT 指令,为模块设定控制参数或发布控制命令。通过控制模块外部引脚EN(PIO11)输入高低电平,可以实现模块工作状态的转换。下图为HC-05蓝牙模块实物图。

自动连接工作模式:
角色说明
主(Master)在主模式下,蓝牙模块充当主机,负责主动扫描、连接和控制一个或多个从设备,不可被其他设备搜索到
从(Slave)在从模式下,蓝牙模块充当从设备,等待主设备的连接请求,不能主动连接其他设备
回环(Loopback)在回环模式下,蓝牙模块可以将接收到的数据回送到发送方,允许模块自我测试,既可以连接其他设备,也可以被其他设备搜索连接
HC-05蓝牙模块在AT指令模式与透传模式切换方法:

①模块上电之前按住按钮,进入AT模式,指示灯2s闪烁一次,发送AT+RESET命令或者重新上电进入数据透传模式

②模块上电之后,要发送AT指令的时候,先按住按钮,直到指令发送完为止,松开手之后又进入了数据透传模式

③模块上电之后,EN引脚(PIO11)连接高电平,此时进入AT模式,之后将其置为低电平,输入命令AT+RESET,退出AT 指令模式,进入数据透传模式

综上所诉,其实在每次要发送AT指令的时候,必须确保EN引脚处于高电平即可,数据透传模式,必须保证EN引脚处于低电平。

以上三种方式都可以完成模式切换,在实验的过程中,我们不想要手动控制它的模式转换,因此我们选择第三种方式,来控制它的工作模式,后面在具体的代码中,我们就需要按照要求对其EN引脚进行相应的配置即可,结合下面的原理图可以更好的理解其模式转换的的设置。
请添加图片描述

常用AT指令解析:

在本次实验中,我们只使用到其中的部分AT指令,感兴趣的同学可以自行尝试其他的AT指令以及其他的模式哦。

序号指令指令说明返回值
1AT测试蓝牙模块是否进入AT指令模式OK:成功进入AT模式
2AT+RESET复位蓝牙模块,对于hc05模块来说,复位之后需要重新上电启动,进入AT模式OK:复位成功
3AT+VERSION查看蓝牙版本号VERSION:3.0-20170601
OK :版本号查看成功
4AT+ORGL恢复默认状态,对于hc05模块来说,恢复默认状态之后需要重新上电启动,进入AT模式OK:恢复成功
5AT+ADDR获取蓝牙模块地址+ADDR:98D3:21:F808D8
OK:获取成功
6AT+NAME?设备名称查询+NAME:H-C-2010-06-01
OK
7AT+NAME=设备名称设置eg:AT+NAME=mybleOK:设备名称设置成功
8AT+UART/AT+UART?设备串口信息查询
eg:
发送:AT+UART
返回:+UART:9600,0,0
OK
+UART:,,
OK
串口波特率
停止位
校验位
9AT+UART=,,设置蓝牙串口的波特率,停止位,校验位
eg:
发送:AT+UART=115200,1,0
返回:OK
OK:串口参数设置成功
10AT+ROLE/AT+ROLE?查询模块当前角色
eg:
发送:AT+ROLE
返回:+ROLE:0
+ ROLE:
OK
为0:从角色( Slave)
为1:主角色( Master)
为2: 回环角色( Slave-Loop)
默认值: 0
11AT+ROLE=设置当前蓝牙模块的模式,可以是:0、1、2。对于hc05模块来说,重置蓝牙工作模式之后需要重新上电启动,进入AT模式OK
12AT+ CLASS/AT+ CLASS?查询设备类型
eg:
发送:AT+ CLASS
返回:+CLASS:1f00
OK
+ CLASS:
OK
Param:设备类 蓝牙设备类实际上是一个 32 位 的参数,该参数用于指出设备类 型,以及所支持的服务类型。 默认值: 0
13AT+CLASS=设置设备类
eg:
发送:AT+CLASS=aabb
返回:OK
OK:设备类型设置成功
14AT+IAC/AT+IAC?查询设备访问码
eg:
发送:AT+IAC
返回:+IAC:9E8B33
OK
+IAC:
OK
:查询成功
15AT+IAC=设备访问码设置
eg:
发送:AT+IAC=9E8B35
返回:OK
OK:设置成功
16AT+ PSWD/AT+ PSWD?查询配对码
eg:
发送:AT+ PSWD
返回:+PIN:“1234” 
OK
+PIN:
OK
17AT+PSWD=设置配对码
eg:
发送:AT+ PSWD=“2334”
返回:OK
OK:配对码设置成功
18AT+CMODE/AT+CMODE?查询连接模式
eg:
发送:AT+CMODE
返回:+CMODE:1
OK
+CMODE:
OK
为0:指定蓝牙地址连接模式
(指定蓝牙地址由绑定指令设置
为1:任意蓝牙地址连接模式
(不受绑定指令设置地址的约束)
为2: 回环角色( Slave-Loop)
默认值: 0
19AT+CMODE=设置连接模式
eg:
发送:AT+CMODE=1
返回:OK
OK:
20AT+PMSAD=从蓝牙配对列表中删除指定认证设备
为目标地址
OK:
21AT+STATE/AT+STATE?获取蓝牙工作状态
eg:
发送:AT+STATE
返回:+STATE:INITIALIZED
OK
+STATE:
OK
22AT+INQ/AT+INQ?查询蓝牙设备+INQ: , <>OK
Param1:蓝牙地址
Param2:设备类
Param3: RSSI 信号强

三、示例代码

bluetooth_hc05.c

//单片机头文件
#include "stm32f10x.h"

//硬件驱动
#include "delay.h"
#include "usart.h"
#include "pinInit.h"
#include "bluetooth_hc05.h"

//C库
#include <string.h>
#include <stdio.h>

/**************************************************************************/
//函数名称:串口3中断服务函数
//函数作用:用于接收hc05返回的OK
/**************************************************************************/
u8 i3=0;
u8 res3=0;
extern u8 Usart3_buff[128];//接收蓝牙模块返回的响应信息
void USART3_IRQHandler(void)
{
	/*编写代码,实现串口三中断服务函数接收AT指令返回值*/
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收中断
	{
	  res3 = USART_ReceiveData(USART3); 
	  Usart3_buff[i3]=res3;             //将接收的数据存放于数组中
	  i3++;
	  if(Usart3_buff[i3]=='K')    //
		{
		  i3=0;
		}
	  USART_ClearFlag(USART3, USART_FLAG_RXNE);
	}
	/* END */
  
}
/**************************************************************************/
//函数作用:字符串匹对函数,0匹配成功,1匹配失败
/**************************************************************************/
u8 Find_char(char *a,char *b)  //b为子串
{ 
  if(strstr(a,b)!=NULL)
	    return 0;
	else
			return 1;
}
/*****************  发送一个字符 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
	/* 发送一个字节数据到USART */
	USART_SendData(pUSARTx,ch);
		
	/* 等待发送数据寄存器为空 */
	while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);	
}

/*****************  发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{
	unsigned int k=0;
  do 
  {
      Usart_SendByte( pUSARTx, *(str + k) );
      k++;
  } while(*(str + k)!='\0');
  
  /* 等待发送完成 */
  while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET)
  {}
}
void blueHc05_init(void)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_SET);//EN引脚拉高
	delay_ms(200);
    Usart_SendString(USART3,"AT\r\n");
	delay_ms(200);
	while(Find_char((char*)Usart3_buff,"OK"));
	printf("1.AT测试OK:\r\n");
	
	Usart_SendString(USART3,"AT+NAME=BLE_HC05_2\r\n");                          
	delay_ms(200);
	while(Find_char((char*)Usart3_buff,"OK"));
	printf("2.蓝牙名称设置成功:\r\n");
	
	Usart_SendString(USART3,"AT+PSWD=1234\r\n");                            
	delay_ms(200);
	while(Find_char((char*)Usart3_buff,"OK"));
	printf("3.配对码设置成功:\r\n");
	
	Usart_SendString(USART3,"AT+CMOD=1\r\n");                            
	delay_ms(200);
	while(Find_char((char*)Usart3_buff,"OK"));
	printf("4.设置蓝牙连接模式为任意模式成功:\r\n");
	
	Usart_SendString(USART3,"AT+ROLE=0\r\n");                            
	delay_ms(200);
	while(Find_char((char*)Usart3_buff,"OK"));
	printf("5.设置蓝牙为从机模式成功:\r\n");
	
	Usart_SendString(USART3,"AT+UART=38400,1,0\r\n");                            
	delay_ms(200);
	while(Find_char((char*)Usart3_buff,"OK"));
	printf("6.设置蓝牙串口参数成功:\r\n");
	
	GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_RESET);//EN引脚拉低
}

main.c

#include "usart.h"
#include "delay.h"
#include "bluetooth_hc05.h"
#include "pinInit.h"
/*
代码填写说明:
1.bluetooth.c中的串口三中断服务函数
2.bluetooth.c中的blueHc05_init()蓝牙初始化函数
3.mian.c中的蓝牙传输灯控代码
*/
u8 Usart3_buff[128];
int main(void){
	
	uart_init(115200);
    uart3_init(38400);
	delay_init();
	pin_init();
    printf(" Hardware init...\r\n");
	blueHc05_init();
	delay_ms(500);

	while(1)
	{
	 USART3_IRQHandler();

	 /*编写代码,实现接收控制命令后开灯,延时2秒后关灯*/
     if(Find_char((char*)Usart3_buff,"TURNON")==0)
	 {
	    printf("开灯\r\n");
		GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);
		delay_ms(2000);
        GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);
		Usart3_buff[0]='\0';	  
	 }
	 /* END */
	}	
	
}

代码讲解

以上代码主要描述了蓝牙模块的初始化以及接收LED灯打开的控制命令过程,其中的核心是蓝牙通信的处理过程。

  1. 串口三中断服务函数
void USART3_IRQHandler(void)
{
if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //接收中断
	{
	  res3 = USART_ReceiveData(USART3); 
	  Usart3_buff[i3]=res3;             //将接收的数据存放于数组中
	  i3++;
	  if(Usart3_buff[i3]=='K')    
		{
		  i3=0;
		}
	  USART_ClearFlag(USART3, USART_FLAG_RXNE);
	}
  
}

通过对前面列举出的蓝牙模块常用AT指令的了解,不难发现,这些AT指令的返回值都带有”OK“字符串,因此我们可以设置当接收到字符‘K’时,说明AT指令返回正确,可以将接收缓存器Usart3_buff清空,方便下一次的接收,但这不具有普遍性,紧针对于本次实验可用,感兴趣的同学可以尝试写出更完整的中断服务函数。

  1. 检测AT指令返回值函数
u8 Find_char(char *a,char *b)  //b为子串
{ 
  if(strstr(a,b)!=NULL)
	    return 0;
	else
			return 1;
}

这个函数中主要是利用了标准库中的字符串匹配函数strstr(a,b),这个函数的功能为,判断字符串a中是否包含了字符串b,匹配成功了就返回1,如果匹配失败,返回null。

  1. 蓝牙模块AT模式与透传模式自动切换
GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_SET);//EN引脚拉高

GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_RESET);//EN引脚拉低

当发送AT指令时,需要将EN引脚设置为高电平,才能进入AT指令模式,当要进入数据传输模式时,需要将EN引脚设置为低电平。

  1. 蓝牙模块波特率设置
uart3_init(38400);

在HC-05蓝牙模块的AT指令模式下,只有将串口波特率设置成38400,才能成功的将AT指令发送到蓝牙模块,并接收。

  1. LED灯控制
if(Find_char((char*)Usart3_buff,"TURNON")==0)
	 {
	    printf("开灯\r\n");
		GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);
		delay_ms(2000);
        GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);
		Usart3_buff[0]='\0';	  
	 }

四、结果显示

在本次测试中,我选择在手机应用商店下载蓝牙调试宝来测试,当蓝牙模块进入透传模式,调试助手成功连接蓝牙模块之后,就可以向其发送数据了,此时我们可以从接收到的数据中解析出是否有我们设置的控制命令,从而达到开关灯的效果。
在这里插入图片描述
在这里插入图片描述

五、注意事项

  • 本次测试中需要清楚的了解蓝牙模块命令响应模式以及自动连接模式的转换细节,只有进入了正确的模式,下一步发送的数据才能被正确的接收。
  • 当蓝牙模块进入透传模式,调试助手成功连接蓝牙模块之后,就可以向其发送数据了,此时我们可以从接收到的数据中解析出是否有我们设置的控制命令,从而达到开关灯的效果。
评论 37
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NoTB

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值