
01引言$ i" D9 q1 F0 L+ e; _& S/ z! `! l9 ~ STM32WB55是一款支持BLE5.x的双核高性能MCU,针对BLE的应用固件包STM32Cube_FW_WB_V1.xx.xx\Projects\P-NUCLEO-WB55.Nucleo\Applications\BLE里面也提供了大量的例程,目前支持的标准GAP服务例程在STM32CubeMX中已有列出,或可以在固件包STM32Cube_FW_WB_V1.xx.xx \Middleware\ST\STM32_WPAN\ble\svc中找到。然而,在实际的STM32WB意向客户中,使用BLE私有协议来开发Profile非标产品的客户占了绝大部分。读者可以去查看BLE_p2pServer、BLE_Custom等例程,对于需要添加自定义ATT属性和服务的应用,现有例程里面STM32CubeMX是无法自定义添加ATT属性和服务。但笔者发现,其实使用STM32CubeMX的Custom Template是能实现上述功能的。4 c4 _5 H' g+ i. G4 N, X9 u7 b 本文的目的旨在使用STM32CubeMX以及Custom Template例程基于STM32WB55-Nucleo实现基于BLE私有协议的通用通信框架,使客户快速上手进行产品开发,且可以直接应用在产品上,应用框架的设计如下图所示。另外,本文还对BLE协议栈的下载和升级注意事项做了详细指导,如果读者不熟悉这些内容,可以先行阅读。% n( c- }" v( b# ? $ a2 j" d, G1 a8 P w& F ![]() 如上图所示,使用手机APP与STM32WB进行BLE私有协议通信,一共设计了4种类型的数据访问:读/写、只写、只读、通知,这4种访问类型基本可以覆盖大部分数据访问场景 , x: Y! m, U; Y. G ' p, U5 l+ \( E 02STM32CubeMX实现步骤 2.1 创建BLE工程添加并配置外设 请在搭建工程之前,下载安装最新的STM32CubeMX和STM32CubeWB " T( K5 C% S% u$ y( E0 s7 i3 N 2.1.1 在STM32CubeMX中点击“File”/“New Project”在弹出对话框中输入“STM32WB55RG”创建一个新工程" @( N# ^( c* J3 n- _ & h r, _7 u( ]: n6 `9 U3 V ![]() 3 P8 P5 m9 F& ]. e( v3 R 2.1.2 工程配置如下图所示,配置工程名字、保存路径、选择编译工具、调整堆栈大小和选择需要的STM32CubeWB的库文件(缺省为已安装的最新版本)。 X% H E0 Z0 U2 S7 a2 X8 n& `1 [ ![]() , ]+ r7 K! o2 ~4 |0 E! V% P* {$ ] 2.1.3 系统配置:调试口3 U) p4 l4 O" u8 m; _ 4 e9 L. x. Y- f% Z. v0 c ![]() 2 g* f5 b: K) { r) k5 b 2.1.4 外设配置:添加外部高速晶振(HSE)和低速晶振(LSE) ![]() 2.1.5 外设配置:调试打印串口USART,手动将USART1引脚重映射到PB6/PB7 ) K) R/ I5 ^) o% i! y, ` ![]() 使能USART1的TX的DMA功能和USART1的全局中断 2 W$ q) z" v5 @1 P( q. i ![]() 9 ]7 ^' K) R; A( {1 D. V- \ 2.1.6 外设配置:使能HESM,它完全由BLE stack管理1 T' u v) Z0 S- _ ![]() - K6 Q+ N; P: s , b6 k5 T+ K9 x7 k 2.1.7 外设配置:使能RF,它完全由BLE stack管理。 ![]() . z. ~7 W9 X) h7 L 2.1.8 外设配置:使能IPCC,它完全由BLE stack管理。只需同时使能它的RX/TX中断即可。# X% R1 y( F( U8 | ![]() , R+ ^* `3 u' Q' [ 2.1.9 外设配置:使能RTC,同时选择WakeUp为“Internal WakeUp”和WakeUp中断。" G' Y$ e: s4 F6 M ![]() 2.1.10 外设配置:配置时钟* W8 o; ?, ?# H& N. e% G . u, f# G* W, o" \% ~: C4 M ![]() 2.1.11 外设配置:NVIC的配置 ![]() / n$ l8 X( p4 g8 Q& D" c 至此,外设的配置和添加部分已经完成。8 V" Y4 a( `& W( ^ 2.2 BLE协议栈的添加及配置# T) w; o ]$ p3 W1 S/ n/ |' I 2.2.1 协议栈配置:使能BLE协议栈 * E% a' I6 V# ?1 r ![]() , m9 C' u5 B! Y7 o0 |9 [9 w 2.2.2 协议栈配置:禁止“Custom P2P Server”并使能“Custom Template”自定义GATT通用模板5 E* y( S2 j. }! V % n' ?# P4 i& S9 ]! w ![]() 2.2.3 协议栈配置:新建一个GATT服务,其名称为“My_Data_Server"2 i* {8 N! a' R+ c/ P % T; J" w6 D" ~5 ^, j& G6 X0 F ![]() 2.2.4 协议栈配置:GATT服务基本配置 ![]() 2.2.5 协议栈配置:配置GATT读&写 服务特征及属性值 6 I& A) y' o# j K- W: x ![]() 2.2.6 协议栈配置:配置GATT写 服务特征及属性值7 N# h# r% k$ _3 S7 T, T5 F " O% M2 c& S/ G" b ![]() 7 N& g: l2 s' I. m4 S. X2 P 2.2.7 协议栈配置:配置GATT读 服务特征及属性值/ X* _) G1 b5 y" t" M 2 A& O) T8 L( g/ c7 v. E ![]() 2.2.8 协议栈配置:配置GATT通知 服务特征及属性值) A! Q( q* Z+ L0 Q. ?5 N ' X. R# p# {# U+ Y3 m ![]() 2.2.9 协议栈配置:配置GATT广播参数配置 2 _& m& P8 h0 g5 i. ?+ | ![]() 7 j3 n! o; o" R) b; \ 2.2.10 协议栈配置:BLE配对参数设置 2 X3 A1 K8 a+ t' G2 N" R) \ ![]() ( `: D0 o8 X5 ^5 v2 I9 V/ V5 ?( S 2.2.11 协议栈配置:BLE协议栈调试及打印配置(需依次序配置) * t3 {3 X1 t" @9 ` ![]() 2.3 生成工程代码并初步测试5 Q( [2 J' `( m2 i" W 2.3.1 点击“GENERATE CODE”生成工程代码* Z' o, d2 {2 U; s9 s* b3 G( v " A% c4 Q& p* m5 g7 w- e ![]() 6 K* z# J: o2 r' n1 P4 H! Y( I7 r 2.3.2 在生成的代码中添加BLE Trace&Debug初始化代码 : W$ j* d- x% S; z6 y+ D9 I 2.3.3 在“main.c”文件中取消“MX_UART_Init(void)”的“static”属性 0 [9 R G" ~% C+ B 2.3.4 在“app_entry.c”文件中增加“Debug”模块的初始化代码“APPD_Init()”。+ @; ]2 N. \5 L9 d- i3 Y6 @ n ![]() ' t# s h( w" Q# y4 ~) \ 2.3.5 下载代码到STM32WB55-NUCLEO中运行。此时,在手机的蓝牙列表中,已经能成功地搜索添加的BLE设备。说明Debug和BLE协议栈已经成功运行。 ![]() 2.4 添加BLE Stack应用代码 为了便于对后续添加代码的理解,我们先将Central(手机)与STM32WB进行BLE通信的数据交互概括如下。所以需要将用户代码添加到Custom_STM_Event_Handler()、Custom_STM_App_Notification()中。 5 {4 s. k! a" i1 ^5 d( y ![]() BLE应用代码添加:定义用户数据缓存。( L$ C7 b0 e9 k, S! G6 O 在“custom_app.c”文件中定义4个用户缓存区数组。! T$ X, [# c0 i) x. K& T* X$ T ![]() & q, o" I2 f7 L" N* V# Z BLE事件驱动代码添加:! [0 j$ H0 E+ x# I3 ~5 E5 S/ a 在“custom_stm.c”文件中的“Custom_STM_Event_Handle r(void*Event)”中依次为WRITE_READ_DATA_BUF、WRITE_DATA_BUF、NOTIFY_DATA_BUF特征和属性添加stack层的事件驱动代码,以使BLE数据从stack层传递到app层。7 s$ E5 S& n0 Z 3 G" @( K" H: d 添加特征1 Events:WRITE_READ_DATA_BUF(即User_Write_Read_Data[]对应的写&读操作句柄)请求驱动代码。 ![]() 上图对应的代码文本如下所示:0 [5 l r' X1 x5 G4 j ![]() ( t# W8 H! s& O ![]() 上图对应的代码文本如下图所示:1 l- y/ q6 @9 E1 J. w3 E: `5 w . h* N7 s' u. @4 n ![]() 添加特征2 Events驱动:WRITE_DATA_BUF(即User_Write_Data []对应的写操作句柄)代码。! E0 ?5 ^; R5 m5 x ![]() 上图对应的代码文本如下图所示:2 U( U/ c5 g# z; w 0 r+ q3 V: \1 B7 g; ] ![]() 添加特征3 Events驱动:READ_DATA_BUF(即User_Read_Data[]对应的写操作句柄)代码* N* T) [+ q3 m ! l) Q- f0 c8 f& [3 n ![]() 2 d; X n- T& i8 a& n6 J5 r( N 上图对应的代码文本如下图所示:0 k( q7 ^% H( r. n5 r" {2 ^ ![]() # i* Y3 ~! }, ~, _ 添加特征4 Events驱动:NOTIFY_DATA_BUF(即User_Notify_Data[]对应的写操作句柄)请求驱动已经由STM32CubeMX自动完成了。NOTIFY_DATA_BUF不用再手动添加。 ![]() BLE应用数据代码添加:1 _" m9 Y, j/ r8 l" x 在“custom_app.c”文件中的Custom_STM_App_Notification(Custom_STM_App_Notification_evt_t*pNotification)”添加代码,以将BLE数据上传到4个User_xxx_Data[]缓冲区,依次添加代码如下。 ![]() 4 X2 A" G- w" ]) y7 ]# c 2.5 修改BLE最大数据包传输长度) T( V; L2 |* R* h 如果不修改,BLE单包长度最大仅为23字节 1. 在“app_conf.h”中修改BLE stack最大数据包长度(CFG_BLE_MAX_ATT_MTU) 6 r1 M5 x+ n& |4 p ![]() 6 C b4 u, g- B9 H, b 2. 在“app_ble.c”文件SVCCTL_UserEvtFlowStatus_t_SVC CTL_App_Notification(void*pckt)中添加红色部分代码。 ![]() ; y8 l: Z8 `7 J8 i) l* z% M 至此,所有代码更改完成。9 h! q2 ^; ~ m' ^# ^4 R 6 a; H5 l9 F$ s& p ]: ]0 Q, V4 Y( W 03测试平台搭建及功能测试3 Z. Y& { H4 r) p' b" D 1 Z* e* g3 O0 {7 ^9 W/ W' ~+ D O 3.1 使用STM32CubeProgrammer BLE协议栈安装(升级) / ?- o/ ]8 F% [" ~( B2 ~% L+ V 升级ST-LINK固件以保证与STM32CubeProgrammer驱动是匹配的+ p1 i4 D, ?6 r+ {' w* C/ ] & I, A4 @# Z9 v% F) N( ]( D2 k6 \ ![]() 查看当前FUS版本,并将FUS升级到最新版本+ h1 i+ g" q' p: k4 N$ ? ![]() 8 K: T0 t$ |9 i, a# C# C: R 如果当前FUS版本是0.5.3,FUS固件使用“stm32wb5x_FUS_fw_for_fus_0_5_3.bin”,否则FUS固件使用“stm32wb5x_FUS_fw.bin”,强烈建议阅读BLE协议栈及FUS升级详细说明“STM32Cube_FW_WB_V1.13.3\Projects\ STM32WB_Copro_Wireless_Binaries\STM32WB5x\Release_Notes.html”。 % d& t- ~% I$ T! K ![]() 升级(安装)BLE协议栈,根据MCU型号选择相应的固件和下载地址 # h: e1 x0 Y5 P$ P0 [ ![]() 3.2 测试平台搭建及验证 ) n& D+ H! t8 s- Y7 w. b% ^: d 3.2.1 在Android安卓应用市场下载安装“BLE调试助手”- p" i. O- ~0 d6 v& V3 _' R ![]() 3 g! F0 l- {; D$ I9 F/ I 3.2.2 可发现设备“MY_STM32WB”,并点击“CONNECT”后可以发现application特征和属性访问服务,如下图所示。7 u B3 \7 v$ J2 }8 O: j* D ![]() 3.2.3 设置BLE最大单包传输长度为256字节,否则L2CAP层传输超过23字节将自动分包。 5 c' d9 o0 n, O# W; h2 e/ i$ _ ![]() 3.2.4 手机app写数据访问(User_Write_Read_Data[64])测试 3 o0 h& M- d" S( { ![]() 3.2.5 手机App读数据访问(User_Write_Read_Data[64])测试 ![]() 3.2.6 手机App写User_Write_Data[64]测试: D7 G1 }1 C' c9 p) t$ ~5 h2 z0 p2 b ![]() 3.2.7 手机App读User_Read_Data[64]测试。7 M6 U. v, R8 S0 c3 M! k ![]() 3.2.8 通知数据访问(User_Notify_Data[64])测试5 Q$ X6 S$ u* M( |* Q- v' ~$ b2 d! _ 8 A; M. D s) c) ]0 T( T. s ![]() ) U+ Y& Q- | M# _; x5 ~0 E" B& w 至此,整个验证和测试过程完成。3 N+ F- j7 e) k! o6 l% D6 k # G$ y3 \6 L/ c: k$ l7 D7 P ( P! M' H @" Q 04小结 BLE经过多年的发展和迭代,BLE协议本身已是一个很复杂和庞大的协议族,如果希望开发自定义Service和GATT应用时,若对底层协议不熟悉的话还是较为困难的。但是由于STM32良好的生态,特别是借助于我们的STM32CubeMX+STM32Cube_FW_ WB固件包,使得我们可以快速、高效地开发出各种BLE应用。 1 [3 g2 f& z3 X/ u& b( D7 b* ? # K$ }6 t8 x, } 7 q' j1 ?! C4 n& \ 转载自: STM32单片机 8 j- C. g0 X) b/ N) B7 J' c |
【NUCLEO-WB09KE评测】+3.蓝牙广播
Nucleo-STM32WB09KE测评-蓝牙调试并使用OLED显示数据
【NUCLEO-WB09KE评测】创建BLE工程和开启调试信息
【NUCLEO-WB09KE评测】+2.串口打印
【NUCLEO-WB09KE评测】+5.实现标准电量服务
【NUCLEO-WB09KE评测】BLE例程HeartRate及工具探索
STM32WB系列MCU低功耗测试
Nucleo-STM32WB09KE测评--IIC传感器读取
【NUCLEO-WB09KE评测】+4.蓝牙控制LED
【NUCLEO-WB09KE评测】+1.点灯
谢谢分享,是否有其他的custom template案例来参考