前言

在物联网(IoT)入门项目中,无线通信是必不可少的一环。蓝牙HC-05模块因其价格低廉、使用简单(串口透传),成为了嵌入式开发者的首选。本文将带你从HC-05的工作原理出发,手把手教你如何通过AT指令配置模块,并使用STM32CubeMX与HAL库实现手机蓝牙控制LED灯的亮灭。


第一部分:HC-05蓝牙模块原理简述

1.1 什么是“串口透传”?

HC-05的核心功能是SPP(Serial Port Profile)串口透传
简单来说,它就像一根无形的串口线。当单片机向HC-05发送数据时,HC-05通过无线电波发给手机;手机发数据给HC-05时,HC-05会将其转化为串口信号发给单片机。

  • 单片机视角:我只是在和一个普通的串口设备(UART)说话。
  • 手机视角:我连接了一个蓝牙设备。

1.2 两种工作模式

HC-05有两个非常重要的状态,初学者容易混淆:

  1. 数据传输模式(正常模式)
    • 模块上电后,LED快闪(未连接)或双闪(已连接)。
    • 此时发送的数据会被直接无线传输,模块不解析AT指令。
  2. AT指令模式(配置模式)
    • 模块上电前按住按钮,LED慢闪(约2秒闪一次)。
    • 此时通过串口发送特定指令(如改名、改波特率),模块会回复“OK”,但不进行无线传输

1.3 物理接口

  • VCC/GND:供电(通常3.6V-6V,注意信号电平通常兼容3.3V)。
  • TXD:发送端,接单片机的RX。
  • RXD:接收端,接单片机的TX(需分压或直接接3.3V单片机)。
  • EN/KEY:使能/模式切换引脚(用于进入AT模式)。
  • STATE:状态指示(连接成功输出高电平,未连接低电平)。

第一部分 深度剖析:蓝牙技术与HC-05架构原理

在动手连线之前,我们需要先理解蓝牙(Bluetooth)究竟是如何实现无线通信的。HC-05之所以好用,是因为它在芯片内部帮我们将复杂的无线射频协议转换成了简单的串口信号。

1.1 无线电基础:2.4GHz ISM频段

蓝牙和Wi-Fi一样,都工作在 2.4GHz ISM(工业、科学、医疗)频段。这是一个全球通用的免费频段,无需授权即可使用。

  • 物理层:蓝牙通过无线电波发送二进制数据(0和1)。
  • 挑战:既然Wi-Fi、微波炉、无线鼠标都在用2.4GHz,蓝牙为什么不会被严重干扰?这就涉及到了蓝牙的核心技术——FHSS

1.2 抗干扰的核心:FHSS(跳频扩频技术)

这是蓝牙通信最精妙的地方。

  • 原理:蓝牙不会一直占用某一个固定的频率传输数据。它将2.4GHz频段划分为79个信道(每个信道带宽1MHz)。
  • 跳频:发送端和接收端商量好一个算法,每秒钟跳变1600次频率。比如这一毫秒在信道1发数据,下一毫秒跳到信道58,再下一毫秒跳到信道12。
  • 结果:即使某个频段(比如信道5)有很强的Wi-Fi干扰,蓝牙也只会损失极少的数据包,并在下一个瞬间跳到干净的信道继续传输。这就是为什么蓝牙连接如此稳定的原因。

1.3 网络拓扑:主从模式(Master-Slave)

蓝牙通信必须基于主从关系建立连接(Piconet 微网):

  • 主设备(Master):发起连接的设备,决定跳频的序列和时钟同步。在我们的项目中,智能手机是主设备。
  • 从设备(Slave):等待连接的设备,跟随主设备的指令进行跳频。在我们的项目中,HC-05模块是从设备。
  • 关系:一个主设备最多可以同时连接7个从设备,但一个从设备(HC-05)同一时间只能连接一个主设备。

1.4 HC-05的“大脑”:SPP协议与蓝牙版本

HC-05 是一款 经典蓝牙(Bluetooth Classic) 模块,通常遵循 蓝牙 2.0 + EDR 标准。

  • 协议栈(Profile):蓝牙协议栈非常复杂,包含L2CAP、RFCOMM等层。但HC-05只为我们暴露了一个最顶层的应用文件——SPP(Serial Port Profile,串口配置文件)
  • SPP的作用:它的作用就是模拟RS-232串口线。它让无线信道在两端的设备看来,就像是一条透明的电线。
  • 注意:由于HC-05是经典蓝牙,它不支持苹果iOS设备的直接连接(iPhone通常只支持低功耗蓝牙BLE,如HC-08或HC-10)。如果你的项目需要连iPhone,需要换用BLE模块,但原理类似。

1.5 硬件内部架构

剥开HC-05的蓝色热缩管,你会看到两部分核心电路:

  1. CSR BC417芯片:这是核心蓝牙芯片,负责射频发送、FHSS跳频算法、基带处理。它内部其实跑着一套复杂的嵌入式系统。
  2. Flash存储器:存储了CSR芯片的固件和配置信息(我们用AT指令修改的名字和密码就存在这里)。
  3. 底板电路:由于CSR芯片工作电压是3.3V且引脚微小,我们买到的HC-05模块带有一个绿色底板,上面有LDO(稳压芯片)将5V转为3.3V,并引出了TX/RX/VCC/GND引脚,方便单片机连接。

第二部分:HC-05的初始化与烧录(AT指令配置)

在连接STM32之前,我们需要先配置模块的波特率、名称和配对密码。我们需要一个USB转TTL模块(如CH340)。

2.1 硬件连接(进入AT模式)

  1. 接线
    • USB-TTL 5V -> HC-05 VCC
    • USB-TTL GND -> HC-05 GND
    • USB-TTL TX -> HC-05 RX
    • USB-TTL RX -> HC-05 TX
  2. 进入方法
    • 先按住HC-05模块上的微动开关(Button)不放
    • 给模块上电。
    • 看到LED进入慢闪状态(约2秒闪一次)后,松开按钮。

2.2 串口助手配置

打开电脑上的串口调试助手(如XCOM、SSCOM):串口助手

  • 波特率38400(HC-05进入AT模式的默认波特率通常是38400,无论通信波特率是多少)。
  • 停止位/数据位:1位停止位,8位数据位,无校验。
  • 发送设置:勾选“发送新行”(发送\r\n),这点非常重要,否则模块无响应。

2.3 常用AT指令实战

在发送框输入以下指令(不区分大小写):

  1. 测试指令

    • 发送:AT
    • 返回:OK (说明连接正常)

  1. 恢复出厂设置

    • 发送:AT+ORGL
    • 返回:OK

  1. 修改蓝牙名称

    • 发送:AT+NAME=MySTM32_BT
    • 返回:OK

  1. 修改配对密码

    • 发送:AT+PSWD=1234或则123456(有的模块是默认6位密码,有的默认4位)
    • 返回:OK

  1. 配置通信波特率(重要!)

    • 发送:AT+UART=9600,0,0 (设置为9600波特率,1停止位,无校验)
    • 返回:OK
    • 注意:这里设置的是之后与STM32通信的速率,通常选9600。

  1. 设置主从模式

    • 发送:AT+ROLE=0 (0为从机Slave,手机连模块必须设为从机)
    • 返回:OK

配置完成后,断电,准备连接STM32。


第三部分:STM32CubeMX 配置

假设我们使用 STM32F103C8T6,我们将使用 USART1 连接蓝牙,PC13 控制板载LED。

3.1 基础配置

  1. System Core -> SYS:Debug选择 Serial Wire
  2. System Core -> RCC:HSE选择 Crystal/Ceramic Resonator
  3. Clock Configuration:将HCLK配置为72MHz。

3.2 串口配置 (USART1)

  1. 点击 Connectivity -> USART1
  2. Mode:选择 Asynchronous(异步通信)。
  3. Parameter Settings
    • Baud Rate: 9600 (必须与刚才AT指令设置的一致)。
    • Word Length: 8 Bits。
    • Parity: None。
    • Stop Bits: 1。

  1. NVIC Settings (中断设置):
    • 勾选 USART1 global interrupt -> Enabled
    • 原理:我们需要利用串口接收中断,当蓝牙发来数据时,CPU自动跳过去处理,而不是死等。

3.3 LED引脚配置

  1. 在右侧芯片图找到 PC13
  2. 设置为 GPIO_Output
  3. GPIO Settings:User Label 命名为 LED

3.4 生成代码

点击 GENERATE CODE,生成Keil工程。


第四部分:代码编写 (Keil MDK)

我们需要在生成的代码中添加串口接收逻辑。

4.1 定义变量

在 main.c 的 /* USER CODE BEGIN PV */ 区域添加:

/* USER CODE BEGIN PV */
uint8_t rx_data; // 用于存放接收到的1个字节数据
/* USER CODE END PV */

4.2 开启接收中断

在 main() 函数的 /* USER CODE BEGIN 2 */ 区域开启第一次中断接收:

/* USER CODE BEGIN 2 */
// 开启串口接收中断,接收1个字节存入 rx_data
HAL_UART_Receive_IT(&huart1, &rx_data, 1);
/* USER CODE END 2 */

4.3 重写中断回调函数

在 main.c 底部 /* USER CODE BEGIN 4 */ 区域,编写接收完成后的处理逻辑:

/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    // 判断是否是串口1触发的中断
    if(huart->Instance == USART1)
    {
        // 逻辑处理:假设收到字符 '1' 开灯,收到 '0' 关灯
        if(rx_data == '1')
        {
            // 对于PC13,通常低电平点亮,根据实际电路调整
            HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); // 开灯
        }
        else if(rx_data == '0')
        {
            HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);   // 关灯
        }
        
        // 重点!处理完数据后,必须再次开启中断,否则只能接收一次
        HAL_UART_Receive_IT(&huart1, &rx_data, 1);
    }
}
/* USER CODE END 4 */

第五部分:连接与测试

5.1 最终硬件接线

将STM32断电,连接HC-05:

  • HC-05 VCC -> STM32 5V
  • HC-05 GND -> STM32 GND
  • HC-05 TX -> STM32 RX (PA10)
  • HC-05 RX -> STM32 TX (PA9)

注意:这次不要按按钮,直接上电,HC-05指示灯应快闪,进入配对模式。

5.2 手机端操作

  1. 下载蓝牙串口APP(安卓推荐“蓝牙串口助手”或“Bluetooth Electronics”)。
  2. 打开手机蓝牙,搜索设备 MySTM32_BT(我们在AT模式改的名字)。
  3. 点击连接,输入密码 123456
  4. 连接成功后,HC-05指示灯变为双闪或常亮。

5.3 控制测试

  1. 在APP的对话框模式下,选择“ASCII”或“字符模式”发送。
  2. 发送数字 1 -> 观察开发板LED是否点亮。
  3. 发送数字 0 -> 观察开发板LED是否熄灭。

如果不熟悉CUBEmx可以去小B站搜索keysking,他的快速入门教程堪称第一。

总结

通过本文,我们完成了从HC-05的原理理解,到使用USB-TTL修改参数,最后结合STM32CubeMX和中断代码实现无线控制的全过程。
掌握了这个基础,你就可以扩展更多功能,例如:

  • 反向传输:STM32采集温湿度数据,通过 HAL_UART_Transmit 发送给手机显示。
  • PWM调光:发送不同的字符控制LED的亮度。
  • 小车控制:发送 'W', 'A', 'S', 'D' 控制蓝牙小车的前后左右。

注意事项:蓝牙模块有时候需要的是3.6到6v供电,接3.3v会搜索不到模块,直接接5V供电

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐