请解释 NRF5中nrf_sdh_enable_request
时间: 2023-09-16 18:12:37 浏览: 217
nrf_sdh_enable_request是一个函数,用于启用SoftDevice Handler Library(SDH)的功能。SDH是一个库,用于管理Nordic Semiconductor的SoftDevice,即蓝牙协议栈。当使用Nordic Semiconductor的SDK时,SDH通常被用来初始化和配置SoftDevice,并处理SoftDevice的事件和回调。nrf_sdh_enable_request函数会请求启用SDH,它将初始化SoftDevice并启动SoftDevice的事件处理。如果SDH已经被启用,该函数将什么都不做。
相关问题
两个手机的蓝牙app作为主机蓝牙连接一个nrf52832蓝牙模块,当第一台手机连接上nrf52832从机模块,其他手机就无法搜索到nrf52832从机模块的蓝牙名称了,这个nrf52832从机模块的实现代码怎么写呢?
nrf52832从机模块的实现代码需要使用SoftDevice API来实现蓝牙连接和广播。以下是一个简单的示例代码,用于设置从机模块的蓝牙名称和广播参数:
```c
#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#include "nrf_ble_qwr.h"
#include "nrf_ble_gatt.h"
#include "nrf_ble_scan.h"
#include "nrf_ble_advertising.h"
#define DEVICE_NAME "MyDevice" // 设置从机模块的蓝牙名称
static ble_gap_adv_params_t m_adv_params; // 广播参数
void ble_stack_init(void)
{
ret_code_t ret;
// Initialize the SoftDevice handler module.
NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
ret = nrf_sdh_enable_request();
APP_ERROR_CHECK(ret);
// Wait for SoftDevice to be enabled
while (nrf_sdh_is_enabled() == false)
{
// Do nothing.
}
// Enable BLE stack.
ret = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &cfg_ble);
APP_ERROR_CHECK(ret);
ret = nrf_sdh_ble_enable(&ram_start);
APP_ERROR_CHECK(ret);
}
void advertising_init(void)
{
ret_code_t ret;
uint8_t flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
memset(&m_adv_params, 0, sizeof(m_adv_params));
m_adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
m_adv_params.p_peer_addr = NULL;
m_adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
m_adv_params.interval = MSEC_TO_UNITS(100, UNIT_0_625_MS);
m_adv_params.duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED;
m_adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
m_adv_params.secondary_phy = BLE_GAP_PHY_1MBPS;
m_adv_params.scan_req_notification = false;
m_adv_params.discovery_mode = BLE_GAP_DISCOVERY_MODE_GENERAL;
// Add advertising data.
ble_advdata_t advdata;
memset(&advdata, 0, sizeof(advdata));
advdata.name_type = BLE_ADVDATA_FULL_NAME;
advdata.include_appearance = false;
advdata.flags = flags;
advdata.uuids_complete.uuid_cnt = 0;
advdata.uuids_complete.p_uuids = NULL;
// Set device name and advertising data.
ble_advdata_manuf_data_t manuf_data;
memset(&manuf_data, 0, sizeof(manuf_data));
manuf_data.company_identifier = 0x0059; // 设置厂商标识
manuf_data.data.p_data = NULL;
manuf_data.data.size = 0;
advdata.p_manuf_specific_data = &manuf_data;
ret = ble_advdata_encode(&advdata, m_adv_params.adv_data.p_data, &m_adv_params.adv_data.len);
APP_ERROR_CHECK(ret);
}
void advertising_start(void)
{
ret_code_t ret;
// Start advertising.
ret = sd_ble_gap_adv_start(&m_adv_params, APP_BLE_CONN_CFG_TAG);
APP_ERROR_CHECK(ret);
}
```
在这个示例代码中,首先需要初始化蓝牙协议栈,然后进行广播参数的设置和广播的开启。在设置广播参数时,需要指定广播类型、广播间隔、厂商标识等信息。在设置完广播参数之后,可以使用`sd_ble_gap_adv_start`函数开启广播。
需要注意的是,在蓝牙连接时,从机模块需要通过`sd_ble_gap_connect`函数响应主机的连接请求。如果从机模块已经与一个主机建立了连接,其他主机将无法连接该从机模块。如果需要支持多主机连接,需要使用多连接的蓝牙模块或者手动管理连接。
nrf52832作为从机,连接多主机的情况下,如何能感知出连接的主机的服务和特征呢?请给出具体的实现代码基于nrf52832软件库
在nrf52832的软件库中,可以使用SoftDevice API来实现BLE从机的连接和服务发现。具体实现代码如下:
首先,在初始化BLE从机时,需要开启SoftDevice和BLE从机模式:
```c
// 初始化SoftDevice
ret_code_t err_code = nrf_sdh_enable_request();
APP_ERROR_CHECK(err_code);
// 初始化BLE从机
ble_stack_init();
// 开启BLE从机模式
ble_gap_adv_start(&m_adv_params, APP_BLE_CONN_CFG_TAG);
```
然后,在连接建立后,可以在BLE事件处理函数中处理发现服务和特征的事件。在连接建立后,会触发BLE_GAP_EVT_CONNECTED事件,可以在该事件处理函数中启动服务发现过程:
```c
case BLE_GAP_EVT_CONNECTED:
{
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
// 开始服务发现
err_code = sd_ble_gattc_primary_services_discover(m_conn_handle, 0x0001, NULL);
APP_ERROR_CHECK(err_code);
break;
}
```
在服务发现过程中,会触发BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP事件和BLE_GATTC_EVT_CHAR_DISC_RSP事件。可以在这两个事件处理函数中获取服务和特征的UUID和句柄等信息:
```c
case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
{
ble_gattc_evt_prim_srvc_disc_rsp_t *p_response = &p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp;
// 遍历所有发现的服务
for (uint32_t i = 0; i < p_response->count; i++)
{
ble_uuid_t uuid = p_response->services[i].uuid;
// 根据UUID判断服务类型
if (ble_uuid_cmp(&uuid, &m_svc_uuid) == 0)
{
// 保存服务句柄
m_svc_handle = p_response->services[i].handle_range.start_handle;
}
}
break;
}
case BLE_GATTC_EVT_CHAR_DISC_RSP:
{
ble_gattc_evt_char_disc_rsp_t *p_response = &p_ble_evt->evt.gattc_evt.params.char_disc_rsp;
// 遍历所有发现的特征
for (uint32_t i = 0; i < p_response->count; i++)
{
ble_uuid_t uuid = p_response->chars[i].uuid;
// 根据UUID判断特征类型
if (ble_uuid_cmp(&uuid, &m_char_uuid) == 0)
{
// 保存特征句柄
m_char_handle = p_response->chars[i].handle_value;
}
}
// 特征发现完成,可以进行读写操作等
break;
}
```
完整的实现代码可以参考以下示例代码:
```c
#include <stdint.h>
#include <string.h>
#include "nordic_common.h"
#include "nrf.h"
#include "app_error.h"
#include "ble.h"
#include "ble_advdata.h"
#include "ble_conn_params.h"
#include "ble_nus.h"
#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#include "nrf_ble_gatt.h"
#include "nrf_ble_qwr.h"
#define DEVICE_NAME "My Device" /**< Name of device. Will be included in the advertising data. */
#define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */
#define APP_BLE_CONN_CFG_TAG 1 /**< A tag identifying the SoftDevice BLE configuration. */
#define APP_BLE_OBSERVER_PRIO 3 /**< Application's BLE observer priority. You shouldn't need to modify this value. */
#define MIN_CONN_INTERVAL MSEC_TO_UNITS(20, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms). */
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(75, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms). */
#define SLAVE_LATENCY 0 /**< Slave latency. */
#define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds). */
#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(30000) /**< Time between each call to sd_ble_gap_conn_param_update after the first (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */
#define BLE_NUS_MAX_DATA_LEN (BLE_GATT_ATT_MTU_DEFAULT - 3) /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
// UUID of the service and characteristic to discover
static ble_uuid_t m_svc_uuid =
{
.uuid = BLE_UUID_NUS_SERVICE,
.type = NUS_SERVICE_UUID_TYPE
};
static ble_uuid_t m_char_uuid =
{
.uuid = BLE_UUID_NUS_TX_CHAR,
.type = NUS_SERVICE_UUID_TYPE
};
// Service and characteristic handles
static uint16_t m_svc_handle = BLE_GATT_HANDLE_INVALID;
static uint16_t m_char_handle = BLE_GATT_HANDLE_INVALID;
// Connection handle
static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID;
// BLE stack initialization
static void ble_stack_init(void)
{
ret_code_t err_code;
// Initialize the SoftDevice handler module
err_code = nrf_sdh_enable_request();
APP_ERROR_CHECK(err_code);
// Configure the BLE stack using the default settings
err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &NRF_BLE_GATT_DEFAULT_CFG);
APP_ERROR_CHECK(err_code);
// Enable BLE stack
err_code = nrf_sdh_ble_enable(&APP_BLE_OBSERVER_PRIO);
APP_ERROR_CHECK(err_code);
}
// Advertising initialization
static void advertising_init(void)
{
ret_code_t err_code;
// Declare and initialize a BLE advertising packet structure
ble_advdata_t advdata;
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;
// Declare and initialize a BLE advertising parameters structure
ble_gap_adv_params_t adv_params;
memset(&adv_params, 0, sizeof(adv_params));
adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
adv_params.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 = MSEC_TO_UNITS(1000, UNIT_0_625_MS);
// Start advertising
err_code = sd_ble_gap_adv_set_configure(&adv_handle, &advdata, &adv_params);
APP_ERROR_CHECK(err_code);
err_code = sd_ble_gap_adv_start(adv_handle, APP_BLE_CONN_CFG_TAG);
APP_ERROR_CHECK(err_code);
}
// BLE event handler
static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
{
ret_code_t err_code;
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
{
m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
// Start service discovery
err_code = sd_ble_gattc_primary_services_discover(m_conn_handle, 0x0001, NULL);
APP_ERROR_CHECK(err_code);
break;
}
case BLE_GAP_EVT_DISCONNECTED:
{
m_conn_handle = BLE_CONN_HANDLE_INVALID;
break;
}
case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
{
ble_gattc_evt_prim_srvc_disc_rsp_t *p_response = &p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp;
// Traverse all discovered services
for (uint32_t i = 0; i < p_response->count; i++)
{
ble_uuid_t uuid = p_response->services[i].uuid;
// Determine the service type based on the UUID
if (ble_uuid_cmp(&uuid, &m_svc_uuid) == 0)
{
// Save the service handle
m_svc_handle = p_response->services[i].handle_range.start_handle;
}
}
break;
}
case BLE_GATTC_EVT_CHAR_DISC_RSP:
{
ble_gattc_evt_char_disc_rsp_t *p_response = &p_ble_evt->evt.gattc_evt.params.char_disc_rsp;
// Traverse all discovered characteristics
for (uint32_t i = 0; i < p_response->count; i++)
{
ble_uuid_t uuid = p_response->chars[i].uuid;
// Determine the characteristic type based on the UUID
if (ble_uuid_cmp(&uuid, &m_char_uuid) == 0)
{
// Save the characteristic handle
m_char_handle = p_response->chars[i].handle_value;
}
}
// Characteristic discovery completed, can perform read/write operations, etc.
break;
}
default:
// No implementation needed.
break;
}
}
// BLE stack initialization
static void ble_init(void)
{
ret_code_t err_code;
// Initialize BLE stack
ble_stack_init();
// Initialize GATT module
err_code = nrf_ble_gatt_init(&m_gatt, NULL);
APP_ERROR_CHECK(err_code);
// Initialize QWR module
err_code = nrf_ble_qwr_init(&m_qwr, &m_qwr_mem);
APP_ERROR_CHECK(err_code);
// Register BLE event handler
err_code = nrf_ble_gatt_cbs_register(&m_gatt, ble_evt_handler, NULL);
APP_ERROR_CHECK(err_code);
// Set the MTU size
err_code = sd_ble_gattc_exchange_mtu_request(m_conn_handle, BLE_GATT_ATT_MTU_DEFAULT);
APP_ERROR_CHECK(err_code);
// Initialize advertising
advertising_init();
}
int main(void)
{
// Initialize BLE
ble_init();
while (true)
{
// Do nothing
}
}
```
阅读全文