手把手教你使用--常用模块--HC05蓝牙模块,无线蓝牙串口透传模块,(实例:手机蓝牙控制STM32单片机点亮LED灯)

最近在学STM32,基本的学完了,想学几个模块来巩固一下知识,就想到了蓝牙模块。玩啥好难过有很多博客教怎么连的,但自己看起来还是有点糊涂。模块的原理和知识点我就不讲解了,这里我主要手把手记录一下我是如何对蓝牙模块进行学习和使用的。

所使用的资料和工具我会放在最后的链接里,大家有需要的可以自行下载。

模块名称:HC-05蓝牙串口通信模块

其他模块:USB转TTL模块、杜邦线、蓝牙串口助手app

蓝牙模块的前期调试

因为我们只是使用到蓝牙模块的透传功能,只需要用到4个引脚(RXT、TXD、GND、VCC)

先使用杜邦线将USB转TTL模块和HC-05蓝牙模块相连

两模块共电、共地、两模块的TX和RX交换相接(USB转TTL的TX(RX)接蓝牙的RX(TX))

如图所示:

然后将USB转TTL模块插到电脑上,通过串口助手进行调试。

蓝牙模块通讯模式有两种工作方式:命令响应工作模式和自动连工作模式(在自动连接工作模式下又可分为主、从和回环三种角色)

        ·当模块处于自动连接工作模式时,将自动根据事先设定的方式连接的数据传输;

        ·当模块处于命令响应工作模式时能执行AT命令,用户可向模块发送各种AT 指令,为模块设定控制参数或发布控制命令。

如何进入命令响应:

给模块上电即插USB的时候,按住蓝牙HC-05模块的那个小按键,此时模块进入AT模式

蓝牙模块上有一个小灯,灯快闪的时候,就是自动连接模式。慢闪的时候,就是命令响应工作模式

命令响应模式的波特率固定为38400,可以直接使用串口助手发送AT指令。

AT命令

AT指令不区分大小写,但是都要以回车符结尾

下面是常用的AT指令

 注意:AT+NAME?可能是没有返回数据的,我们直接设置蓝牙名称就可以了

我们接下来主要配置的就是

蓝牙名称和串口参数(波特率、停止位、校验位)

如图:

设置好之后把usb拔下来,重新上电的时候会默认为自动连接模式,此时使用手机的蓝牙助手对蓝牙模块进行连接,就可以通讯了。蓝牙助手我也会放在后面的资料链接里。

 将串口助手波特率设置为115200,在手机蓝牙中发送信息,会在串口助手中显示出来。

 最后,我们将在STM32开发板中连接蓝牙进行信息传输,控制LED灯

源码我将会放在后面的资料里一起打包。

这里我们使用串口1,因为串口1是我开发板的下载串口,所以要先下载代码之后再连接蓝牙模块的TX和RX,如果使用其他串口进行通讯改为其他串口即可,连接方式如图所示:

 蓝牙模块的RX连PA9,TX连PA10,VCC接板载的5V,GND接板子的GND即可

由于我使用的是野火的开发板,所用到的LED灯是个RGB灯,大家只需要初始化一下串口,然后看一下main函数里面的逻辑来实现自己板子的LED灯即可。也可以在中断函数里对灯进行操作

接下来就可以举一反三,使用蓝牙返回信息等操作了。

资料有需要自行提取:链接:https://pan.baidu.com/s/1iGrbTiivAsTwzd9wDLYFaQ 
提取码:3sp6

资料里面还有一个HC蓝牙助手,可以自定义按钮发送信息。

串口控制LED灯的代码如下:

usart.c:

#include "bsp_usart.h"

//static void NVIC_Configuration(void)    //配置中断优先级,这里不使用中断,所以屏蔽
//{
//  NVIC_InitTypeDef NVIC_InitStructure;
//  
//  /* 嵌套向量中断控制器组选择 */
//  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//  
//  /* 配置USART为中断源 */
//  NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
//  /* 抢断优先级*/
//  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
//  /* 子优先级 */
//  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
//  /* 使能中断 */
//  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
//  /* 初始化配置NVIC */
//  NVIC_Init(&NVIC_InitStructure);
//}

void USART_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;

	// 打开串口GPIO的时钟
#include "stm32f10x.h"                  // Device header
	DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
	
	// 打开串口外设的时钟
	DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);

	// 将USART Tx的GPIO配置为推挽复用模式
#include "stm32f10x.h"                  // Device header
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

  // 将USART Rx的GPIO配置为浮空输入模式
	GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
	
	// 配置串口的工作参数
	// 配置波特率
	USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
	// 配置 针数据字长
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	// 配置停止位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	// 配置校验位
	USART_InitStructure.USART_Parity = USART_Parity_No ;
	// 配置硬件流控制
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	// 配置工作模式,收发一起
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	// 完成串口的初始化配置
	USART_Init(DEBUG_USARTx, &USART_InitStructure);
	
//	// 串口中断优先级配置
//	NVIC_Configuration();
//	
//	// 使能串口接收中断
//	USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);	
	
	// 使能串口
	USART_Cmd(DEBUG_USARTx, ENABLE);	    
}

/* 发送一个字节 */
void Usart_SendByte(USART_TypeDef* pUSARTx, uint8_t data)
{
	USART_SendData(pUSARTx, data);
	while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
}

/* 发送两个字节的数据 */
void Usart_SendHalfWord(USART_TypeDef* pUSARTx, uint16_t data)
{
	uint8_t temp_h,temp_l;
	
	temp_h = (data&0xff00) >> 8 ;
	temp_l = data&0xff;
	
	USART_SendData(pUSARTx, temp_h);
	while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
	
	USART_SendData(pUSARTx, temp_l);
	while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET );
}

/* 发送8位数据的数组 */
void Usart_SendArray(USART_TypeDef* pUSARTx, uint8_t *array,uint8_t num)
{
	uint8_t i;
	for( i=0; i<num; i++ )
  {
		Usart_SendByte(pUSARTx, array[i]);
	}
	while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );
}

/* 发送字符串 */
void Usart_SendStr(USART_TypeDef* pUSARTx, uint8_t *str)
{
	uint8_t i=0;
	do
  {
		Usart_SendByte(pUSARTx, *(str+i));
		i++;
	}while(*(str+i) != '\0');
	while( USART_GetFlagStatus(pUSARTx, USART_FLAG_TC) == RESET );
}

///重定向c库函数printf到串口,重定向后可使用printf函数
int fputc(int ch, FILE *f)
{
		/* 发送一个字节数据到串口 */
		USART_SendData(DEBUG_USARTx, (uint8_t) ch);
		
		/* 等待发送完毕 */
		while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);		
	
		return (ch);
}

///重定向c库函数scanf到串口,重写向后可使用scanf、getchar等函数
int fgetc(FILE *f)
{
		/* 等待串口输入数据 */
		while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);

		return (int)USART_ReceiveData(DEBUG_USARTx);
}

 main.c

int main(void)
{	
	uint8_t ch;
	USART_Config();
	LED_GPIO_Config();
	
	printf( "这是一个串口控制RGB灯的程序\n" );
 
	while (1)
	{
		ch = getchar();
	  printf( "ch=%c\n",ch );
		
		switch(ch)
   {
			case '1': LED_RED;
				break;
		 
			case '2': LED_GREEN;
			  break;
		 
			case '3': LED_BLUE;
			  break;
		 
			default: LED_RGBOFF;
		    break;
	 }
	}
}

 led.c

 
#include "bsp_led.h"   

 /**
  * @brief  初始化控制LED的IO
  * @param  无
  * @retval 无
  */
void LED_GPIO_Config(void)
{		
		/*定义一个GPIO_InitTypeDef类型的结构体*/
		GPIO_InitTypeDef GPIO_InitStructure;

		/*开启LED相关的GPIO外设时钟*/
		RCC_APB2PeriphClockCmd( LED1_GPIO_CLK | LED2_GPIO_CLK | LED3_GPIO_CLK, ENABLE);
		/*选择要控制的GPIO引脚*/
		GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN;	

		/*设置引脚模式为通用推挽输出*/
		GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   

		/*设置引脚速率为50MHz */   
		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 

		/*调用库函数,初始化GPIO*/
		GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);	
		
		/*选择要控制的GPIO引脚*/
		GPIO_InitStructure.GPIO_Pin = LED2_GPIO_PIN;

		/*调用库函数,初始化GPIO*/
		GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure);
		
		/*选择要控制的GPIO引脚*/
		GPIO_InitStructure.GPIO_Pin = LED3_GPIO_PIN;

		/*调用库函数,初始化GPIOF*/
		GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStructure);

		/* 关闭所有led灯	*/
		GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
		
		/* 关闭所有led灯	*/
		GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PIN);	 
    
    /* 关闭所有led灯	*/
		GPIO_SetBits(LED3_GPIO_PORT, LED3_GPIO_PIN);
}

/*********************************************END OF FILE**********************/

  • 116
    点赞
  • 1011
    收藏
    觉得还不错? 一键收藏
  • 26
    评论
好的,下面是HC-05蓝牙模块STM32连接点的步骤及手把手学: 材料准备: - HC-05蓝牙模块 - STM32开发板 - 杜邦线若干 - LED一个 - 220欧姆电阻一个 步骤: 1. 将HC-05蓝牙模块的VCC接5V,GND接GND,TX接STM32的RX,RX接STM32的TX。 2. 在STM32上选择一个IO口(例如PA5),将该IO口通过220欧姆电阻连接到LED的阳极上,LED的阴极连接到GND。 3. 下载并打开Keil或者其他STM32编程工具,创建一个新工程。 4. 在工程中添加HC-05蓝牙模块驱动程序库文件(一般为.h和.c文件)。 5. 编写代码,初始化串口,并设置波特率为9600,与HC-05蓝牙模块通信。同时,将PA5口作为输出口初始化。 6. 在程序中使用while循环,不断读取HC-05蓝牙模块发送来的数据,并通过PA5口控制LED的亮灭。 具体代码实现如下(以STM32F103C8T6为例): ``` #include "stm32f10x.h" #include "hc05.h" int main(void) { uint8_t data; GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); USART_Cmd(USART1, ENABLE); while (1) { if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) { data = USART_ReceiveData(USART1); if (data == '1') { GPIO_SetBits(GPIOA, GPIO_Pin_5); } else if (data == '0') { GPIO_ResetBits(GPIOA, GPIO_Pin_5); } } } } ``` 注:以上代码中的hc05.h文件是自己编写的HC-05蓝牙模块驱动程序库文件,可根据实际情况进行修改。 完成以上步骤后,将程序烧录到STM32开发板上,打开手机蓝牙并连接HC-05蓝牙模块,即可通过发送字符1或0控制LED的亮灭。
评论 26
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值