一、模块选型与原理概述

蓝牙串口透传模块本质是一个无线串口桥:MCU通过UART发送数据,模块将其封装为蓝牙协议包发出;接收端模块解包后从UART输出。开发者无需关心蓝牙协议栈,只需操作串口。

  • HC-05:经典蓝牙2.0+EDR,支持主从模式切换,适合与手机/电脑配对,传输速率可达2Mbps(实际有效约1Mbps),但功耗较高。
  • HM-10:BLE 4.0,仅支持从机模式(可配置为iBeacon),低功耗,适合电池供电设备,但传输速率受限(约5-10KB/s),且需支持BLE的主机(如手机4.0+)。

选型建议:若需高速率或与旧设备配对选HC-05;若追求低功耗或与手机APP通信选HM-10。

二、硬件连接与AT指令配置

2.1 硬件连接要点

| 模块引脚 | 接MCU | 说明 | |---------|------|------| | VCC | 3.3V(HC-05可接5V) | 注意HM-10必须3.3V,否则烧毁 | | GND | GND | 共地 | | TXD | MCU_RX | 交叉连接 | | RXD | MCU_TX | 需分压(HC-05)或直接连(HM-10) | | EN/KEY | MCU_PA0(示例) | 高电平进入AT模式 |

关键点:HC-05的RXD电平为3.3V,若MCU为5V需串联1K电阻分压;HM-10的RXD可容忍5V,但建议统一3.3V。

2.2 进入AT模式

  • HC-05:按住模块上的按键上电,或上电前将EN接高电平,此时LED慢闪(约2秒一次),进入AT模式,波特率固定38400。
  • HM-10:直接发送AT指令(默认波特率9600),无需特殊引脚,但部分版本需在未连接状态下。

2.3 常用AT指令配置

以下指令通过串口助手发送,每条指令以\r\n结尾(HC-05)或\r\n(HM-10,但部分版本仅需\n)。

HC-05配置示例(波特率38400):

AT+NAME=MyHC05      // 设置名称
AT+ROLE=0           // 设为从机(1为主机,2回环)
AT+UART=9600,0,0    // 设置串口波特率9600,停止位1,无校验
AT+PSWD=1234        // 设置配对密码
AT+RESET            // 重启生效

HM-10配置示例(波特率9600):

AT+NAME=MyHM10      // 设置名称
AT+ROLE=0           // 从机模式(默认)
AT+BAUD0            // 设置波特率9600(0=9600, 1=115200等)
AT+ADDR?            // 查询MAC地址
AT+RESET

注意:配置后需重新上电,且AT模式与透传模式切换(HC-05需拉低EN)。

三、STM32串口透传代码实现

以下代码基于STM32F103,使用USART1与蓝牙模块通信,USART2用于调试输出。实现功能:MCU将接收到的蓝牙数据原样回传,并打印到调试串口。

3.1 初始化配置

// 初始化USART1(蓝牙)和USART2(调试)
void UART_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    
    // 使能时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    
    // USART1_TX PA9, RX PA10
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // USART2 TX PA2, RX PA3
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    // USART1 配置(与蓝牙模块波特率一致)
    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);
    
    // USART2 配置(115200调试)
    USART_InitStructure.USART_BaudRate = 115200;
    USART_Init(USART2, &USART_InitStructure);
    
    USART_Cmd(USART1, ENABLE);
    USART_Cmd(USART2, ENABLE);
    
    // 使能接收中断
    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);
}

3.2 中断处理与数据回传

// 发送单个字符
void UART_SendChar(USART_TypeDef* USARTx, uint8_t ch) {
    while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
    USART_SendData(USARTx, ch);
}

// 发送字符串
void UART_SendString(USART_TypeDef* USARTx, const char* str) {
    while (*str) {
        UART_SendChar(USARTx, *str++);
    }
}

// USART1中断服务函数
void USART1_IRQHandler(void) {
    uint8_t data;
    if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
        data = USART_ReceiveData(USART1);
        // 回传蓝牙数据
        UART_SendChar(USART1, data);
        // 调试输出到USART2
        UART_SendChar(USART2, data);
    }
}

int main(void) {
    // 初始化系统时钟等
    UART_Init();
    UART_SendString(USART2, "Bluetooth UART Test\r\n");
    while (1) {
        // 主循环可处理其他任务
    }
}

四、数据通信测试与调试技巧

  1. 手机端测试:使用“蓝牙串口助手”APP(HC-05)或“BLE调试助手”(HM-10),配对后发送数据,观察MCU回传。
  2. 逻辑分析仪:若数据异常,用逻辑分析仪抓取UART波形,确认波特率、电平是否匹配。
  3. AT指令验证:发送AT,HC-05返回OK,HM-10返回OK(部分版本返回OK+)。
  4. 流控问题:确保模块的CTS/RTS未连接(默认禁用),否则可能阻塞。

常见问题排查

  • 无法进入AT模式:检查EN引脚电平,HC-05需在上电前拉高。
  • 数据乱码:波特率不一致,或HC-05的RXD电平不匹配。
  • 连接不稳定:距离过远或干扰,尝试降低波特率。

五、注意事项与进阶建议

  • 电源稳定性:蓝牙模块峰值电流可达50mA,避免与电机共用电源,加100uF电容滤波。
  • 电平转换:5V MCU与HC-05通信时,务必分压,否则可能损坏模块。
  • HM-10的AT指令差异:不同固件版本指令略有不同,以官方手册为准。
  • 低功耗设计:HM-10支持AT+SLEEP进入休眠,唤醒需外部中断或定时器。
  • 多模块组网:HC-05可配置为主机,实现一对一透传;HM-10支持广播,但需自定义协议。

进阶方向:可结合蓝牙模块实现OTA固件升级、远程传感器数据采集,或使用BLE的GATT自定义服务实现更复杂通信。

六、总结

HC-05与HM-10作为串口透传模块,极大简化了无线通信开发。掌握AT指令配置和串口中断处理是核心,本文提供的代码可直接移植。实际项目中,务必根据需求选择模块,并注意硬件细节。希望本文能帮助你快速构建稳定的蓝牙通信链路。