手把手教你使用--常用模块--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 headerDEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);// 打开串口外设的时钟DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);// 将USART Tx的GPIO配置为推挽复用模式
#include "stm32f10x.h" // Device headerGPIO_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**********************/
相关文章:
手把手教你使用--常用模块--HC05蓝牙模块,无线蓝牙串口透传模块,(实例:手机蓝牙控制STM32单片机点亮LED灯)
最近在学STM32,基本的学完了,想学几个模块来巩固一下知识,就想到了蓝牙模块。玩啥好难过有很多博客教怎么连的,但自己看起来还是有点糊涂。模块的原理和知识点我就不讲解了,这里我主要手把手记录一下我是如何对蓝牙模块…...
MyBatis高频面试题
目录 1、Mybatis中#和$的区别 2、Mybatis的编程步骤是什么样的 3...
Redis基础篇
redis的三大特点: 支持多数据类型,支持持久化,单线程 多路IO复用 对键操作的命令: keys * 查看当前库所有key exists key 判断key是否存在 del key 删除 unlink key 非阻塞删除,异步删除 expire key …...
unity的C#学习——静态常量和动态常量的定义与使用
定义常量 在C#中,常量是一种不可改变的量,一旦被定义,其值就不能被修改。C#中有两种类型的常量,静态常量和动态常量。 1、静态常量的定义 静态常量是在编译时就已经确定其值的常量,使用const关键字定义。由于在编译…...
栈----数据结构
栈🔆栈的概念🔆栈的结构🔆栈的实现🔆括号匹配问题🔆结语🔆栈的概念 栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。**进行数据插入和删除操作的一端称为栈顶&am…...
【人人都能读标准】11. 原理篇总结:一个程序的完整执行过程
本文为《人人都能读标准》—— ECMAScript篇的第11篇。我在这个仓库中系统地介绍了标准的阅读规则以及使用方式,并深入剖析了标准对JavaScript核心原理的描述。 我们一路走了很远很远,终于到了本书原理篇的最后一站。 在原理篇中,我们先讲了…...
sheng的学习笔记-IO多路复用,NIO,BIO,AIO
基础概念IO分为几种:同步阻塞的BIO,同步非阻塞的NIO,异步非阻塞AIO,IO多路复用,信号驱动IO(不常用)对于一个network IO,它会涉及到两个系统对象,一个是调用这个IO的proce…...
【Python入门第三十五天】Python丨文件打开
在服务器上打开文件 假设我们有以下文件,位于与 Python 相同的文件夹中。 demofile.txt Hello! Welcome to demofile.txt This file is for testing purposes. Good Luck!如需打开文件,请使用内建的 open() 函数。 open() 函数返回文件对象ÿ…...
jsoup 框架的使用指南
概述 参考: 官方文档jsoup的使用JSoup教程jsoup 在 GitHub 的开源代码 概念简介 jsoup 是一款基于 Java 的 HTML 解析器,它提供了一套非常省力的 API,不但能直接解析某个 URL 地址、HTML 文本内容,而且还能通过类似于 DOM、CS…...
web前端开发和后端开发哪个难度大?
前言 因为涉及到的具体的应用的领域不同,所以说不能简单地说哪一个难,对于前端而言你会感觉到入门会非常的简单,这也是会给许多人一种错觉,前端很简单,但是只能说是在入门理解上是有利于新手的,前端在主要…...
认证与认可之间有什么区别和联系?
认证与认可之间有什么区别和联系? 当今社会,认证与认可已经深入企业的生活,那么认证与认可之间到底有什么区别和联系呢? 认证,是指由认证机构证明产品、服务、管理体系符合相关技术规范、相关技术规范的强制性要求或者…...
【Java|golang】1626. 无矛盾的最佳球队---最长子序列,不连续,二维数组排序
假设你是球队的经理。对于即将到来的锦标赛,你想组合一支总体得分最高的球队。球队的得分是球队中所有球员的分数 总和 。 然而,球队中的矛盾会限制球员的发挥,所以必须选出一支 没有矛盾 的球队。如果一名年龄较小球员的分数 严格大于 一名…...
C++ 八股文(简单面试题)
1.左值 可寻址变量,持久性; 2.右值 没有变量名,不可寻址,短暂性; 3.指针 指向的内存地址,指针变量存储的就是指向的对象的首地址 4.引用 为一个变量起别名,定义引用的时候一定要初始化&a…...
RK3588平台开发系列讲解(显示篇)DP显示调试方法
平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、查看 connector 状态二、强制使能/禁⽤ DP三、DPCP 读写四、Type-C 接口 Debug五、查看 DP 寄存器六、查看 VOP 状态七、查看当前显示时钟八、调整 DRM log 等级沉淀、分享、成长,让自己和他人都能有所收获!😄…...
模拟请求发生跨域问题
参考:传送门 问题产生: Access to XMLHttpRequest at ‘http://test-cms.jinhuahuolong.com/api/pages/list’ from origin ‘null’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resourc…...
Qt实践项目:仿Everything软件实现一个QtEverything
⭐️我叫忆_恒心,一名喜欢书写博客的在读研究生👨🎓。 如果觉得本文能帮到您,麻烦点个赞👍呗! 近期会不断在专栏里进行更新讲解博客~~~ 有什么问题的小伙伴 欢迎留言提问欧,喜欢的小伙伴给个三…...
WEB网站服务(一)
1.1 Apache网站服务基础1.1.1Apache简介Apache HTTP Server是开源软件项目的杰出代表,基于标准的HTTP网络协议提供网页浏览服务。Apache服务器可以运行在Linux,UNIX,windows等多种操作系统平台中。1.Apache的起源1995年,Apache服务程序的1.0版…...
Python数据分析script必备知识(一)
Python数据分析script必备知识(一) 1.重定向终端输出内容 使生成的结果移动到其他位置 # 重定向, 使生成的结果移动到其他位置 import syssys.stderr = sys.stdoutprint(dir(sys)) # ,,,,,__stderr__, __stdin__, __stdout__,,,,,,# 使用场景:脚本上线时,想要把输出结果…...
初识linux之管道
一、进程间通信的概念大家都知道,进程是具有独立性的,因为一个程序运行起来生成进程时,也会生成它的进程结构体,即PCB,然后然后通过进程结构体中的结构体指针找到它的虚拟地址空间,然后再通过它的页表映射到…...
C++成神之路 | 第一课【步入C++的世界】
目录 一、认识C++ 1.1、关于 C++ 1.2、C++的前世今生 1.2.1、C+...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战
“🤖手搓TuyaAI语音指令 😍秒变表情包大师,让萌系Otto机器人🔥玩出智能新花样!开整!” 🤖 Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制(TuyaAI…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...
招商蛇口 | 执笔CID,启幕低密生活新境
作为中国城市生长的力量,招商蛇口以“美好生活承载者”为使命,深耕全球111座城市,以央企担当匠造时代理想人居。从深圳湾的开拓基因到西安高新CID的战略落子,招商蛇口始终与城市发展同频共振,以建筑诠释对土地与生活的…...
Linux nano命令的基本使用
参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时,显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement
Cilium动手实验室: 精通之旅---13.Cilium LoadBalancer IPAM and L2 Service Announcement 1. LAB环境2. L2公告策略2.1 部署Death Star2.2 访问服务2.3 部署L2公告策略2.4 服务宣告 3. 可视化 ARP 流量3.1 部署新服务3.2 准备可视化3.3 再次请求 4. 自动IPAM4.1 IPAM Pool4.2 …...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...
五子棋测试用例
一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏,有着深厚的文化底蕴。通过将五子棋制作成网页游戏,可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家,都可以通过网页五子棋感受到东方棋类…...
