蓝牙nRF52832开发板

1 概念

蓝牙芯片:系统级芯片(System on chip)是一种集成多功能模块到单一芯片的集成电路。蓝牙芯片就是一种系统级芯片,蓝牙芯片集成MCU(MicroControlUnit,微型控制单元)和RF(RadioFrequence,射频)两个功能,其中MCU负责蓝牙协议栈处理,RF负责无线数据收发。

Nordic:蓝牙系统级芯片生产公司。

nRF52832:Nordic公司生产的系统级芯片型号,参数如下表所示:

CPU运算器Flash闪存RAM随机存储器
64 MHz Arm Cortex-M4 with FPU512/256 KB64/32 KB
TWI/SPI/UART PWM, PDM, I2SADC, Comparator
2xTWI/SPI, SPI, UARTYesYes
Operating temperatureSupply voltage rangePackages
-40 to 85 °C1.7 to 3.6 V

6x6 mm QFN48
 (32 GPIOs)

3.0x3.2 mm WLCSP50
 (32 GPIOs)

TWI/I2C:两线串行接口,一根SCL,一根SDA,半双工通信;

SPI:同步串行总线,SDI(输入)、SDO(输出)、SCK(串行移位时钟)、CS(信号);

UART:串口,RX(接收)、TX(发送)和GND;

I2S:将两路音频信号变成单一的数据队列,比PCM更适合于立体声系统;

PDM:脉冲密度调制;

PWM:脉冲宽度调制;

ADC:模拟数字转换器;

Comparator:比较器,接受两路模拟信号输入,比较输入产生一路二进制输出信号;

Packages:封装方式。

BLE协议栈:实现低功耗蓝牙协议的代码,分为控制层、主协议层、应用层。

应用层:包括公有服务和私有服务等;

协议层:包括GAP、GATT、L2CAP、SMP、ATT等;

控制层:包括主机控制器HCI、链路层LL、物理层PHY等。

通用访问规范GAP:定义了蓝牙设备的广播、连接、发现和身份识别等基本行为的协议,主要功能包括:广播和扫描、连接和断开、安全性和身份识别;

通用属性配置文件GATT:定义设备之间数据通信的协议框架,主要包括服务、特性及描述符的定义,设备之间通过这些属性的读取和写入来交换数据。

服务配置列表:包含一个或多个服务的文件。

服务:蓝牙BLE中组织数据传输和接收的最小单位,包含一个或多个特性。

特性:包括特性参数和GATT属性;特性参数包括空中属性(写;没有回应的写;读;通知;指示)和描述符;GATT属性包括一个128位的UUID、属性参数和属性特征值。

服务UUID与特性UUID:用于标识一个服务/特性的唯一标识符,128位,通常表示为十六进制字符串。在 GATT 协议中,通过使用服务 UUID 和特性 UUID,蓝牙设备可以组织和交换数据。中央设备(如智能手机)可以通过读取和写入特性来与外围设备(如传感器)进行通信。这种基于 UUID 的标识机制确保了设备之间的互操作性。

MAC地址(Media Access Control Address):媒体存取控制位地址,蓝牙BLE的MAC地址可分为两种,分别为Public Device Address(公共设备地址)和Random Device Address(随机设备地址)。公共设备地址由企业向IEEE购买以保证唯一性;设置随机设备地址:静态设备地址11开头、不可解析私有地址00开头、可解析私有地址。

DFU(Device Firmware Update):设备固件升级,可以通过无线方式(OTA),重新烧录app到蓝牙芯片中,也可以通过有线方式(UART、USB及SPI)。

SWD(Serial Wire Debug):一种用于在嵌入式系统中进行调试和编程的通信接口。它是一种串行单线调试接口,用于连接调试工具(如调试器)与目标芯片,以进行调试、烧录和监控操作。

2 开发软件

keil MDK:C语言编写微控制器系统的软件。

nRFgo Studio:由 Nordic Semiconductor 开发的集成开发环境(IDE),配置和管理Nordic Semiconductor芯片相关的参数,可将程序烧录至芯片。

nRFconnect:由 Nordic Semiconductor 开发的一组工具和应用程序,用于开发、测试和调试基于 Nordic Semiconductor 射频(RF)芯片的无线应用。Program模块可烧录程序至芯片。

3 开发硬件

JLink:将在keil mdk等软件上编写的程序烧录至ARM、Cortex等芯片上的硬件。

nRF52832:Nordic公司生产的蓝牙芯片型号。

蓝牙芯片pinout通过杜邦线连接JLink仿真器,JLink仿真器通过USB连接电脑,安装驱动,重启电脑,打开Keil、nRFStudio和nRFconnect软件可连接并识别到设备。

4 硬件连接

4.1 实物连接方式(一)

如上图所示,传感器因电阻变化引起电压变化,通过数模转化器(HX711模块)将模拟信号转为数字信号,并通过(GND、VCC、RX和TX,即接地、电压、接收端和发送端)4个引脚将数据传输给蓝牙模块(HC-08)。该图中所用蓝牙芯片为TI厂家。

4.2 实物连接方式(二)

如上图所示,JLink仿真器通过USB连接至电脑,通过杜邦线连接至蓝牙芯片的程序烧录端口(对应蓝牙芯片的25、26号引脚),蓝牙芯片(7、8、9、10号引脚)通过CH340芯片(串口转USB)串口转为USB,再通过USB线连接电脑端串口小程序。

电脑端通过软件Keil将蓝牙程序烧录至蓝牙芯片,手机连接蓝牙后,可以发送指令让蓝牙芯片问串口要数据。

4.3 逻辑连接方式

上图所示为nordic 厂家的nRF52832型号的蓝牙芯片引脚图。

 上图所示为SWD接口及传感器与蓝牙芯片引脚对应图。

  上图所示为串口与蓝牙芯片引脚对应图。

5 程序从机设计

5.1 总体流程

连接流程:从机广播-》主机扫描-》发起连接-》连接建立-》数据交换。

蓝牙BLE基础工程搭建流程:打印输出LOG实现;板级设备初始化;内存管理初始化;协议栈初始化;GAP与GATT初始化;广播初始化;服务初始化;连接参数初始化。

5.2 协议栈初始化

该部分主要功能为使蓝牙能用。主要配置内容包括:时钟设置(内部RC时钟、外部晶振时钟、合成时钟)、广播事件、主从机设置、MTU、Gatt服务特性、注册蓝牙事件等。

外部晶振时钟:对电流消耗最低;

内部RC时钟:多消耗电流,节省成本;

内部高速时钟合成:消耗电流最多。

5.3 GAP设置

该部分主要功能为使蓝牙被发现和连接。主要配置内容包括:设备名称设置;连接参数设置(最小/最大连接间隔;从机延迟;连接超时监督时间)等。

5.4 添加服务

1)加入服务配置文件

创建services文件夹->引用官方xxx.c文件->在options for taret的C++中添加路径->在main.c文件中声明xxx.h文件,并声明xxx.h中的观察者函数名称

2)修改sdk_config.h服务配置

修改sdk_config.h文件中的NRF_SDH_BLE_VS_UUID_COUNT的数量,(因为该xx.c服务为官方提供服务)在配置文件中将BLE_LBS_C_ENABLED-ble_lbs_c-NordicLEDButtonServiceClient勾上

3)添加服务

main.c文件中services_init()方法调用xxx.c文件中声明的xxx_init()服务初始化函数,该函数的2个入参分别是该函数的观察者函数和初始化函数,在这个函数中调用sd_ble_gatts_service_add()来添加主服务

// Add Main Service
    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_lbs->service_handle);

第一个参数:服务类型为主服务

第二个参数:用于服务的基础UUID

ble_uuid128_t base_uuid = {LBS_UUID_BASE};
    err_code = sd_ble_uuid_vs_add(&base_uuid, &p_lbs->uuid_type);
    VERIFY_SUCCESS(err_code);

    ble_uuid.type = p_lbs->uuid_type;
    ble_uuid.uuid = LBS_UUID_SERVICE;

第三个参数:唯一的服务句柄,作为服务的回调

4)添加特性

如果该服务不是SIG定义的服务,那么就需要自己根据GATT框架定义服务的特性。

	// Add HT characteristic
    memset(&add_char_params, 0, sizeof(add_char_params));
		// GATT
    add_char_params.uuid              = LBS_UUID_HT_CHAR; //
    add_char_params.uuid_type         = p_lbs->uuid_type;
    add_char_params.init_len          = 2;
    add_char_params.max_len           = 2;
		// characteristic
    add_char_params.char_props.read   = 1;
		add_char_params.char_props.write  = 1;
    add_char_params.char_props.notify = 1;

    add_char_params.read_access       = SEC_OPEN;
		add_char_params.write_access = SEC_OPEN;
    add_char_params.cccd_write_access = SEC_OPEN;

    err_code = characteristic_add(p_lbs->service_handle,
                                  &add_char_params,
                                  &p_lbs->ht_char_handles);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    } 	

5.5 广播设置

该部分主要功能为广播发包及回包内容设置。主要配置内容包括:设备全称类型、图标、服务UUID、广播模式设置等。

 广播初始配置结构体:

typedef struct
{
    ble_advdata_t           advdata;       /**< Advertising data: name, appearance, discovery flags, and more. ¹ã²¥°ü*/
    ble_advdata_t           srdata;        /**< Scan response data: Supplement to advertising data. »Ø°ü*/
    ble_adv_modes_config_t  config;        /**< Select which advertising modes and intervals will be utilized.*/
    ble_adv_evt_handler_t   evt_handler;   /**< Event handler that will be called upon advertising events. */
    ble_adv_error_handler_t error_handler; /**< Error handler that will propogate internal errors to the main applications. */
} ble_advertising_init_t;

广播发包和回收包结构体:

typedef struct
{
    ble_advdata_name_type_t      name_type;                           /**< Type of device name. */
    uint8_t                      short_name_len;                      /**< Length of short device name (if short type is specified). */
    bool                         include_appearance;                  /**< Determines if Appearance shall be included. */
    uint8_t                      flags;                               /**< Advertising data Flags field. */
    int8_t *                     p_tx_power_level;                    /**< TX Power Level field. */
    ble_advdata_uuid_list_t      uuids_more_available;                /**< List of UUIDs in the 'More Available' list. */
    ble_advdata_uuid_list_t      uuids_complete;                      /**< List of UUIDs in the 'Complete' list. */
    ble_advdata_uuid_list_t      uuids_solicited;                     /**< List of solicited UUIDs. */
    ble_advdata_conn_int_t *     p_slave_conn_int;                    /**< Slave Connection Interval Range. */
    ble_advdata_manuf_data_t *   p_manuf_specific_data;               /**< Manufacturer specific data. */
    ble_advdata_service_data_t * p_service_data_array;                /**< Array of Service data structures. */
    uint8_t                      service_data_count;                  /**< Number of Service data structures. */
    bool                         include_ble_device_addr;             /**< Determines if LE Bluetooth Device Address shall be included. */
    ble_advdata_le_role_t        le_role;                             /**< LE Role field. Included when different from @ref BLE_ADVDATA_ROLE_NOT_PRESENT. @warning This field can be used only for NFC. For BLE advertising, set it to NULL. */
    ble_advdata_tk_value_t *     p_tk_value;                          /**< Security Manager TK value field. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/
    uint8_t *                    p_sec_mgr_oob_flags;                 /**< Security Manager Out Of Band Flags field. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/
    ble_gap_lesc_oob_data_t *    p_lesc_data;                         /**< LE Secure Connections OOB data. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/
} ble_advdata_t;

广播模式配置结构体:

typedef struct
{
    bool     ble_adv_on_disconnect_disabled;     /**< Enable or disable automatic return to advertising upon disconnecting.*/
    bool     ble_adv_whitelist_enabled;          /**< Enable or disable use of the whitelist. */
    bool     ble_adv_directed_high_duty_enabled; /**< Enable or disable high duty direct advertising mode. Can not be used together with extended advertising. */
    bool     ble_adv_directed_enabled;           /**< Enable or disable direct advertising mode. */
    bool     ble_adv_fast_enabled;               /**< Enable or disable fast advertising mode. */
    bool     ble_adv_slow_enabled;               /**< Enable or disable slow advertising mode. */
    uint32_t ble_adv_directed_interval;          /**< Advertising interval for directed advertising. */
    uint32_t ble_adv_directed_timeout;           /**< Time-out (number of tries) for direct advertising. */
    uint32_t ble_adv_fast_interval;              /**< Advertising interval for fast advertising. */
    uint32_t ble_adv_fast_timeout;               /**< Time-out (in units of 10ms) for fast advertising. */
    uint32_t ble_adv_slow_interval;              /**< Advertising interval for slow advertising. */
    uint32_t ble_adv_slow_timeout;               /**< Time-out (in units of 10ms) for slow advertising. */
    bool     ble_adv_extended_enabled;           /**< Enable or disable extended advertising. */
    uint32_t ble_adv_secondary_phy;              /**< PHY for the secondary (extended) advertising @ref BLE_GAP_PHYS (BLE_GAP_PHY_1MBPS, BLE_GAP_PHY_2MBPS or BLE_GAP_PHY_CODED). */
    uint32_t ble_adv_primary_phy;                /**< PHY for the primary advertising. @ref BLE_GAP_PHYS (BLE_GAP_PHY_1MBPS, BLE_GAP_PHY_2MBPS or BLE_GAP_PHY_CODED). */
} ble_adv_modes_config_t;

入口文件中定义广播观察函数,连接发生变化后调用:

BLE_ADVERTISING_DEF(m_advertising);    


#define BLE_ADVERTISING_DEF(_name)                                                                  
static ble_advertising_t _name;                                                                    
NRF_SDH_BLE_OBSERVER(_name ## _ble_obs,                                                             
                     BLE_ADV_BLE_OBSERVER_PRIO,                                                     
                     ble_advertising_on_ble_evt, &_name)

void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
{
    ble_advertising_t * p_advertising = (ble_advertising_t *)p_context;

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_CONNECTED:
            on_connected(p_advertising, p_ble_evt);
            break;

        // Upon disconnection, whitelist will be activated and direct advertising is started.
        case BLE_GAP_EVT_DISCONNECTED:
            on_disconnected(p_advertising, p_ble_evt);
            break;

        // 广播超时后,开始下一个广播模式
        case BLE_GAP_EVT_ADV_SET_TERMINATED:
            on_terminated(p_advertising, p_ble_evt);
            break;

        default:
            break;
    }
}

static void on_terminated(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
{
    ret_code_t ret;

    if (p_ble_evt->header.evt_id != BLE_GAP_EVT_ADV_SET_TERMINATED)
    {
        // Nothing to do.
        return;
    }

    if (  p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT//¹ã²¥³¬Ê±
        ||p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED)´ïµ½ÏÞÖƵĹ㲥ʼþ
    {
        //开始广播下一个广播模式
        ret = ble_advertising_start(p_advertising, adv_mode_next_get(p_advertising->adv_mode_current));

        if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
        {
            p_advertising->error_handler(ret);
        }
    }
}

5.6 启动广播

advertising_start(erase_bonds):启动广播;

ret = set_adv_mode_fast(p_advertising, &p_advertising->adv_params):设置为快速广播;

主函数BLE_ADVERTISING_DEF(m_advertising):广播观察函数,设置时间内未连接切换为慢速广播,最终切换为无效广播,设备进入休眠状态。

5.7 数据传输

采用观察者模型,即事先在main.c文件中定义监听函数,一旦收到主机消息即可调用:

NRF_SDH_BLE_OBSERVER(_name ## _obs,=BLE_LBS_BLE_OBSERVER_PRIO,ble_lbs_on_ble_evt, &_name)

服务建立后,主机通过服务中的写属性写一个数据给从机,从机接收到数据后,从协议栈上产生一个BLE_GATTS_EVT_WRITE事件,此时可调度服务处理事件。调度事件派发函数ble_lbs_on_ble_evt,该函数使用简单的switch-case语句通过回调事件头部的id区分不同的事件,并进行不同的处理。

(1)主从机通信方式

1)串口通道AT指令:将蓝牙设置为串口,通过串口协议进行通信,暂未调研。

2)私有任务通道:通过配置的服务和特性进行数据传输,即5.4节服务配置。

(2)从机获取数据方式

1)传感器数据通信

通过引脚直接获取数据,按照官方文件修改。

2)蓝牙串口通信

串口:串行通讯端口,9针或25针。

CH340T:USB转串口的硬件板。从机上配置CH340T可将串口转为USB接口。

 传感器主推数据,蓝牙从缓存中获取数据app_uart_get(),app_uart_fifo.c库文件

static void uart_loopback_test()
{
 
  while (true)
    {
        uint8_t cr;
        while(app_uart_get(&cr) != NRF_SUCCESS);
        while(app_uart_put(cr) != NRF_SUCCESS);

        if (cr == 'q' || cr == 'Q')
        {
            printf(" \n\rExit!\n\r");

            while (true)
            {
                // Do nothing.
            }
        }
    }

}

3)Flash存储

可从存储器中获取数据,暂未调研。

1)fstorage;

2)fds。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值