一:蓝牙模块HC-05 1:硬件引脚配置: | 标号 | PIN | 说明 | |------|-------|---------------------------------------| | 1 | START | 状态引出引脚(未连接/连接输出信号时) | | 2 | RXE | 接收端 | | 3 | TXE | 发送端 | | 4 | GND | 模块供电负载 | | 5 | VCC | 模块供电正极 | | 6 | EN | 继电器(需进入命令模式时拨3.3V) |
(上表中VCC接5v,EN接3.3v,START不接)
2:AT设置工作横式 ·
1.自动连接横式,又称为透传模式。
2.AT横式 (AT mode)进入AT横式的两种方法:
1.按住引脚或EN引脚拉高 (接入3.3V),此时灯是慢闪,进入AT模式,波特率默认是38400;这个模式我们叫做原始模式,原始模式下一直处于AT命令模式状态。
2.HC-05上电开机,红灯快闪,按住按键戏EN引脚拉高 (接入3.3V) , HC.05进入AT命令模式,默认波特率是9600, 这种模式下是正常模式,正常模式下只有按住按键或拉高EN引1脚才处于AT命令状态。
|注意:如果波待率没有设置正确,AT命令是执行无效的。
(
HC-05 蓝牙模块工作模式详解
工作模式分类
自动连接模式(透传模式)
模块默认工作状态
自动搜索并连接配对设备
建立双向数据传输通道(串口透传)
指示灯状态:红灯快闪(约1秒2次)
AT模式(配置模式)
用于参数配置的专用模式
通过AT指令修改名称、波特率、配对密码等
不支持数据传输
指示灯状态:慢闪(约2秒1次)
AT模式进入方法
方法1:原始AT模式(永久配置状态)
项目 | 说明 |
---|---|
进入条件 | 上电前按住按键或将EN引脚接3.3V高电平 |
指示灯 | 慢闪(持续状态) |
波特率 | 固定38400 |
特性 | 模块始终处于AT命令状态,适合批量烧录配置 |
退出方式 | 必须断电重启(不按按键) |
方法2:临时AT模式(动态切换状态)
项目 | 说明 |
---|---|
进入条件 | 正常启动后(红灯快闪时),按住按键或拉高EN引脚至3.3V |
指示灯 | 快闪→慢闪(状态切换) |
波特率 | 默认96000(可修改) |
特性 | 仅当按键/EN保持高电平时处于AT状态,松开即返回透传模式 |
退出方式 | 松开按键/EN引脚拉低 |
关键注意事项
波特率匹配
原始模式:必须使用38400
临时模式:默认96000(除非已修改)
不匹配将导致AT指令无响应
电气特性
EN引脚需稳定接入3.3V(不可浮空)
电压超过3.3V可能损坏模块
指令格式要求
所有AT指令必须以换行符结束(
\r\n
)参数需严格遵循格式(如
AT+NAME="HC05"
)
配置保存机制
原始模式:配置即时生效(也需要重启加
AT+RESET
)临时模式:需发送
AT+RESET
保存配置
)
3.基本配置(所有AT命令都必须换行)
正常模式下是9600, AT模式波特率固定为 38400,8位数据位,1位停止位,无奇偶校验的通信方式
·发送 AT\r\n, 回复 OK
·发送 AT+UART?\r\n,, 回复 +UART9600, 0, 0
·发送 AT+UART=115200, 0, 0\r\n, 回复OK。
通过上述步骤波特率即配置成功。
·发送 AT+NAME="XXXX",修改蓝牙模块名称为XXXX
·发送 AT+ROLE=0, 蓝牙模式即为从模式
。发送AT+CMODE=1, 蓝牙连接模式为任意地址连接模式,也就是说该模块可以被任意蓝牙设备连接
。发送 AT+PSWD=1234, 蓝牙配对密码为 1234
·发送 AT+UART=9600, 0, 0, 蓝牙通信串口波特率为 9600,停止位1位,无校验位
配置完成,需要重启一次 AT+RESET
4: 蓝牙项目步骤
·1.蓝牙模块AT模式基础配置
。 1.蓝牙连接 ch340模块接线 TX,RX、VCC、GND、EN五根引脚
。 2.AT指令配置波特率、蓝牙名称、从模式、配对密码
•2.蓝牙硬件连接32单片机TX,RX、VCC、GND、四根引脚
·3.初始化蓝牙连接申口的时钟,引脚和外设配置
·4.串口接收中断服务函数实现数据的接收和发送
usart.c
#include "stm32f10x.h"
#include "usart.h"
#include "stdio.h"
void my_usart2_Init()//千万不要和32库里面串口定于的名字一样,不然会报错
{
GPIO_InitTypeDef my_usart_Initstruct;
USART_InitTypeDef USART_Initstruct;
NVIC_InitTypeDef NVIC_Initstruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA ,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE );
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
my_usart_Initstruct.GPIO_Pin=GPIO_Pin_2 ;
my_usart_Initstruct.GPIO_Mode=GPIO_Mode_AF_PP ;
my_usart_Initstruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &my_usart_Initstruct);
my_usart_Initstruct.GPIO_Pin=GPIO_Pin_3;
my_usart_Initstruct.GPIO_Mode=GPIO_Mode_IN_FLOATING ;
GPIO_Init(GPIOA, &my_usart_Initstruct);
USART_Initstruct.USART_BaudRate=9600;
USART_Initstruct.USART_HardwareFlowControl= USART_HardwareFlowControl_None ;
USART_Initstruct.USART_Mode= USART_Mode_Rx | USART_Mode_Tx;
USART_Initstruct.USART_Parity= USART_Parity_No;
USART_Initstruct.USART_StopBits=USART_StopBits_1 ;
USART_Initstruct.USART_WordLength=USART_WordLength_8b;
USART_Init(USART2,&USART_Initstruct );
USART_Cmd(USART2, ENABLE);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
NVIC_Initstruct.NVIC_IRQChannel= USART2_IRQn ;
NVIC_Initstruct.NVIC_IRQChannelPreemptionPriority=0;
NVIC_Initstruct.NVIC_IRQChannelSubPriority=0;
NVIC_Initstruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_Initstruct);
}
void my_usart_Init()//千万不要和32库里面串口定于的名字一样,不然会报错
{
GPIO_InitTypeDef my_usart_Initstruct;
USART_InitTypeDef USART_Initstruct;
NVIC_InitTypeDef NVIC_Initstruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_USART1,ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
my_usart_Initstruct.GPIO_Pin=GPIO_Pin_9 ;
my_usart_Initstruct.GPIO_Mode=GPIO_Mode_AF_PP ;
my_usart_Initstruct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &my_usart_Initstruct);
my_usart_Initstruct.GPIO_Pin=GPIO_Pin_10 ;
my_usart_Initstruct.GPIO_Mode=GPIO_Mode_IN_FLOATING ;
GPIO_Init(GPIOA, &my_usart_Initstruct);
USART_Initstruct.USART_BaudRate=115200;
USART_Initstruct.USART_HardwareFlowControl= USART_HardwareFlowControl_None ;
USART_Initstruct.USART_Mode= USART_Mode_Rx | USART_Mode_Tx;
USART_Initstruct.USART_Parity= USART_Parity_No;
USART_Initstruct.USART_StopBits=USART_StopBits_1 ;
USART_Initstruct.USART_WordLength=USART_WordLength_8b;
USART_Init(USART1,&USART_Initstruct );
USART_Cmd(USART1, ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
NVIC_Initstruct.NVIC_IRQChannel= USART1_IRQn ;
NVIC_Initstruct.NVIC_IRQChannelPreemptionPriority=0;
NVIC_Initstruct.NVIC_IRQChannelSubPriority=0;
NVIC_Initstruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_Initstruct);
}
void My_Usart_Send_Byte(USART_TypeDef* USARTx, uint16_t Data)
{
USART_SendData( USARTx, Data);
while(USART_GetFlagStatus( USARTx, USART_FLAG_TXE) != SET);
}
void My_Usart_Send_Sting(USART_TypeDef* USARTx,char * str)
{
uint16_t i=0;
do
{
My_Usart_Send_Byte(USARTx,*(str+i));
i++;
}while(*(str+i) != '\0');
while(USART_GetFlagStatus( USARTx, USART_FLAG_TC) != SET);
}
int fputc(int ch, FILE * p)
{
USART_SendData( USART1, (u8)ch);
while(USART_GetFlagStatus( USART1, USART_FLAG_TXE) != SET);
return ch;
}
void USART1_IRQHandler()
{
char str;
if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)
{
str=USART_ReceiveData(USART1);
printf("shuju=%c\r\n",str);
if(str=='0')
{
GPIO_ResetBits( GPIOA, GPIO_Pin_1);
printf("LED IS ON\r\n");
}
if(str=='1')
{
GPIO_SetBits( GPIOA, GPIO_Pin_1);
printf("LED IS OFF\r\n");
}
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
}
}
void USART2_IRQHandler()
{
char str;
if(USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET)
{
str=USART_ReceiveData(USART2);
printf("shuju=%c\r\n",str);
if(str=='0')
{
GPIO_ResetBits( GPIOA, GPIO_Pin_1);
printf("LED IS ON\r\n");
}
if(str=='1')
{
GPIO_SetBits( GPIOA, GPIO_Pin_1);
printf("LED IS OFF\r\n");
}
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
}
}
usart.h
#ifndef USART_H_
#define USART_H_
void my_usart_Init(void);
void my_usart2_Init(void);
void My_Usart_Send_Byte(USART_TypeDef* USARTx, uint16_t Data);
void My_Usart_Send_Sting(USART_TypeDef* USARTx, char * str);
#endif
main.c
#include "stm32f10x.h"
#include "main.h"
#include "led.h"
#include "Bear.h"
#include "key.h"
#include "relay.h"
#include "shake.h"
#include "wireless.h"
#include "exti_key.h"
#include "usart.h"
#include "stdio.h"
void delay(uint16_t time)//延时1ms 软件延时粗延时
{
uint16_t i=0;
while(time --)
{
i=12000;
while(i --);
}
}
int main()
{
my_usart_Init();
my_usart2_Init();
LED_Init();
// My_Usart_Send_Byte( USART1, 'A');
// My_Usart_Send_Byte( USART1, 'B');
// My_Usart_Send_Byte( USART1, 'C');
// My_Usart_Send_Sting( USART1, "kobe \r\n");
printf("kobe is king \r\n");
while(1)
{
// USART_SendData( USART1, 'A');
}
}
今日心得
1:用户提到AT模式使用的是38400波特率,但查询UART设置时返回的却是9600?
核心原因:
双波特率机制:
AT模式波特率:固定38400(进入配置模式时使用)
工作模式波特率:可配置(透传模式使用的波特率)
AT+UART? 命令的本质:
查询的不是当前AT模式波特率
查询的是透传模式(工作模式)的波特率设置
✅
AT+UART?
只显示工作模式波特率,不显示AT模式波特率✅ AT模式波特率固定为38400且不可更改
✅ 您看到的9600是模块在透传模式下的通信波特率
✅ 您的所有AT命令执行成功(每个都返回OK)
使用建议:
配置时:
始终使用38400与AT模式通信
AT命令只修改透传模式参数
透传使用时:
使用配置的波特率(您最后设为9600)
需与配对设备保持相同波特率
提示:当模块无响应时,优先检查:
AT模式必须用38400
透传模式用配置的波特率(如9600)
EN引脚保持稳定连接
2:AT+ROLE=0为蓝牙模式的从模式,解释一下什么是从模式和代码
什么是从模式(Slave Mode)?
当设置 AT+ROLE=0
时,HC-05 模块被配置为从模式,这是蓝牙通信中的被动角色:
特性 | 说明 |
---|---|
角色定位 | 被动等待连接(类似"服务员") |
连接行为 | 无法主动扫描/连接其他设备,只能被主设备(Master)发现并连接 |
典型应用 | 作为外围设备(如传感器、执行器)与手机/电脑配对 |
工作状态 | 启动后广播自身存在(可被手机蓝牙列表检测到) |
连接限制 | 同一时间只能被一个主设备连接(1:1连接) |
✅ 对比主模式(AT+ROLE=1
):主设备可主动扫描连接多个从设备(类似"顾客")
3:设置密码为4位数