nRF52832 广播相关配置

nRF52832 广播相关配置

先上例程中和广播有关的代码吧:

/**@brief Function for initializing the Advertising functionality.
 *
 * @details Encodes the required advertising data and passes it to the stack.
 *          Also builds a structure to be passed to the stack when starting advertising.
 */
void advertising_init(void)
{
    ret_code_t    err_code;
    ble_advdata_t advdata;
    ble_advdata_t srdata;

    ble_uuid_t adv_uuids[] = {{LBS_UUID_SERVICE, m_lbs.uuid_type}};

    // Build and set advertising data.
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance = true;
    advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;


    memset(&srdata, 0, sizeof(srdata));
    srdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
    srdata.uuids_complete.p_uuids  = adv_uuids;

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);

    err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
    APP_ERROR_CHECK(err_code);

    ble_gap_adv_params_t adv_params;

    // Set advertising parameters.
    memset(&adv_params, 0, sizeof(adv_params));

    adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;
    adv_params.duration        = APP_ADV_DURATION;
    adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    adv_params.p_peer_addr     = NULL;
    adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
    adv_params.interval        = APP_ADV_INTERVAL;

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);
    APP_ERROR_CHECK(err_code);
}

然后调用err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);启动广播
SDK中提供的广播流程:
在这里插入图片描述

转换之后就是例程中的两行:

err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &adv_params);
err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);

简单看看sd_ble_gap_adv_set_configure吧

广播配置函数sd_ble_gap_adv_set_configure

uint32_t sd_ble_gap_adv_set_configure(uint8_t *p_adv_handle,ble_gap_adv_data_t const *  p_adv_data,ble_gap_adv_params_t const * p_adv_params)   

[in,out]    p_adv_handle    Provide a pointer to a handle containing BLE_GAP_ADV_SET_HANDLE_NOT_SET to configure a new advertising set. On success, a new handle is then returned through the pointer. Provide a pointer to an existing advertising handle to configure an existing advertising set.
[in]    	p_adv_data  	Advertising data. If set to NULL, no advertising data will be used. See ble_gap_adv_data_t.
[in]    	p_adv_params    Advertising parameters. When this function is used to update advertising data while advertising, this parameter must be NULL. See ble_gap_adv_params_t.

第一个参数p_adv_handle

这里创建新的广播设置,第一个参数p_adv_handle使用BLE_GAP_ADV_SET_HANDLE_NOT_SET

第二个参数ble_gap_adv_data_t const * p_adv_data

第二个参数ble_gap_adv_data_t const * p_adv_data为广播数据。首先配置一个空间给ble_gap_adv_data_t ,然后设置数据即可。

初始化ble_gap_adv_data_t 配置内存
/**@brief Struct that contains pointers to the encoded advertising data. */
static ble_gap_adv_data_t m_adv_data =
{
    .adv_data =
    {
        .p_data = m_enc_advdata,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
    },
    .scan_rsp_data =
    {
        .p_data = m_enc_scan_response_data,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX

    }
};
ble_gap_adv_data_t 写入数据

adv_data 为广播数据,
scan_rsp_data为扫描回应数据,
本质其实就是个指针和长度而已,关键就是里面的数据了。
初始化这些数据,可以使用函数ble_advdata_encode实现。因为有广播数据和扫描回应数据,所以需要执行两次分别初始化这两个变量。

ble_advdata_encode函数原型

ret_code_t ble_advdata_encode(ble_advdata_t const *constp_advdata,uint8_t *const p_encoded_data,uint16_t *const p_len)  
/*
Function for encoding data in the Advertising and Scan Response data format (AD structures).
This function encodes data into the Advertising and Scan Response data format (AD structures) based on the fields in the supplied structures.
This function can be used to create a payload of Advertising packet or Scan Response packet, or a payload of NFC message intended for initiating the Out-of-Band pairing.

Parameters
[in]    p_advdata   Pointer to the structure for specifying the content of encoded data.
[out]   p_encoded_data  Pointer to the buffer where encoded data will be returned.
[in,out]    p_len   in: Size of p_encoded_data buffer. out: Length of encoded data.
*/

sdk说的还是很清楚了,所以去配置ble_advdata_t const *constp_advdata吧。
ble_advdata_t参数还是很多,详细看SDK,这里只看看例程中使用的几个参数:

ble_advdata_t advdata;
ble_advdata_t srdata;
ble_uuid_t adv_uuids[] = {{LBS_UUID_SERVICE, m_lbs.uuid_type}};

memset(&advdata, 0, sizeof(advdata));
advdata.name_type= BLE_ADVDATA_FULL_NAME;//广播名称类型,包括短名称,全称以及无名称
advdata.include_appearance = true;//Determines if Appearance shall be included. 应该涉及蓝牙的属性,还不清楚详细功能
advdata.flags= BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;//广播标志涉及蓝牙属性,在这里配置为一般发现模式,不支持BR/EDR 

memset(&srdata, 0, sizeof(srdata));
srdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);  
srdata.uuids_complete.p_uuids  = adv_uuids;  //List of UUIDs in the 'Complete' list.

BR:Basic Rate,EDR:Enhanced Data Rate,BR是正宗的蓝牙技术,似乎就是指经典蓝牙连接而已(待确认)

第三个参数ble_gap_adv_params_t const * p_adv_params

第三个参数ble_gap_adv_params_t const * p_adv_params,广播的一些配置信息

ble_gap_adv_params_t adv_params;
// Set advertising parameters.
memset(&adv_params, 0, sizeof(adv_params));
adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;  //此版本SoftDevice只支持此选项
adv_params.duration        = APP_ADV_DURATION;  //广播超时时间 APP_ADV_DURATION为BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED 即无限制
adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;//设置广播为可连接和可扫描的无定向广告事件
adv_params.p_peer_addr     = NULL;
adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;//设置为允许任何设备的扫描和连接请求
adv_params.interval        = APP_ADV_INTERVAL;//设置广播间隔时间,单位为0.625 ms,这里APP_ADV_INTERVAL为64,也就是65*0.625ms=40ms

ble_gap_adv_params_t除了这些参数外还有一些,一部分为experimental features,还有一些在properties.type设置为BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED时无效。除了这些还有以下两个参数;

ble_gap_ch_mask_t ble_gap_adv_params_t::channel_mask    //屏蔽广播信道设置,广播使用信道37 38 39,只能针对这3个屏蔽,并且至少开启一个.
uint8_t ble_gap_adv_params_t::scan_req_notification  //设能广播扫描请求通知,当被扫描时,在蓝牙事件回调函数中激活(应该有更合适的词吧)BLE_GAP_EVT_SCAN_REQ_REPORT事件
//以上不需要屏蔽广播信道,不需要回调,所以都为0即可.

nRF52832 ble_app_blinky 例程

<think>好的,我现在需要帮助用户了解如何在nRF52832配置定向广播的具体代码。用户之前已经询问过蓝牙定向广播如何加快自动连接,现在他们可能正在实际开发中遇到了问题,需要具体的实现步骤。 首先,我需要确认用户的需求。他们可能已经了解了理论部分,现在需要实际的代码示例。用户可能正在使用Nordic的SDK,可能是nRF5 SDK或较新的nRF Connect SDK。但考虑到nRF52832通常与nRF5 SDK一起使用,尤其是像15.3.0这样的版本,我应该基于这个环境来提供代码。 接下来,我需要回顾nRF52832的蓝牙协议栈。Nordic的SDK中使用SoftDevice,定向广播需要配置特定的广播参数,比如类型为BLE_GAP_ADV_TYPE_ADV_DIRECT_IND。同时,用户需要指定目标设备的地址,也就是主设备的MAC地址。这可能涉及到设置定向广播的超时时间,通常为1.28秒,之后设备需要切换回非定向模式。 然后,我需要考虑代码的结构。通常,配置广播包括初始化广播参数、设置定向地址、处理超时事件等。用户可能需要示例代码,包括初始化和启动广播的部分,以及事件处理,比如超时后切换到非定向广播。 另外,用户可能需要注意以下几点:如何获取主设备的地址,是否需要配对过程,以及如何管理连接参数。此外,功耗也是一个问题,因为定向广播可能更耗电,尤其是在频繁使用时。 我还需要检查是否有常见的错误点,比如地址类型是否正确(公共地址还是随机地址),广播参数是否配置正确,以及事件处理函数是否正确处理超时情况。例如,如果广播超时后没有正确切换模式,设备可能停止广播,导致无法连接。 此外,用户可能需要了解如何与其他设备配合使用,比如主设备应该如何扫描和连接。可能需要设置白名单,或者主设备需要特定的扫描参数来快速响应定向广播。 最后,我需要确保提供的代码示例清晰,并且包含必要的注释,帮助用户理解每个步骤的作用。同时,提醒用户根据实际情况调整参数,比如广播间隔、超时时间,以及目标地址的设置。以下是</think>基于 **nRF5 SDK**(如v15.3.0)的nRF52832定向广播(Directed Advertising)配置代码示例及关键步骤解析: --- ### **1. 配置定向广播的核心代码** ```c #include "ble_gap.h" #include "ble_advdata.h" // 定义目标主设备的MAC地址(示例) static ble_gap_addr_t m_target_addr = { .addr_type = BLE_GAP_ADDR_TYPE_PUBLIC, // 或 BLE_GAP_ADDR_TYPE_RANDOM_STATIC .addr = {0x01,0x02,0x03,0x04,0x05,0x06} // 替换为主设备实际地址 }; // 配置定向广播参数 void start_directed_advertising(void) { ble_gap_adv_params_t adv_params = { .type = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND, // 定向广播类型 .p_peer_addr = &m_target_addr, // 目标设备地址 .fp = BLE_GAP_ADV_FP_ANY, // 过滤策略 .interval = MSEC_TO_UNITS(20, UNIT_0_625_MS),// 广播间隔20ms .timeout = 128 // 超时时间1.28秒(128*10ms) }; // 启动定向广播 uint32_t err_code = sd_ble_gap_adv_start(&adv_params, BLE_CONN_CFG_TAG_DEFAULT); APP_ERROR_CHECK(err_code); } // 处理广播超时事件(在BLE事件回调中) void on_ble_evt(ble_evt_t const * p_ble_evt) { switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_TIMEOUT: if (p_ble_evt->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_ADVERTISING) { // 定向广播超时后,切换为普通广播或重新尝试 stop_advertising(); start_normal_advertising(); // 自定义的非定向广播函数 } break; // 其他事件处理... } } ``` --- ### **2. 关键配置解析** #### **(1) 广播类型选择** - `BLE_GAP_ADV_TYPE_ADV_DIRECT_IND`:定向可连接广播,直接指向目标设备。 - **注意**:定向广播不支持携带额外广播数据(如设备名称),需确保`advdata.scan_rsp_data`为空。 #### **(2) 目标地址设置** - **地址类型**:需与主设备的地址类型匹配: - `BLE_GAP_ADDR_TYPE_PUBLIC`:公共地址(如手机蓝牙MAC)。 - `BLE_GAP_ADDR_TYPE_RANDOM_STATIC`:静态随机地址(常见于从设备)。 - **获取主设备地址**:通常通过首次扫描或配对过程获取并存储。 #### **(3) 广播参数优化** - **间隔(interval)**:建议设为 **20~30ms**(`MSEC_TO_UNITS(20, UNIT_0_625_MS)`)。 - **超时(timeout)**:固定为 **1.28秒**(值=128),超时后必须停止并切换广播模式。 --- ### **3. 完整流程示例** #### **步骤1:初始化BLE协议栈** ```c void ble_stack_init(void) { ble_enable_params_t ble_config = { .common_enable_params = { .vs_uuid_count = 1 // 至少1个UUID }, .gatt_enable_params = { .att_mtu = BLE_GATT_ATT_MTU_DEFAULT } }; uint32_t err_code = sd_ble_enable(&ble_config); APP_ERROR_CHECK(err_code); } ``` #### **步骤2:配置广播数据(无扫描响应)** ```c void advertising_init(void) { ble_advdata_t advdata; memset(&advdata, 0, sizeof(advdata)); advdata.name_type = BLE_ADVDATA_NO_NAME; // 定向广播不携带名称 advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE; // 无扫描响应数据(定向广播不支持) uint32_t err_code = ble_advdata_set(&advdata, NULL); APP_ERROR_CHECK(err_code); } ``` #### **步骤3:启动定向广播** ```c void start_directed_advertising(void) { // 参考前述代码... } ``` --- ### **4. 注意事项** #### **(1) 地址类型匹配** - 若主设备使用随机地址,需确保从设备配置的`.addr_type`与主设备类型一致,否则无法连接。 #### **(2) 超时处理** - 定向广播超时后必须停止并切换模式,否则协议栈会返回`NRF_ERROR_INVALID_STATE`错误。 #### **(3) 功耗限制** - 定向广播期间无线电持续工作,功耗较高(约0.5~1mA),不适合电池供电设备长期使用。 --- ### **5. 调试技巧** 1. **使用nRF Sniffer**:通过Wireshark抓包确认广播包是否包含正确的目标地址。 2. **日志输出**:在`sd_ble_gap_adv_start()`后检查返回错误码,常见错误: - `NRF_ERROR_INVALID_PARAM`:地址类型或间隔错误。 - `NRF_ERROR_INVALID_STATE`:未停止前一次广播。 3. **连接后参数协商**:在`BLE_GAP_EVT_CONNECTED`事件中调整连接间隔: ```c ble_gap_conn_params_t conn_params = { .min_conn_interval = MSEC_TO_UNITS(7.5, UNIT_1_25_MS), .max_conn_interval = MSEC_TO_UNITS(15, UNIT_1_25_MS), .slave_latency = 0 }; sd_ble_gap_conn_param_update(p_conn_handle, &conn_params); ``` 通过以上代码和配置nRF52832可实现快速定向广播连接,典型连接时间可缩短至30ms以内。实际开发中建议结合具体应用场景调整参数。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值