告别HC-05配对烦恼!用STM32F103C8T6 HAL库驱动JDY-31蓝牙模块,手机直连真香

张开发
2026/4/15 20:26:48 15 分钟阅读

分享文章

告别HC-05配对烦恼!用STM32F103C8T6 HAL库驱动JDY-31蓝牙模块,手机直连真香
用STM32F103C8T6 HAL库玩转JDY-31蓝牙模块手机直连的极致体验在嵌入式开发中蓝牙模块的选择往往决定了项目原型的开发效率。传统HC-05模块虽然功能强大但其繁琐的配对流程常常让开发者望而却步。而JDY-31模块以其即插即用的特性正在成为快速原型开发的新宠。想象一下这样的场景你刚完成一个智能家居控制器的硬件搭建迫不及待想用手机测试功能。如果使用HC-05你需要先进入AT模式配置参数然后进行设备配对整个过程可能要花费十几分钟。而JDY-31只需要简单的串口连接手机就能直接识别并建立通信——这种效率提升对于时间紧迫的开发者来说简直是福音。1. JDY-31与HC-05核心差异解析1.1 连接方式的革命性改变JDY-31最显著的特点就是无需配对的手机直连功能。这与HC-05的工作机制形成鲜明对比特性JDY-31HC-05连接方式手机直接搜索连接需要预先配对主从模式仅支持从机模式支持主从模式切换默认名称JDY-31-SPPHC-05典型应用场景手机与设备快速通信设备间双向通信首次使用准备时间1分钟5-15分钟这种差异源于两者设计理念的不同HC-05更注重通用性和灵活性而JDY-31则专注于简化手机与嵌入式设备的连接流程。1.2 硬件接口对比虽然两者都使用UART通信但硬件连接上有些许差异JDY-31常见4针版本VCC(3.3V)、GND、TXD、RXD6针版本只需使用中间4针两侧为未连接的引脚HC-056针接口VCC、GND、TXD、RXD、STATE、EN需要额外关注STATE和EN引脚的状态// JDY-31典型接线示意图 // STM32F103C8T6 JDY-31 // PA9(TX) - RXD // PA10(RX) - TXD // 3.3V - VCC // GND - GND2. STM32硬件配置与HAL库初始化2.1 硬件准备对于STM32F103C8T6蓝莓开发板用户连接JDY-31只需要最基本的四线连接。建议使用USART1(PA9/PA10)或USART2(PA2/PA3)作为通信接口因为这些引脚在大多数开发板上都有明确引出。注意虽然JDY-31标称支持3.3V-5V供电但实测3.3V供电更为稳定建议直接使用STM32的3.3V输出。2.2 CubeMX配置使用STM32CubeMX可以快速完成USART初始化在Pinout界面启用USART1配置为Asynchronous模式参数设置Baud Rate: 9600默认Word Length: 8 bitsStop Bits: 1Parity: NoneHW Flow Control: Disable生成代码后HAL库会自动完成USART初始化。我们只需要关注应用层的数据收发即可。3. 基础通信实现3.1 数据发送实现JDY-31的数据发送与普通串口完全相同直接使用HAL_UART_Transmit函数void sendBluetoothData(const char *message) { uint16_t len strlen(message); HAL_UART_Transmit(huart1, (uint8_t*)message, len, 1000); } // 调用示例 sendBluetoothData(Hello JDY-31!\r\n);在实际项目中建议封装更健壮的发送函数包含错误处理和重试机制。3.2 数据接收实现接收数据推荐使用中断模式避免阻塞主程序#define RX_BUFFER_SIZE 128 uint8_t rxBuffer[RX_BUFFER_SIZE]; uint8_t rxByte; volatile uint16_t rxIndex 0; // 中断回调函数 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart-Instance USART1) { rxBuffer[rxIndex] rxByte; if(rxIndex RX_BUFFER_SIZE) rxIndex 0; // 重新启用接收中断 HAL_UART_Receive_IT(huart1, rxByte, 1); } } // 初始化接收 void initBluetoothReceiver() { HAL_UART_Receive_IT(huart1, rxByte, 1); }这种实现方式可以持续接收数据而不影响主程序运行特别适合需要同时处理多个任务的场景。4. 实战项目手机控制LED让我们通过一个完整示例展示JDY-31的实际应用——用手机APP控制开发板上的LED。4.1 硬件连接除了基本的JDY-31连接外还需要LED连接在PC13蓝莓开发板自带LED可选添加电阻保护LED4.2 软件实现// 在main.c中添加 void processBluetoothCommand(uint8_t *data, uint16_t size) { if(size 1) return; if(strncmp((char*)data, LED_ON, 6) 0) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET); sendBluetoothData(LED turned ON\r\n); } else if(strncmp((char*)data, LED_OFF, 7) 0) { HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET); sendBluetoothData(LED turned OFF\r\n); } } // 在while(1)循环中添加 if(rxIndex 0) { processBluetoothCommand(rxBuffer, rxIndex); rxIndex 0; // 清空缓冲区 }4.3 手机端设置在手机端可以使用任何支持SPP协议的蓝牙串口APP如AndroidSerial Bluetooth TerminaliOSLightBlue连接步骤打开APP并搜索蓝牙设备选择JDY-31-SPP连接成功后即可发送LED_ON和LED_OFF命令5. 高级应用技巧5.1 波特率修改虽然JDY-31默认使用9600波特率但可以通过AT命令修改// 发送AT命令修改波特率为115200 const char *atCommand ATBAUD8\r\n; // 8对应115200 HAL_UART_Transmit(huart1, (uint8_t*)atCommand, strlen(atCommand), 1000);常见波特率对应代码4: 96005: 192006: 384007: 576008: 115200提示修改波特率后需要同步修改STM32的USART配置并重启模块使设置生效。5.2 模块名称修改个性化模块名称可以方便在多设备环境中识别// 修改模块名称为MyDevice const char *nameCommand ATNAMEMyDevice\r\n; HAL_UART_Transmit(huart1, (uint8_t*)nameCommand, strlen(nameCommand), 1000);5.3 数据分包处理当传输大量数据时需要考虑分包处理#define MAX_PACKET_SIZE 64 typedef struct { uint8_t data[MAX_PACKET_SIZE]; uint16_t length; uint8_t complete; } BluetoothPacket; BluetoothPacket currentPacket; void processIncomingData(uint8_t byte) { static uint16_t pos 0; if(byte \n) { // 假设以换行符作为结束标志 currentPacket.data[pos] \0; currentPacket.length pos; currentPacket.complete 1; pos 0; } else if(pos MAX_PACKET_SIZE-1) { currentPacket.data[pos] byte; } }这种处理方式可以有效管理数据流避免缓冲区溢出。

更多文章