打开主菜单

谷雨文档中心 β

更改

NRF52832DK协议栈实验

添加6,403字节2019年7月26日 (五) 11:48
实验现象
==== 实验现象 ====
这一章的实验,打印的“乱七八糟”的内容比较多,原因在于我们调高了LOG打印的等级,我们将等级调成了DEBUG档位(最高级别),有关LOG等级的说明请大家查看本手册的LOG打印实验说明。
 
其中整个的流程,还是上电先扫描,然后发起连接,或者连接参数,更新MTU大小,最后再获取NUS服务。
 
当成功获取NUS服务之后,我们向从机Wirte“AAA”。
[[文件:Nrf rtt 110.png|边框|居中|无框|878x878像素]]
主机上电等待连接,连接成功后,获取连接参数,更新MTU大小。
 
当被主机使能Notify之后,我们向主机Notify“BBB”。
[[文件:Nrf rtt 210.png|边框|居中|无框|656x656像素]]
==== 工程及源码讲解 ====
 
===== 主机部分 =====
源码讲解的部分,我们接着上一章的NUS服务获取之后,开始说明,我们是怎么进行数据的收发的。
 
====== ble_nus_c_evt_handler()函数 ======
主机的nus client回调函数,相对于上一章节,在BLE_NUS_C_EVT_DISCOVERY_COMPLETE服务发现完成的事件中,我们开启了一个周期定时器任务。
 
这边需要注意,我们接收到从机Notify的数据,是由BLE_NUS_C_EVT_NUS_TX_EVT事件返回,我们可以在这边获取接收的数据。<syntaxhighlight lang="c" line="1" start="244">
//******************************************************************
// fn : ble_nus_c_evt_handler
//
// brief : NUS事件
//
// param : none
//
// return : none
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.");
app_timer_start(m_timer_nus, APP_TIMER_TICKS(1000), NULL);
break;
 
case BLE_NUS_C_EVT_NUS_TX_EVT:
NRF_LOG_DEBUG("Receiving data.");
NRF_LOG_HEXDUMP_DEBUG(p_ble_nus_evt->p_data, p_ble_nus_evt->data_len);
break;
 
case BLE_NUS_C_EVT_DISCONNECTED:
NRF_LOG_INFO("Disconnected.");
break;
default:
break;
}
}
 
</syntaxhighlight>那么接下来我们看一下定时器任务中处理了什么,可以看到我们初始化了一个周期定时器,这个定时器是1s执行一次,没过1s之后,就会返回一次nus_timeout_handler。
 
在这个nus_timeout_handler函数中,我们调用ble_nus_c_string_send()函数,去向从机设备发送AAA。<syntaxhighlight lang="c" line="1" start="458">
//******************************************************************
// fn : nus_timeout_handler
//
// brief : NUS定时器超时任务
//
// param : p_event -> 指向数据库发现事件的指针
//
// return : none
static void nus_timeout_handler(void * p_context)
{
ble_nus_c_string_send(&m_ble_nus_c, "AAA", 3);
}
 
//******************************************************************
// fn : timer_init
//
// brief : 初始化定时器
//
// param : none
//
// return : none
static void timer_init(void)
{
ret_code_t err_code = app_timer_init();
APP_ERROR_CHECK(err_code);
err_code = app_timer_create(&m_timer_nus,APP_TIMER_MODE_REPEATED,nus_timeout_handler);
APP_ERROR_CHECK(err_code);
}
</syntaxhighlight>
 
===== 从机部分 =====
我们从NUS的回调函数中,可以看到,我们利用BLE_NUS_EVT_RX_DATA事件接收主机Write的数据。
 
而当我们的Notification被使能的时候,也就是BLE_NUS_EVT_COMM_STARTED事件返回,我们通用会开启一个定时器任务。<syntaxhighlight lang="c" line="1" start="195">
//******************************************************************
// fn : nus_data_handler
//
// brief : 用于处理来自Nordic UART服务的数据的功能
// details : 该功能将处理从Nordic UART BLE服务接收的数据并将其发送到UART模块
//
// param : ble_nus_evt_t -> nus事件
//
// return : none
static void nus_data_handler(ble_nus_evt_t * p_evt)
{
if (p_evt->type == BLE_NUS_EVT_RX_DATA)
{
NRF_LOG_DEBUG("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);
}
else if (p_evt->type == BLE_NUS_EVT_TX_RDY)
{
NRF_LOG_DEBUG(" Service is ready to accept new data to be transmitted..");
}
else if(p_evt->type == BLE_NUS_EVT_COMM_STARTED)
{
NRF_LOG_DEBUG("NUS Notification Enable.");
app_timer_start(m_timer_nus, APP_TIMER_TICKS(1000), NULL);
}
else if (p_evt->type == BLE_NUS_EVT_COMM_STOPPED)
{
NRF_LOG_DEBUG("NUS Notification Disable.");
}
}
</syntaxhighlight>接下来我们同样看一下我们的定时器任务,我们初始化了一个周期的定时器任务,这个定时器任务在上方BLE_NUS_EVT_COMM_STARTED事件中被设置为1s周期。
 
也就是每过1s都会进入一次nus_timeout_handler()函数,在这个函数中,我们调用ble_nus_data_send()函数,向主机Notify数据。<syntaxhighlight lang="c" line="1" start="343">
//******************************************************************
// fn : nus_timeout_handler
//
// brief : NUS定时器超时任务
//
// param : p_event -> 指向数据库发现事件的指针
//
// return : none
static void nus_timeout_handler(void * p_context)
{
uint16_t len = 3;
ble_nus_data_send(&m_nus, "BBB", &len, m_conn_handle);
}
 
//******************************************************************
// fn : timers_init
//
// brief : 初始化定时器功能
//
// param : none
//
// return : none
static void timers_init(void)
{
ret_code_t err_code = app_timer_init();
APP_ERROR_CHECK(err_code);
err_code = app_timer_create(&m_timer_nus,APP_TIMER_MODE_REPEATED,nus_timeout_handler);
APP_ERROR_CHECK(err_code);
}
</syntaxhighlight>
==== 实验总结 ====
这一章的学习,我们是建立在已经获取了NUS服务的基础上进行的,所以掌握的要点也比较少。
 
1、主机如何接收和Write数据
 
2、从机如何接收和Notify数据
510
个编辑