智能手环开发之 实现蓝牙(BLE)基本功能

0.前言

         随着医疗健康、可穿戴设备的发展,华为、小米、vivo等大厂都在做智能手环、手表等可穿戴设备。未来,蓝牙设备的开发也会越来越多。

关于蓝牙BLE起源发展,各种类型蓝牙芯片介绍,以及蓝牙手环的硬件开发等在之前的文章已经有过详细介绍。

本文主要介绍蓝牙手环开发中,如何构建一个最小的BLE系统框架,以及使用的模块。

总结一句话:能让芯片的蓝牙协议栈跑起来,手机能连接上蓝牙手环设备。

 

                

要让蓝牙功能跑起来,需要将注意力放在BLE开发的程序框架和模块的整体功能上,之后再深入学习各个模块。

1.BLE程序框架

智能手环的核心除了各种传感器算法,最重要的就是蓝牙了。一个BLE程序通常至少包含4个必要部分:系统初始化、启动、空闲管理和事件处理。如下图所示。

(1)系统初始化

这个系统初始化看起来很简单,小学生貌似都能懂,不就是初始化系统吗?

的确是初始化系统,那需要初始化什么呢?

a.日志打印初始化:说白了就是为了方便我这种开发狗看上电启动的Log信息以及后续输出调试信息。不是必须的,但很重要。

b.APP定时器初始化:初始化APP定时器,用于实现各种定时任务。很重要。

c.硬件初始化:如指示灯初始化、OLED屏幕初始化、电源管理初始化等。

d.BLE相关初始化:包含蓝牙协议栈初始化、广播、首选连接参数、GAP层、服务等初始化配置。这部分初始化完成后,整个BLE部分的程序就会按照我们自己设置的参数运行。

(2)启动

对于外围设备来说,如手环,启动的是广播,启动之后系统开始按照配置的广播间隔开始发送广播,等待中心设备连接,也就是等待手机连接。

对于中心设备(手机)而言,启动的是扫描,扫描周围的蓝牙设备。

(3)空闲管理

    空闲管理说白了就是为了省电,实现低功耗。你戴个手环,总不希望天天充电吧。空闲管理就是在你不看手环时候让手环进入到低功耗模式。若有事件唤醒,如抬手腕亮屏等,就会恢复工作模式。

    若程序中启用了日志打印功能,空闲管理还处理挂起的日志信息。

(4)事件处理

应用程序通过注册“事件监听”来监视BLE协议栈事件。开发过Android就比较容易理解,如Button就需要监听,看看Button是否按下等。

 蓝牙中如外围设备和中心设备连接后,SoftDevice会提交 “连接事件”,应用程序会在事件处理函数中接收该事件并执行操作。

 对于一开始接触蓝牙开发的人而言,看完这些感到一丝丝懵逼也是很正常的。开发过蓝牙的话,这些就很容易理解了。

  没关系,下面开始实战。

  本次开发选用 Nordic nRF52832蓝牙芯片,相关开发板某宝也有很多卖。关于Nordic芯片之前的文章有过介绍,翻阅历史文章。

2.先看Main函数

    Main函数中主要调用各个模块的初始化函数,如硬件初始化、IIC屏幕初始化等,这些模块初始化本文暂不深入,主要是讲蓝牙架构。其中最重要的是蓝牙初始化。

    弄懂了蓝牙初始化,蓝牙就能跑起来。

int main(void)

{

    //Log 初始化

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));

    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("log init ok.");

    NRF_LOG_FLUSH();    


    //硬件初始化,APP timer,led,power Manager等

    my_ble_init_harder();


    //twi初始化,iic设备扫描,iic_sacn.c

    iic_scan_address();

    nrf_delay_ms(2000);


    //蓝牙初始化

    my_ble_init();

}

//蓝牙初始化函数

void my_ble_init(void)

 {

    NRF_LOG_INFO("Hello world BLE developer\n");

    NRF_LOG_INFO("BLE Template example:Log use uart as output terminal");

    //初始化协议栈

    ble_stack_init();

    NRF_LOG_INFO("ble_stack_init()...OK");


    //配置GAP参数

    gap_params_init();

    NRF_LOG_INFO("gap_params_init()...OK");
  

    //初始化GATT

    gatt_init();

    NRF_LOG_INFO("gatt_init()...OK");


    //初始化广播

    advertising_init();

    NRF_LOG_INFO("advertising_init()...OK");


    //初始化服务

    services_init();

    NRF_LOG_INFO("services_init()...OK");


    //连接参数协商初始化

    conn_params_init();

    NRF_LOG_INFO("conn_params_init()...OK");


    //ble_address_change_test();

    //启动app time定时器

    NRF_LOG_INFO("BLE HRS example started."); 

    application_timers_start();
  

    //启动广播

    NRF_LOG_INFO("advertising_starting...");

    advertising_start();

   //主循环

    while(true)

    {

        //OLED 显示

        my_oled_iic();

        //处理挂起的LOG和运行电源管理

        idle_state_handle();

    }

 }   

3.蓝牙初始化

    如上面代码,蓝牙初始化,包括初始化蓝牙协议栈,配置GAP参数,初始化GATT,初始化广播,初始化服务,连接参数初始化,启动广播,主循环。完成这些,手环蓝牙芯片就能够发广播了,打开手机蓝牙就能够搜索到。

    当然,这些初始化函数也是有很多内容的,也是非常关键的。实际蓝牙手环的代码复杂的多,需要花时间和精力去探索。

                    

4.总结

至于每个初始化函数的代码怎么写,还有广播参数等等,后面文章会逐一介绍。

毕竟一下子写的太长,也没人有耐心看下去。本文主要介绍蓝牙程序框架,以及跑起整个蓝牙时候大致的流程。

欲穷千里目,更上一层楼。了解整个架构,后续开发会轻松许多。

 

白浪介绍:

(1)关于射频、微波、天线、无线通信、智能硬件、软件编程、渗透安全、人工智能、区块链,Java、Android、C/C++、python等综合能力的培养提升。

(2)各种学习资料、学习软件分享。

  (3) 关注后,查看往期博客内容,会有更多技术文章

========******=========******========******=========******==========

发布了42 篇原创文章 · 获赞 13 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/sunskyday/article/details/104784879