基于nRF52832的BLE透传模块E104-BT02应用与调试全攻略
2026/9/17 16:34:15 网站建设 项目流程

在嵌入式项目里跟BLE打交道,最烦的不是协议本身,而是“代码堆完了,设备死活连不上”或者“连上了,数据收不到”。这类问题排查起来特别耗时间,很多时候问题不是出在你的逻辑上,而是出在底层配置和模块选型上。E104-BT02这个模块,我觉得算是把这条弯路给拉直了不少。它是成都亿佰特出的一款基于Nordic nRF52832方案的BLE透传模块,板上自带天线、晶振和匹配电路,对外直接用串口收发数据,协议栈和射频部分全部封装好了。这篇文章就说清楚它怎么用、电路怎么搭、驱动怎么调,以及调试过程中一定会踩的几个坑。

这个模块比较适合三类人:一是想把产品快速加BLE功能但不想啃协议栈的老嵌入式工程师,二是做毕业设计或电子竞赛的学生,三是刚接触BLE通信、想找一个稳定参照物的学习者。整个上手路径其实比想象中短得多——供电、串口、指令配置、透传,四步就能跑起来。而且官方SDK里提供了完整开源电路和驱动代码,意味着你既能把它当黑盒用,也能在出问题时打开原理图和源码自己深挖。

下面我按实际项目里推进的顺序,把从选型到落地全程拆开讲。每一部分都会说明当时为什么这么做、有哪些替代方案、最终怎么取舍。

1. 模块选型思路:为什么是E104-BT02而不是直接上nRF52832

1.1 模块化方案和SoC方案的本质区别

先说结论:如果你只是想在现有产品里快速加一个BLE通道,选模块比选SoC方案至少能省两周时间。E104-BT02的核心是nRF52832,这颗芯片支持BLE 5.0,具备64MHz主频的Cortex-M4F内核,有512KB Flash和64KB RAM,性能在中低端BLE方案里算相当能打的。但直接把SoC画到板子上,要处理晶振匹配、天线阻抗、射频走线、频偏校准等一系列问题。不是做不到,而是对一个以业务逻辑为主的项目来说,投入产出比太低。

E104-BT02把射频部分全部封好了,模块上自带PCB天线,你只需要关心供电、串口和复位这几个引脚。采用模块化方案的底气在于:射频性能是经过出厂校准的,你画的板子只要电源和地处理好,性能不会差太多。如果是自己画SoC,尤其是两层板,天线底下净空没处理好,实测通信距离可能直接砍半。

1.2 E104-BT02这颗模块的核心参数

模块支持BLE 4.2和BLE 5.0(实际广播物理信道仍是1M PHY),这个基本覆盖了绝大多数透传场景。有效数据吞吐大概在3~5KB/s,注意这不是理论速率,是实测透传速率,因为BLE协议本身有大量开销。如果你要传输音频或高速传感器流,这个模块不合适,得考虑BLE Audio或换Wi-Fi方案。

主要参数列一下,方便对比:

参数项说明
工作频段2.4GHz ISM全球通用
发射功率-20dBm ~ +4dBm可软件配置
接收灵敏度-96dBm1Mbps速率下
通信距离约80米(开阔地)实测依赖环境
供电范围1.8V ~ 3.6V推荐3.3V
串口波特率1200 ~ 115200默认115200
工作电流平均约10mA(广播+连接)低功耗模式可到uA级
引脚数SMD-16封装实际常用6个左右

这些参数里,最值得注意的是供电范围。模块支持1.8V起供电,但如果你的主控是5V系统,比如传统51单片机或STM32F103,直接接肯定不行,需要加LDO或者电平转换。我在项目里一般用ME6211或XC6206这类低压差LDO,纹波小,价格也低。

1.3 选型时的几个备选方案对比

市面上同类模块还有几款,做选型对比时我比较关注三点:协议栈稳定度、AT指令完善程度、以及资料开源程度。E104-BT02在这三点的均衡性不错。

对比维度可以参考这个表格:

模块核心芯片是否开源电路透传模式资料完整度
E104-BT02nRF52832支持较完整
HM-10CC2540部分支持
AT-09CC2541部分支持
JDY-31CC2541支持一般

HM-10和AT-09属于老牌模块,稳定性有口碑,但它们基于CC254x,是BLE 4.0,不支持BLE 5.0特性,而且CC254x的技术生态已经处于半停滞状态。E104-BT02基于nRF52832,这颗芯片在Nordic生态里属于中坚力量,以后升级到nRF52系列其他型号也很平滑。

有一类特殊需求要说一下:如果你要做的是BLE数字钥匙这类需要复杂加密和私有协议的产品,AT透传模块就完全不够用了。这种情况更适合直接基于nRF52832的SDK自研固件,或者选支持SDK二次开发的模块形态。E104-BT02提供了开源电路,本质上就是给了你一个“抄作业入口”——先拿它跑通业务,再照着它的电路和驱动去改自己的方案。

2. 硬件电路搭建:最小系统的五个关键点

2.1 最小电路连接

E104-BT02是16脚SMD封装,但实际用起来没那么复杂。官方开源电路里有完整的参考设计,我在这里把最核心的电路连接提炼出来。

模块需要连接的引脚如下:

  • VCC(Pin1)接3.3V电源
  • GND(Pin3、Pin10)接地,两个地都要接
  • TXD(Pin2)接主控的RX
  • RXD(Pin4)接主控的TX
  • RESET(Pin12)接主控GPIO(可选)
  • STATE(Pin13)接主控GPIO(可选,用于检测连接状态)

这六个引脚就是绝大部分应用需要的全部了。注意模块的TXD和RXD是针对模块自身来说的,跟主控连接时交叉对接。这块做反了是新手最常见的低级错误,我之前就见过有人线都焊好了,串口助手也打开了,数据完全没反应,最后发现是TX接TX、RX接RX。

2.2 电源设计的关键细节

BLE模块对电源纹波比较敏感。nRF52832在射频发射瞬间电流会突然拉高,如果电源没设计好,瞬间压降会导致模块复位或发射功率下降。我看到不少DIY项目直接用AMS1117给模块供电,其实这样做有一定隐患:AMS1117在低压差场景下静态电流偏大、动态响应一般,在射频应用里不够理想。

建议按这个思路做:

  • 主电源用LDO输出3.3V,LDO输入输出各加一个10uF和0.1uF电容并联
  • 模块VCC引脚旁边再放一个1uF陶瓷电容,尽量靠近引脚放置
  • 如果系统里还有其他数字电路,考虑给模块单独一组LC滤波,电感和电容值分别取10uH和10uF

我做过一个温湿度采集节点,刚开始跟模块共用一路电源,每次蓝牙一广播,传感器读数就跳变。排查到最后发现是电源被拉低导致的ADC参考不稳,给模块单独加了一路LC滤波后问题消失。

2.3 状态指示电路

STATE引脚会在模块与手机建立连接后输出高电平,断开后输出低电平。这个引脚非常实用,可以驱动一个LED做连接状态指示,也可以直接接到主控IO上,让MCU知道当前连接状态,从而决定是否进入休眠或调整数据上报策略。

我在实际项目里的做法是:

  • 用STATE引脚通过一个1k电阻驱动LED到GND
  • 同时把STATE引脚接到MCU的GPIO
  • 高电平表示已连接,低电平表示未连接

类比对理解单片机中断的概念,STATE引脚相当于给主控一个“连接状态改变”的信号,这样主控就不用频繁轮询模块状态了。

2.4 PCB布局的几个禁忌

如果照着开源电路打样板,有几个布局问题要特别注意:

模块天线区域正下方不能走线、不能铺铜。天线下方铺地会改变天线阻抗,虽然不至于完全连不上,但通信距离会缩短明显。

模块尽量放在PCB边缘,天线部分最好伸出去悬空。如果产品结构限制必须把天线放在内部,要避开金属外壳正对位置。我在一个项目里把模块贴在锂电池旁边,距离只有3mm,结果通信距离从室内七八米掉到两米,后来重新布局天线朝向才改善。

晶振是关键器件,模块内置了晶振,走线时不要把高频信号线布在模块附近。如果要在模块周围布线,尽量包地处理。

2.5 从开源电路里能学到什么

官方开源电路里除了模块参考设计,还有整个DEMO板的电源、串口转USB、按键和LED电路。对新手来说,这个电路图本身就是很好的学习材料。我仔细看过一遍,有几个细节可以借鉴:他们的USB转串口部分用了CH340,兼容性较好;电源部分加了ESD防护;串口信号线串了0欧电阻,方便调试时断开后级电路。

完整的开源电路文件在SDK包里能找到,包含Altium格式的原理图和PCB。如果你要基于这个模块设计自己的产品,直接把这个参考设计改改搬过来,比自己从零画省不少事。

3. 固件与驱动代码:从AT指令到底层逻辑

3.1 E104-BT02的固件工作模式

模块出厂自带AT指令固件,支持透传模式。所谓透传模式,就是你往模块串口发的数据,会原封不动通过BLE发给手机端;手机端发来的数据,会原封不动通过串口输出。中间不需要你做任何协议转换。

模块上电后有两种状态:

  • 未连接状态:进行广播,等待中心设备连接
  • 已连接状态:建立BLE连接,进入透传模式

这个设计跟HC-05蓝牙串口模块的思路一致,好处是上手几乎没有学习成本,坏处是你无法自定义GATT服务。如果要自定义服务,就得用SDK里的透传服务模板去改,这就涉及到nRF5 SDK的开发了。

3.2 驱动代码框架

官方SDK提供的驱动代码主要包含以下文件:

  • e104_bt02.c:模块操作函数,包括初始化、发送、接收
  • e104_bt02.h:头文件,定义接口
  • main.c:示例主程序
  • app_ble.c / app_ble.h:BLE相关配置

从驱动代码的架构来看,它遵循的是一个典型的“中间层”设计——底层硬件抽象、中间协议逻辑、上层业务接口三层解耦。你在自己的项目里移植时,只需要保留底层串口驱动和BLE处理代码,替换掉上层的业务逻辑就行。

驱动核心接口大致是这几个:

  • e104_bt02_init():初始化串口和模块
  • e104_bt02_send():通过BLE发送数据
  • e104_bt02_receive():接收BLE数据
  • e104_bt02_state_check():查询模块连接状态

3.3 串口驱动的实现要点

跟模块通信的物理接口是串口,所以驱动代码中最基础的底层是串口驱动。默认波特率115200,8位数据位,1位停止位,无校验。这组参数在绝大多数MCU上都有现成驱动,移植成本很低。

以STM32标准库为例,串口初始化代码的核心思路是:

- 使能GPIO和USART时钟 - 配置TX、RX引脚为复用推挽输出和浮空输入 - 配置USART参数:波特率115200、字长8位、停止位1位、无校验 - 使能USART,使能接收中断

中断处理的逻辑是:每接收到一个字节,存入环形缓冲区;主循环或数据处理任务从缓冲区取数据,再调用上层回调函数处理。这个结构的好处是收发不会互相阻塞,数据量大时也不容易丢。

3.4 广播配置的核心逻辑

如果你使用AT指令方式,模块默认广播名是类似“E104-BT02_XXXXXX”的格式,其中XXXXXX是MAC地址后三位字节的十六进制表示。这种默认广播名足够测试用,但产品化时通常要改。

通过AT指令可以修改广播名,可配置的内容还包括广播间隔、发射功率和连接间隔。这几个参数的配置逻辑值得展开说:

广播间隔越长,功耗越低,但手机发现设备所需时间也越长。如果产品需要快速连接,广播间隔可以设短一点,比如20ms到50ms;如果要省电,可以设到100ms以上。

发射功率直接决定通信距离,但功耗随之线性增加。4dBm和-20dBm的功耗差距大概是数十倍量级。我一般调试阶段用满功率,做低功耗设计时再降到0dBm或-4dBm。

连接间隔影响数据吞吐,间隔越短,吞吐越高,功耗也越高。如果只是传少量控制指令,30ms的间隔完全够用;如果要传传感器数据流,可以试试7.5ms,但要注意这时功耗会明显上升。

3.5 GATT服务与自定义固件

透传AT模式下,模块使用的是固定的串口透传服务,这个服务的UUID是公开的,你可以拿nRF Connect直接操作。如果你不想依赖这个固定服务,而是想自己定义服务特征,就得编译自定义固件。

nRF5 SDK里其实自带了一个现成的模板,就是UART服务模板。这个模板定义了一个RX特征和TX特征,逻辑跟E104-BT02的透传服务几乎一样。在SDK中找到这个模板,把服务UUID、特征UUID改成你需要的值,就完成了最基本的自定义GATT服务。

这里提一下BLE中GATT的核心概念:一个服务(Service)包含若干特征(Characteristic),每个特征有自己的UUID、属性和值。手机端读写数据,本质上是读写某个特征的值。举个例子,串口透传服务就是两个特征,一个用来接收外部数据(写入),一个用来发送数据到外部(通知)。理解了这个模型,BLE应用层开发就掌握了核心。

3.6 驱动代码中的几个注意细节

官方驱动代码里的串口接收使用的是中断方式,这在数据量不大时绰绰有余。但透传场景下手机可能连续发几百字节,如果单片机主频低且中断处理不及时,DMA方式会更稳妥。实测在STM32F103上,115200波特率下用串口空闲中断加DMA接收,处理几十KB数据没有问题。

另一个细节是,模块上电后大约需要几百毫秒完成内部初始化,如果主控上电后立刻发送AT指令,可能会因为模块未就绪而收不到应答。在驱动代码里,建议在模块复位引脚上加延时逻辑,或者主控初始化时延时500ms再开始发AT指令。这个坑看着小,实际栽过的人不少。

4. 调试流程实录:从串口到手机App的完整链路

4.1 调试环境准备

开始调试前,需要准备以下工具:

  • E104-BT02模块一个
  • USB转TTL模块一个(推荐CP2102或CH340)
  • 手机一部,安装nRF Connect或LightBlue
  • PC串口调试助手一个

硬件连接方式:USB转TTL的TX接模块RX,USB转TTL的RX接模块TX,两端GND互连,VCC接3.3V。这里要特别强调共地问题——两个设备不共地,通信肯定会出错。USB转TTL模块通常标称3.3V输出,实测有些型号空载时电压超过3.6V,如果手头有万用表,建议上电后先测一下再确认接模块。

4.2 第一步:验证串口通信

先把模块通过USB转TTL接到电脑,打开串口调试助手,选择对应COM口,波特率115200。发送AT指令测试:

发送“AT\r\n”,模块正常会回复“OK\r\n”。这一步验证了串口通信链路是否通畅。

如果没有任何回应,排查顺序是:

  1. 检查TX和RX是否接反(对调试试)
  2. 检查供电电压是否在3.3V左右
  3. 检查串口参数是否完全正确(波特率、数据位、停止位、校验位)
  4. 检查地线是否连接

4.3 第二步:用手机扫描连接

串口通了之后,打开nRF Connect,点击扫描,应该能看到名为“E104-BT02_XXXXXX”的设备。点击设备,会看到两个可操作的服务——一个是Generic Access服务,一个是Generic Attribute服务,再往下就是透传服务。

找到透传服务的UUID,通常是“FFF0”系列,点进去会看到两个特征,一个可写、一个可通知。把可通知的特征开启通知(点击“Notify”图标),然后切换到“串口调试助手”窗口,往串口发送“Hello\r\n”。回到nRF Connect,在通知的日志里应该能看到刚才发送的字符。

反向测试:在nRF Connect中点击可写特征,输入“Hi”,点写入,在串口调试助手窗口里应该能看到输出“Hi”。

这里我需要提醒一个关键点:开启通知(Enable Notification)的情况下,模块才会主动把接收到的串口数据推送到手机。如果没开通知,你往串口发数据手机那边收不到,但手机往模块写数据串口还是能收到。这个不对称现象容易让人产生困惑。

4.4 第三步:AT指令配置参数

如果默认参数不满足需求,用AT指令修改。比较常用的几条:

指令功能示例
AT+NAME=xxx修改广播名AT+NAME=MyDevice
AT+MAC查看MAC地址AT+MAC\r\n
AT+BAUD=9600修改波特率AT+BAUD=9600\r\n
AT+PWR=0设置发射功率等级AT+PWR=0\r\n
AT+ADVI=100设置广播间隔AT+ADVI=100\r\n
AT+RESET模块复位AT+RESET\r\n

配置完参数后,记得发送AT+RESET让模块用新参数重启。修改波特率后串口助手也需要同步切换波特率,这是一步很容易让人误以为模块坏了的情况。

4.5 第四步:与主控MCU联调

主控MCU联调的流程是:先确认串口与模块通信正常,再确认手机能与模块建立BLE连接,最后把两者串联起来测试。

建议的步骤是:

  1. 主控上电后,先通过串口发送AT指令,检查回复是否正确
  2. 在手机端扫描连接模块,确认透传通路完好
  3. 主控向模块发送固定数据,手机端确认收到
  4. 手机端向模块写入数据,主控串口中断或轮询中确认收到

做到第4步,整个数据链路就完全打通了。这时再进入业务逻辑开发,细节问题会少很多。

4.6 模块低功耗模式注意事项

如果你要做的产品靠电池供电,需要关注模块的低功耗模式。E104-BT02在未连接状态默认是低功耗广播,电流较低;连接状态下,连接间隔越长,平均电流越低。

刚上手时不建议直接进入低功耗开发,因为低功耗条件下调试难度会增加,排查问题更难区分是软件逻辑还是硬件问题。我的建议是先用默认参数跑通功能,再逐步优化功耗。

5. 常见问题与排查技巧实录

5.1 搜索不到设备

这个问题在BLE开发中最常见,出现时先别急着怀疑模块坏了,按顺序排查:

模块没供电。很多人用USB转TTL模块的3.3V输出直接供电,但有些USB转TTL的3.3V输出电流很小,模块工作电流一上来电压就被拉低了。建议用单独的3.3V稳压源供电,或用带供电能力的开发板给模块供电。

广播名被修改过。上电前按住模块的恢复默认配置引脚再上电,可以恢复出厂设置。但手边没有资料时,这个方法不一定好使。所以拿到模块第一步先记住默认广播名和MAC地址,后面能省很多麻烦。

手机蓝牙未开启或缓存异常。手机蓝牙偶尔会有缓存残留,设备已经改名但手机还显示旧名字,或者设备已经断开但列表里显示的还是之前的状态。关闭蓝牙再打开通常能解决。

模块射频损坏。ESD静电、电源接反都可能导致射频部分损坏,这种情况只能换模块。

5.2 能搜索到但连接失败

扫描能看到设备,说明广播正常,但连接失败的情况通常指向几个方面:

模块已经被其他设备连接。BLE是点对点通信,一个从设备同一时刻只能被一个主设备连接。如果之前用nRF Connect连接过模块但没断开,换个手机连就会失败。处理方法是先把之前的连接断开,或者给模块断电重启。

连接参数不匹配。有些手机对连接参数要求比较严格,如果模块广播里设置的连接参数不符合手机接受的区间,连接会被拒绝。默认配置一般兼容性较好,如果修改过连接参数导致连不上,恢复默认再试。

模块进入了低功耗深度睡眠模式。在低功耗模式下,模块的广播事件非常稀疏,手机需要更长时间才能完成连接。延长扫描时间或用测试模式关掉低功耗选项,连接成功率会高很多。

5.3 连接后数据收发异常

连接正常但数据不通,有几种典型表现,排查方式也不同。

手机收不到串口发来的数据,优先检查是否开启了通知。用nRF Connect时点一下透传特征的通知开关再测试;用自己App时,记得在连接成功后初始化时执行一次“setCharacteristicNotification”和“writeDescriptor”操作,这两步缺一不可。

串口收不到手机发来的数据,检查模块与主控串口接线,特别是交叉关系。同时检查主控串口中断是否正常使能,引脚复用是否配置正确。

数据内容错误,比如收到乱码,优先检查波特率和数据位设置。模块默认115200,主控端也要匹配。如果一端配置了9600另一端还是115200,收到的数据大概率是乱码。

5.4 信号距离短

通信距离明显达不到标称值,可能的原因:

天线区域被遮挡或金属物体靠近。模块的天线对周围环境比较敏感,尽量把天线区域留空,避免放在金属外壳内、贴电池等情况。

供电不足导致射频输出功率下降。射频发射时电流瞬时需求大,电源压降会导致内部功率放大电路工作不正常。改善供电质量后,距离往往会显著提升。

发射功率配置过低。检查AT+PWR是否设置成了低功率档位。如果为了省电设成了-20dBm,那通信距离短是正常现象。

5.5 模块频繁断开

连接后频繁断开是非常影响体验的问题,一般原因如下:

电源电压不稳。连接状态下射频电流变化频繁,如果电源内阻大,电压波动会触发模块的欠压保护或复位。这是频繁断开最常见的原因,改善电源质量后问题通常能解决。

周围2.4GHz干扰较强。微波炉、Wi-Fi路由器、USB 3.0接口等都会产生2.4GHz频段干扰,测试时尽量换个环境再验证。

连接参数过激进。连接间隔设太短、从设备延迟设0,会导致两侧设备同步压力增大,稍有干扰就容易断开。适当放宽连接间隔,比如15ms到30ms,稳定性会明显提升。

5.6 调试工具使用小技巧

nRF Connect除了常规的数据收发测试,还提供了几个很有价值的信息页面:

  • 可以查看广播数据包内容,包括广播类型、设备名称、服务UUID、厂商自定义数据
  • 可以查看已连接设备的连接参数,包括连接间隔、从设备延迟、超时时间
  • 可以在日志里看到MTU协商的结果

MTU(Maximum Transmission Unit)这个参数值得展开说明。BLE 4.2默认ATT MTU是23字节,其中有效载荷只有20字节,这就是“一次最多发20字节”说法的来源。通过MTU协商,可以把MTU提升到247字节,有效载荷相应增加到244字节。E104-BT02的固件会自动协商MTU,但如果你的App端没有请求更大的MTU,数据传输速度就会受限。这里我可以补充一个实操技巧:在nRF Connect中连接后,找到“MTU”选项手动设置最大MTU值,再测试同样的数据量,你会发现传输速度有明显提升。

5.7 绑定与配对问题

热词里出现的“ble调试助手绑定(bond)”涉及的是BLE的配对与绑定机制。所谓绑定,就是中心设备和外围设备在首次配对后,将加密密钥存储在本地,以后重新连接时直接复用密钥,不需要再次配对。在产品设计中,绑定功能很有用——比如你的设备需要和用户的手机长期保持加密通信,绑定可以省去每次连接都确认的步骤。

在用nRF Connect调试时,如果你想测试绑定流程,在连接后打开配对界面,选择“Pairing”或“Bonding”,输入或确认PIN码即可。测试结束如果想清除绑定信息,模块侧可以通过恢复出厂设置清除,手机侧在蓝牙设置里删除已配对设备即可。

6. 完整示例工程解析:一个真实的温湿度采集节点

6.1 需求场景设定

用一个框架来巩固前面的内容——一个基于STM32F103和E104-BT02的温湿度采集节点,通过BLE把数据传给手机。这个例子不复杂,但覆盖了串口通信、模块初始化、数据上报等全部关键路径。

需求如下:

  • 每隔2秒采集一次温湿度
  • 手机连接模块后,数据实时推送到手机
  • 手机发送指令可以修改采集间隔

6.2 硬件连接方案

STM32F103与模块连接:

主控引脚模块引脚说明
PA9(USART1_TX)RXD主控发送,模块接收
PA10(USART1_RX)TXD模块发送,主控接收
PA11STATE连接状态检测
PA12RESET模块复位
3.3VVCC电源
GNDGND共地

6.3 驱动代码核心逻辑

驱动代码的思路分三块:串口底层、指令收发、业务逻辑。

串口底层配置,以STM32标准库为例:

void USART1_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); 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); USART_InitStructure.USART_BaudRate = 115200; 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); USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); USART_Cmd(USART1, ENABLE); }

串口中断接收数据的逻辑,使用环形缓冲区:

#define RX_BUFFER_SIZE 256 volatile uint8_t rx_buffer[RX_BUFFER_SIZE]; volatile uint16_t rx_head = 0; volatile uint16_t rx_tail = 0; void USART1_IRQHandler(void) { if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { uint8_t data = USART_ReceiveData(USART1); uint16_t next = (rx_head + 1) % RX_BUFFER_SIZE; if (next != rx_tail) { rx_buffer[rx_head] = data; rx_head = next; } // 缓冲区满时丢弃数据,防止覆盖未读数据 } }

业务逻辑部分,每2秒采集一次数据并转发到串口:

void process_periodic_report(void) { uint16_t temp, humi; char report[32]; temp = read_temperature(); humi = read_humidity(); sprintf(report, "T:%d.%d H:%d.%d\r\n", temp / 10, temp % 10, humi / 10, humi % 10); e104_bt02_send((uint8_t *)report, strlen(report)); }

数据接收部分,主循环定期检查串口缓冲区内是否有来自手机的数据,解析简单指令:

void process_serial_command(void) { char cmd[16]; uint16_t len = 0; while (rx_tail != rx_head && len < (sizeof(cmd) - 1)) { cmd[len++] = rx_buffer[rx_tail]; rx_tail = (rx_tail + 1) % RX_BUFFER_SIZE; if (cmd[len - 1] == '\n') { break; // 一行命令结束 } } if (len > 0 && cmd[len - 1] == '\n') { cmd[len] = '\0'; if (strstr(cmd, "INTERVAL=1000")) { report_interval_ms = 1000; e104_bt02_send((uint8_t *)"OK\r\n", 4); } // 其他指令类似处理 } }

6.4 代码移植注意事项

这段代码可以直接跑到STM32F103上,其他MCU只需替换串口初始化和中断部分。移植时特别注意两点:

环形缓冲区的大小要根据数据量设定。默认256字节够用,但如果你要传输较大的数据帧,建议开到512或1024。数据内容超过缓冲容量后,新数据会覆盖未读数据,这是缓冲区设计的常见取舍。

提醒一下,uart接收中断中尽量避免做耗时操作,比如调用sprintf或printf。中断里快速拷贝数据到缓冲区就够了,解析和上层逻辑放到主循环完成。否则低波特率时容易丢失后续数据。

波特率修改后记得同时修改主控串口配置。如果模块波特率改成了9600,而主控还是115200,收发数据就是乱码。调试这种问题最费时间,因为它们表象相似,需要逐一排除。

7. 开源电路设计思路:照着画一版自己的模块化产品

7.1 参考电路的整体框架

出于让内容更完整的考虑,这里把官方开源电路的设计思路做一个梳理。这套电路不是简单的“最小系统”,而是一个完整的测试、评估、二次开发平台,包括:

  • E104-BT02模块插座或焊盘
  • 3.3V LDO电源,支持USB或外部直流供电
  • USB转串口电路,用于连接电脑调试
  • 按键和LED,用于复位和状态指示
  • 预留主控接口,便于连接外部MCU

从布局上看,他们把模块放在板子一角,天线区域悬空,电源部分与天线保持距离,形成一条相对完整的射频隔离带。这种布局思路值得借鉴:数字电路和射频电路分区,电源回路尽量短粗,地平面尽量完整。

7.2 借鉴这套电路的三个理由

从工程角度看,官方开源电路的价值不仅在于“能用”,还在于它包含了很多细节设计:串口信号线上的限流电阻、电源入口的TVS管保护、去耦电容的摆放位置。这些细节在原理图里可能不起眼,但实际在产品可靠性上影响很大。

在生产层面,照着成熟参考设计做,能规避很多EMC问题。BLE模块的工作频率2.4GHz,如果布局不合理,谐波会让产品过不了FCC或CE认证,重新改板的时间和成本都很高。参考官方电路能帮你站在一个相对合理的起点上。

7.3 从参考设计到自己产品的改造路径

如果你最终想做自己的产品,建议的改造路径是:

第一步,原样复制官方参考设计打样测试,确保性能达标。第二步,移除调试用部分,比如USB转串口、按键LED,只保留模块和必要接口。第三步,针对你的结构要求重新布局,主要调整位置和尺寸,但保持电源和天线的关键设计。第四步,结合产品做外观和天线方案的最终调整,比如是否需要外置天线。

这个流程看着简单,但每一步都有一个验证环节,不要一次改太多。我有一次是为了“调整形状”把模块位置挪了5毫米,结果通信距离从30米降到10米。从此以后严格遵循“一次只改一个变量”的节奏,发现问题才能及时定位。

8. 从E104-BT02出发:BLE开发更高的进阶方向

“BLE数字钥匙”是目前比较热门的应用方向,如果你想往更高的层面走,E104-BT02可以作为起点,但远远不是终点。数字钥匙这类应用涉及复杂的加密鉴权、车规级安全标准和云端联动,模块的AT透传模式已经满足不了需求,这时就进入了基于nRF52832原厂SDK的开发范围。

进阶开发的核心路径有几个方向:

方向一是从“会用AT指令”到“能自由配置协议栈”。透传模块帮你封装好了连接和收发,但如果要做私有GATT服务、多点连接、或基于Mesh的组网通信,你就需要直接用nRF5 SDK做开发。官方提供了一整套协议栈接口,代码层面有清晰的架构可以学习。

方向二是从“单设备”到“多设备协同”。BLE不只是手机和单设备通信,还可以做设备之间的数据传输。比如一个主控设备同时管理多个传感器节点,或者不同模块之间组成物联网络。E104-BT02的透传模式只支持点到点,组网需要更底层的能力和更复杂的调度逻辑。

方向三是深入射频与功耗工程。BLE产品的核心竞争力往往体现在功耗和稳定性上,而不是功能多少。理解广播事件、连接事件、睡眠时钟、DC-DC电源配置之间的关系,能把产品续航从几个月优化到一年以上,这是工程师真正的价值所在。

BLE调试助手绑定、MTU协商、GATT服务设计、广播类型选择这些东西,在透传模块阶段你可能感受不深——因为封装层帮你做了绝大部分工作。但一旦进入自定义固件开发,这些都是每天都要面对的基础问题。先用E104-BT02把整条链路跑通,建立“扫描-连接-发现服务-读写特征-通知”的完整心智模型,再往底层深入,就顺理成章了。

根据我个人的经验,做BLE开发最容易卡住的阶段不是一开始,而是你觉得自己已经“会了”的时候。透传模块跑得很顺,让你以为BLE不过如此,然后第一次做自定义固件就被广播类型、连接参数、服务发现这些概念打了个措手不及。所以趁现在还有耐心,把基础概念的功课提前做扎实,后面会轻松很多。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询