nrf51蓝牙未连接超时自动关机

问题

硬件: nrf51822开发板
软件: MDK
SDK: nRF5_SDK_12.3.0_d7731ad
工程是基于

nRF5_SDK_12.3.0_d7731ad\examples\ble_peripheral\ble_app_uart

在开发nrf51822过程中,发送大概3分钟未连接蓝牙后,就再也搜索不到该蓝牙,只能通过复位才能重新搜索到蓝牙,必现。


原因

在广播初始化中

/**@brief Function for initializing the Advertising functionality.
 */
static void advertising_init(void)
{
    uint32_t               err_code;
    ble_advdata_t          advdata;
    ble_advdata_t          scanrsp;
    ble_adv_modes_config_t options;

    // Build advertising data struct to pass into @ref ble_advertising_init.
    memset(&advdata, 0, sizeof(advdata));
    advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    advdata.include_appearance = false;
    advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;

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

    memset(&options, 0, sizeof(options));
    options.ble_adv_fast_enabled  = true;
    options.ble_adv_fast_interval = APP_ADV_INTERVAL;
    options.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;

    err_code = ble_advertising_init(&advdata, &scanrsp, &options, on_adv_evt, NULL);
    APP_ERROR_CHECK(err_code);
}

options.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS;配置的是当APP_ADV_TIMEOUT_IN_SECONDS指定时间内对端未连接,则触发

BLE_ADV_EVT_IDLE

事件,在本例程中对该事件的处理方式是

/**@brief Function for putting the chip into sleep mode.
 *
 * @note This function will not return.
 */
static void sleep_mode_enter(void)
{
    uint32_t err_code = sd_power_system_off();
    APP_ERROR_CHECK(err_code);
}


/**@brief Function for handling advertising events.
 *
 * @details This function will be called for advertising events which are passed to the application.
 *
 * @param[in] ble_adv_evt  Advertising event.
 */
static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
    uint32_t err_code;

    switch (ble_adv_evt)
    {
        case BLE_ADV_EVT_FAST:
            break;
        case BLE_ADV_EVT_IDLE:
            sleep_mode_enter();
            break;
        default:
            break;
    }
}

调用sleep_mode_enter();函数通知sd进入system OFF模式,对于该模式ds里面的描述是:

System OFF is the deepest power saving mode the system can enter. In this mode, the system’s core
functionality is powered down and all ongoing tasks are terminated. The only mechanism that is functional
and responsive in this mode is the reset and the wakeup mechanism

所以只能通过复位来唤醒MCU。


解决方法

解决方式有两种:
1. 在BLE_ADV_EVT_IDLE事件被触发后不要调用sleep_mode_enter();
2. 取消超时功能,即在advertising_init函数中配置options.ble_adv_fast_timeout为0同时配置advdata.flags为BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE

你可能感兴趣的:(嵌入式开发)