当前位置: 首页 > news >正文

【已验证】基于STM32和HAL库的大夏龙雀BT311-10C02S蓝牙模块驱动

最近买了一个大夏龙雀家的蓝牙模块DX-BT311-10C02S,这个蓝牙是一款基于BLE 5.4规范的串口透传模块,支持AT指令配置、主从模式切换,非常适合与单片机搭配实现无线数据传输。

如果是第一次买还是很便宜的,他家的模块有一说一是真的不错

本文将分享如何使用STM32F103C6T6(HAL库)驱动该模块,完成基础功能验证。

一、模块简介

DX-BT311-10C02S具有以下特点(拷贝手册的):

  • 支持BLE 5.4协议,主从模式可切换

  • 默认串口参数:9600bps/8/n/1

  • 提供UART接口,支持AT指令配置

  • 默认从模式,UUID:SERVICE UUID: 0xFFE0,NOTIFY/WRITE UUID: 0xFFE1,WRITE UUID: 0xFFE2

  • 支持数据透传,连接后自动进入透传模式

  • 具有LINK-STATUS引脚,高电平表示蓝牙已连接

手册中AT指令格式说明:

  • 所有指令以AT开头,以\r\n结尾

  • 响应以+开头,成功时以OK结束,失败返回ERROR=<code>

  • 例如修改名称:发送AT+NAME1234,返回+NAME=1234后跟OK

二、硬件连接

STM32F103C6T6DX-BT311模块
PB10 (USART3_TX)RX
PB11 (USART3_RX)TX
3.3VVCC
GNDGND
PA0(可选)LINK-STATUS

三、驱动设计思路

为了高效处理不定长数据,我们采用DMA + 空闲中断 + 环形缓冲区的方案:

  • DMA接收:开启USART3的DMA循环接收,无需CPU干预。

  • 空闲中断:当模块发送一帧数据(以空闲状态结束)时,触发中断,在中断中将DMA缓冲区数据拷贝到环形缓冲区。

  • 环形缓冲区:用于暂存接收数据,供主循环取用。

  • AT命令同步:发送AT命令后,清空环形缓冲区,然后循环调用行读取函数,直到收到“OK”或“ERROR”或超时。这样既能与透传数据隔离,又避免阻塞。

关键点:

  1. 接收统一由环形缓冲区管理,AT命令和透传数据共用缓冲区,但通过状态标志区分。

  2. 连接状态通过PA0引脚轮询检测,并提供回调。

  3. 支持GBK编码,方便设置中文蓝牙名称。

四、关键代码实现

4.1 初始化与DMA启动

void bt311_init(UART_HandleTypeDef *huart, DMA_HandleTypeDef *hdma_rx) { g_bt311.huart = huart; g_bt311.hdma_rx = hdma_rx; ring_buffer_clear(); // 启动DMA空闲中断接收 HAL_UARTEx_ReceiveToIdle_DMA(huart, g_bt311.rx_dma_buf, BT311_RX_DMA_BUF_SIZE); }

4.2 空闲中断回调

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if (huart != g_bt311.huart) return; for (uint16_t i = 0; i < Size; i++) { // 存入环形缓冲区 uint16_t next_head = (g_bt311.rx_ring_head + 1) % BT311_RX_RING_SIZE; if (next_head != g_bt311.rx_ring_tail) { g_bt311.rx_ring_buf[g_bt311.rx_ring_head] = g_bt311.rx_dma_buf[i]; g_bt311.rx_ring_head = next_head; } } g_bt311.rx_ready = 1; HAL_UARTEx_ReceiveToIdle_DMA(huart, g_bt311.rx_dma_buf, BT311_RX_DMA_BUF_SIZE); }

4.3 AT命令发送与同步

bool bt311_send_cmd(const char *cmd, char *response, uint16_t resp_size, uint32_t timeout_ms) { // 发送命令(添加\r\n) char full_cmd[128]; snprintf(full_cmd, sizeof(full_cmd), "%s\r\n", cmd); HAL_UART_Transmit(g_bt311.huart, (uint8_t*)full_cmd, strlen(full_cmd), 100); // 清空环形缓冲区 ring_buffer_clear(); uint32_t start = HAL_GetTick(); char line[128]; while (HAL_GetTick() - start < timeout_ms) { if (ring_buffer_read_line(line, sizeof(line))) { if (strstr(line, "OK") != NULL) return true; if (strstr(line, "ERROR") != NULL) return false; } bt311_process(); // 处理环形缓冲区(从DMA搬运) HAL_Delay(1); } return false; }

4.4 主循环处理

void bt311_process(void) { // 处理透传数据(用户回调) if (g_bt311.rx_ready && g_bt311.user_rx_callback) { // 从环形缓冲区取数据,调用回调 // ... } // 处理连接状态变化 if (g_bt311.link_status_port) { uint8_t cur = HAL_GPIO_ReadPin(...); if (cur != g_bt311.link_status) { g_bt311.link_status = cur; if (g_bt311.link_status_callback) g_bt311.link_status_callback(cur); } } }

4.5 测试函数

提供全功能测试函数,自动完成初始化、AT测试、版本查询、MAC读取、名称设置、连接状态检测、数据收发打印,方便快速验证。

void bt311_run_full_test(UART_HandleTypeDef *huart, DMA_HandleTypeDef *hdma_rx) { bt311_init(huart, hdma_rx); bt311_register_rx_callback(print_received_data); bt311_set_link_status_pin(GPIOA, GPIO_PIN_0); bt311_register_link_callback(print_link_status); // 执行AT测试 if (bt311_test()) printf("AT OK\r\n"); char version[32]; bt311_get_version(version); char mac[18]; bt311_get_mac(mac); bt311_set_name("HealthMonitor"); bt311_reset(); while (1) { bt311_process(); // 连接后每5秒发送模拟数据 if (bt311_get_link_status()) { static uint32_t last = 0; if (HAL_GetTick() - last > 5000) { bt311_send_data((uint8_t*)"HR:75,SPO2:98\r\n", 14); last = HAL_GetTick(); } } HAL_Delay(10); } }

五、测试验证

在STM32F103C6T6上运行后,串口调试助手输出:

手机连接后,发送的数据被正确打印,同时模块每隔5秒自动发送模拟心率血氧数据。连接状态引脚PA0电平变化触发回调,工作稳定。

六、总结

本文介绍了DX-BT311-10C02S蓝牙模块的驱动设计思路与关键实现。通过DMA+空闲中断+环形缓冲区的组合,实现了高效、非阻塞的数据接收,并统一处理AT命令响应与透传数据。该驱动已成功应用于健康监测项目,可方便地扩展其他传感器。代码结构清晰,移植方便,可作为STM32与BLE模块通信的参考模板。

七、参考代码

通过网盘分享的文件:HealthMonitor_BT.zip
链接: https://pan.baidu.com/s/1y88ASSL0hksTsjAsc1txFw?pwd=d37u 提取码: d37u
--来自百度网盘超级会员v8的分享

http://www.jsqmd.com/news/551097/

相关文章:

  • OpenClaw故障排查手册:GLM-4.7-Flash常见错误修复
  • 2026年市面上料仓生产厂家,100T水泥罐/散装水泥罐/水泥罐/不锈钢储罐/不锈钢容器/料仓,料仓生产厂家有哪些 - 品牌推荐师
  • RexUniNLU完整教程:从克隆项目到API服务部署全链路指南
  • 小白程序员快看!轻松入门大模型驱动的AI Agent,收藏这份超全学习指南!
  • 不止于转换:PyTorch模型转ONNX后,用Netron可视化并验证推理一致性的完整流程
  • 用Python搞定抖音点赞参数:手把手教你逆向生成bd-ticket-guard-client-data
  • **发散创新:基于 Rust的开源权限管理系统设计与实现**在现
  • 【深度学习】RoBERTa:BERT的优化升级与实战应用
  • 2026年3月卫生巾厂家推荐,安睡裤卫生护垫卫生巾贴牌OEM代工,非标定制快速交付实力源头厂商 - 品牌企业推荐师(官方)
  • BiliTools全平台高效解决方案:从基础应用到高级配置的完整指南
  • 工业现场Python网关崩溃频发?揭秘PLC协议栈握手超时、GIL阻塞与内存泄漏的三角死锁(内附厂商未公开日志解码表)
  • pose-search:Web端人体姿态识别与动作检索的革新实践
  • 如何让AI帮我润色论文?2026年实测Gemini3/Claude/GPT-4o效果对比
  • 免费AI写论文工具实测:8款全学科通用神器,文献真实可查,毕业论文1小时搞定初稿! - 麟书学长
  • Finnhub Python API客户端实战指南:解决7个核心技术难题的系统方案
  • AIGlasses OS Pro C语言SDK实战:从环境配置到视觉检测完整流程
  • Semaphore实战:用Ansible+GitLab构建自动化部署流水线
  • 技术解密:戴森电池32次红灯故障的终极破解方案
  • Cursor免费试用限制突破:深入解析go-cursor-help项目的技术实现与实战指南
  • 大模型驱动下的AI Agent演化:小白程序员必看收藏指南
  • 揭秘水稻叶面病斑检测模型:如何用OpenCV+YOLOv8在边缘设备实时预警?
  • node-forge vs node-rsa:哪个更适合你的RSA加密需求?详细对比与迁移指南
  • Nunchaku-flux-1-dev助力内容创作:自动化生成文章配图与社交媒体素材
  • 连连数字CEO辛洁离职 董事长章征宇接任 温映色任财务总监
  • QLVideo终极指南:三步让Mac视频预览功能全面升级
  • 攻克RVC变声器:7大技术难关的系统解决方案
  • Irony Mod Manager:重新定义Paradox游戏模组管理体验的智能工具
  • volatile vs synchronized:Java 并发两大护法
  • 如何解决视频抠像中的稳定性难题:MatAnyone一致性内存传播技术详解
  • 3分钟让静态图像“活“起来:AI肖像动画技术全解析