(原创文章,已同步多个平台,转载请与作者联系)
0.前言
随着医疗健康、可穿戴设备的发展,华为、小米、vivo等大厂都在做智能手环、手表等可穿戴设f z i备。未来,蓝牙设备的开发也会越来越多。
关于蓝牙BLE起源发展,各种类型蓝牙芯片介绍,以及蓝牙手环的硬件开发等在之前的文章已经有过详细介绍。
本文主要介绍蓝牙手环开发中,如何& T T ? # y构建一个最小的BLE系统框架,以及使用的模块 2 6 9 y。
总结一句话:能让芯片的蓝牙协议栈跑起来,手机能连接上蓝牙手环设备。
要让蓝牙功能跑起来,需要将注意力放在BLE开发的程序框架和模块的整体功能上,之后再深s q N e T J S入学习各个模块。
1.BLE程序框架
智能i a N { = -手环的核心除了各种? . D * 9 O M T传感器算法,9 g } N最重要的就是蓝牙了。一个BLE程序通常至少包含4个必要部分:系统初始化、w 5 K启动、空闲管理和事件处理。如[ H ? T 7 & ` f Y下图所示。
(1)系统初始化
这个系统初始化看起来很简单,小学生貌似都能懂,不就是初始化系统吗?
的确是初始化系统,那需要初始化什么呢?
a.日志打印初始化:说白了就是为了方便我这种开发狗看] d : # 2 $上k : z @ { A s电启动的Log信息以及后续输出调试信息。不是必须的,但很重要。
b.APl z X ` . F PP定时器初始化:初始化APP定时器,用于实现各种定时任务。很重要。
c.硬件初始化:如指示灯初始化、OLED屏幕初始化、电源管理初始化等。
d.BLE相关初始化:包含蓝牙协议栈初始化、广播、首选连接参数、GAP层、服务等初始化配置。这i b d m ! 0 f部分初始化完成后,整个BLE部分的程序就会按照我们自己设置的参数运行。
(2)启动
对于外围设备来说,如手环,启动的是广播,启动之后系统开始按照配置的广播间隔开始发送广播,等待中心设备连接,也就是等待手机连接。
对于中心设备(手机)而言,启动的是扫描,扫描周围的蓝牙设备。
(3)空闲管理
空闲管理说白了就是为了省电,实现低功耗。你戴个手环,总不希望天天充电吧i { @ ! ) s ~。空闲管理就是在你不看手环时候让手环进入到低功耗模式l ( p。若有事件唤醒,如抬手腕亮屏等,就会恢复工作模式。
若k q 9 S d w程序中启用了日志打印功能,空闲管理还处理挂起的日志信息。
(4)事件处理
应用程序通过注册\o C N * ^ a"事件监听\"来监视BLE协议栈事件。开发过Android* J 3就比较容易理解,如Button就需要监听,看看Button是否按I 0 k F g z b Y M下等。
蓝牙中如外围设备和中心设备连接后,SoftD3 } | % Y Mevice会提交 \"连接事件\",应用程序会在事_ l L M件处理函数中接收该事件并执行操作。
对于一开始接触蓝牙开发的人而言,看完这些感到一丝丝懵逼! H ] 0 - F也是很正常的。开发过蓝牙的话,这些就很容易理解了。
没关系,下面开始实战。
本次开发选用 Nordic nRF52832蓝牙芯片,相关开发板某宝也有很多卖。关于Nordic芯片之前的文章有过介绍,翻阅历史文章。
2.先看Main函数
Main函数中主要调用各个模块f Q ) F ) n的初始化函数,如硬件初始化、IIC屏幕初始化等,这些模块初始化本文暂不深入,主要是讲蓝牙架构。其U { ^中最重A 4 : & /要的是蓝牙: M X , Y 3初始化。
弄懂了蓝牙初始化,蓝牙就能跑起来。
int mai[ 4 8 } D - + Un(void)
{
//Log 初始化
APP_ERROR_CHECK(NRFW / q I x_LL F Z s i s T G ROG_INIT(NULL));
NRF_L0 & ,OG_DEFAULT_BACKENDS_INIT();
NRF_LOG_INFO(\"log init ok.\");
/ E T ! r NRF_LOG_FLUe F c * : f C + &SH();
d ( s [ _ &nX * O K S : b vbsp;
//硬件初始化,APP timer,led,pob ( A : 9 % w qwer Manager等
&nbL F $ X * 5sp; e F x ? I r my_ble_init_harder();
//twi初始化,iic设备扫描,iic_sacn.c
iic_scan_address();
nrf_delay_ms(2000);
&nbs( a r q O U ; 4p; //蓝牙初始化
my_ble_init();
}
//蓝牙初始化函数
void my_ble_ini^ ! 0t(void)
{
NRF_LOG_INFO(\"Hello world BLE developer\\nt D a\");
NRF_LOG_+ u h p y 5 G E +INFO(\"BLE Template ec Q # } axample:Log use uarg S T V ` n J R )t as output terminal\");
&nbs* b Kp;//初d j h $ w p %始化协p A P 7 k 9议栈
ble_stack_init();
NRF_LOG_INFO(\"ble_stack_init()...OK\");
//配置GAP参数
gap_params_init();
NRF_LOG_INFO(z . 0 l\"gap_B A params_init()...OK\");
&nbK _ % L G & [ - 6sp;
//初始化GATT
&nI 5 w $ w w [ v Obsp; &nbx { R :sp; gatt_init();
NRF_LOG_INFO(\"gatt_init()...OK\");
&nA 6 ! s ; C lbsp;//初始化广播
j 9 | 2 3 N advertising_init();
NRF_LOG_INFO(\"advertising_init()...OK\");
&nbc r & P e rsp;//初始化服务
services_init();
&n0 l l 7 P a - 9 Tbsp; NRF_LOG_INFO(\"services_init()...OK\");
//连接参数协商初始化
conn_params_init();
 , ^ m; NRF_LOG_INFO(\"conn_params_init()..D H M % r G h 7.O5 - u I B U 1 X RK\");
//ble_ad- . p # 0 Gdress_chaD K Z Onge_test();
//启动app time定时器
7 n P 0 : ; [ NRF_LO_ f aG_INFO(\"BLE HRS example started.\");
application_tB U Dimers_starW = H b x &t();
b 0 o ) //启动广播
C } R ^ O z G NRF_LOG_INFO(\"advertisi{ X ^ j m /ng_starting...\");
advertising_start();
//主循环
whi + Kle(true)
&nbsd ` U Q sp;{
&5 % } m +nbsp; //OLE^ c Y F ! pD 显示
M K w , G [ & x q my_oled_iic();
&nb6 4 m y t ~ P 7sp( - m = h j; //处理挂起的LOG和运行8 k z . p 3 电源管理
idle_state_handle();
}
}
3.蓝牙初始化
如上面代码,蓝牙初始化,包括初始化蓝牙协议栈,配置GAP参数,初始化GATT,初始化广播,初始化服务,x W T连接参数初始化,启动广播,主循环。完成这些,手环蓝牙芯片就能够发广播了,打开手机蓝牙就能够搜索到。6 ( 3 ? # ! m H
当然,这些初始化函数也是有很r T r多内容的,也是非常关键的。实际蓝牙手环的代码复杂的多,需要花时间和精力去探索。
4.总结
至于每个初始化函数的代码怎么写,还有广播参数等等,后面文章会逐一介绍。
毕竟一下子写的太长,也没人有耐心看下去。本文主要介绍蓝牙程序框架,以及跑起整个蓝牙时候大致的流程。
欲穷千里目,更上一层楼。了解整个架构,后续开发会轻松许多。