Nordic nRF5 SDK 学习笔记之八, Nordic UART Service NUS 服务透传

硬件: nRF52832 DK

软件: nRF SKD Ver 15.2

官方样例

        NUS 服务端: SDK15.2\ble_peripheral\ble_app_uart       

        NUS Client 客户端: SDK15.2\examples\ble_central\ble_app_uart_c

DOC 文档

         Nordic UART Service, ~/nRF5_SDK_15.2.0_offline_doc/nrf5/group__ble__nus.html

         Nordic UART Service Client,~/nRF5_SDK_15.2.0_offline_doc/nrf5/group__ble__nus__c.html

有用参考https://devzone.nordicsemi.com/f/nordic-q-a/28208/when-is-nus-ready (提及 Nordic UART Service (NUS) event types) 


NUS-S 服务端程序开发要点:

1. 于 sdk_config.h Configuration Wizard 中,选中  BLE_NUS_ENABLED;

2. 项目结构中,添加 文件 ble_nus.c;

3. 蓝牙服务初始化, 以及 NUS 服务初始化;

static void services_init(void)
{
    uint32_t           err_code;
    ble_nus_init_t     nus_init;
    nrf_ble_qwr_init_t qwr_init = {0};

    // Initialize Queued Write Module.
    qwr_init.error_handler = nrf_qwr_error_handler;

    err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
    APP_ERROR_CHECK(err_code);

    // Initialize NUS.
    memset(&nus_init, 0, sizeof(nus_init));

    nus_init.data_handler = nus_data_handler;

    err_code = ble_nus_init(&m_nus, &nus_init);
    APP_ERROR_CHECK(err_code);
}

4. NUS 服务对应的中断事件处理;


/**@brief Function for handling the data from the Nordic UART Service.
 * @details This function will process the data received from the Nordic UART BLE Service and send
 *          it to the UART module.
 * @param[in] p_evt       Nordic UART Service event.
 */
/**@snippet [Handling the data received over BLE] */
static void nus_data_handler(ble_nus_evt_t * p_evt)
{

    if (p_evt->type == BLE_NUS_EVT_RX_DATA)
    {
        uint32_t err_code;

        NRF_LOG_INFO("Received data from BLE NUS. Writing data on UART.");
        NRF_LOG_HEXDUMP_DEBUG(p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);

        for (uint32_t i = 0; i < p_evt->params.rx_data.length; i++)
        {
            do
            {
                err_code = app_uart_put(p_evt->params.rx_data.p_data[i]);
                if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY))
                {
                    NRF_LOG_ERROR("Failed receiving NUS message. Error 0x%x. ", err_code);
                    APP_ERROR_CHECK(err_code);
                }
            } while (err_code == NRF_ERROR_BUSY);
        }
        if (p_evt->params.rx_data.p_data[p_evt->params.rx_data.length - 1] == '\r')
        {
            while (app_uart_put('\n') == NRF_ERROR_BUSY);
        }
    }
		else if(p_evt->type == BLE_NUS_EVT_COMM_STARTED)
    {
			NRF_LOG_INFO("BLE_NUS_EVT_COMM_STARTED ");
			nus_data_send_to_central_welcome();
    }
		else if (p_evt->type == BLE_NUS_EVT_TX_RDY )
		{
			NRF_LOG_INFO("BLE_NUS_EVT_TX_RDY ");
		}
		else if (p_evt->type == BLE_NUS_EVT_COMM_STOPPED)
		{
			NRF_LOG_INFO("BLE_NUS_EVT_COMM_STOPPED ");
		}
}
/**@snippet [Handling the data received over BLE] */

5. NUS 数据透传函数 

uint32_t ble_nus_data_send(ble_nus_t * 	p_nus,
    uint8_t * 	p_data,
    uint16_t * 	p_length,
    uint16_t 	conn_handle 
)	

6. NUS 服务事件类型 

/**@brief   Nordic UART Service event types. */
typedef enum
{
    BLE_NUS_EVT_RX_DATA,      /**< Data received. */
    BLE_NUS_EVT_TX_RDY,       /**< Service is ready to accept new data to be transmitted. */
    BLE_NUS_EVT_COMM_STARTED, /**< Notification has been enabled. */
    BLE_NUS_EVT_COMM_STOPPED, /**< Notification has been disabled. */
} ble_nus_evt_type_t;

7. 重要提醒

* NUS 数据透传函数  uint32_t ble_nus_data_send()  使用前, NUS Client 客户端须使能服务通知 (Notification); 否则会导致程序出错!

* 于 NUS 服务的中断回调函数 static void nus_data_handler(ble_nus_evt_t * p_evt) {} 中,通过变量 p_evt->type 获取 NUS 服务事件类型; 即是 p_evt->type 为 BLE_NUS_EVT_COMM_STARTED 时, NUS 数据透传函数  uint32_t ble_nus_data_send() 可正常使用

* NUS 服务与 UART 串口没有关联!可单独使用。


NUS-C 客户端程序开发要点:

1. 于 sdk_config.h Configuration Wizard 中,选中  BLE_NUS_C_ENABLED;

2. 项目结构中,添加 文件 ble_nus_c.c;

3. NUS_C 初始化;

/**@brief Function for initializing the Nordic UART Service (NUS) client. */
static void nus_c_init(void)
{
    ret_code_t       err_code;
    ble_nus_c_init_t init;

    init.evt_handler = ble_nus_c_evt_handler;

    err_code = ble_nus_c_init(&m_ble_nus_c, &init);
    APP_ERROR_CHECK(err_code);
}

4. NUS_C 对应的中断事件处理;


/**@brief Callback handling Nordic UART Service (NUS) client events.
 * @details This function is called to notify the application of NUS client events.
 * @param[in]   p_ble_nus_c   NUS client handle. This identifies the NUS client.
 * @param[in]   p_ble_nus_evt Pointer to the NUS client event.
 */

/**@snippet [Handling events from the ble_nus_c module] */
static void ble_nus_c_evt_handler(ble_nus_c_t * p_ble_nus_c, ble_nus_c_evt_t const * p_ble_nus_evt)
{
    ret_code_t err_code;

    switch (p_ble_nus_evt->evt_type)
    {
        case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
            NRF_LOG_INFO("Discovery complete.");
            err_code = ble_nus_c_handles_assign(p_ble_nus_c, p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
            APP_ERROR_CHECK(err_code);

            err_code = ble_nus_c_tx_notif_enable(p_ble_nus_c);
            APP_ERROR_CHECK(err_code);
            NRF_LOG_INFO("Connected to device with Nordic UART Service.");
            break;

        case BLE_NUS_C_EVT_NUS_TX_EVT:
            ble_nus_chars_received_uart_print(p_ble_nus_evt->p_data, p_ble_nus_evt->data_len);
            break;

        case BLE_NUS_C_EVT_DISCONNECTED:
            NRF_LOG_INFO("Disconnected.");
            scan_start();
            break;
    }
}
/**@snippet [Handling events from the ble_nus_c module] */

5. NUS_C 数据透传函数 

uint32_t ble_nus_c_string_send	(	ble_nus_c_t * 	p_ble_nus_c,
    uint8_t * 	p_string,
    uint16_t 	length 
)	

6. NUS_C 事件类型

猜你喜欢

转载自blog.csdn.net/weixin_42396877/article/details/84891603