日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

BLE-NRF51822教程6-创建一个自己的服务

發(fā)布時(shí)間:2025/3/21 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BLE-NRF51822教程6-创建一个自己的服务 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
首先打開 sdk 下的工程模板 在以下路徑中
XXXX\Keil_v5\ARM\Pack\NordicSemiconductor\nRF_Examples\9.0.0\ble_peripheral\ble_app_template\pca10028\s110\arm5打開工程后,可以發(fā)現(xiàn)該模板的框架和一般工程例子基本是一樣的。區(qū)別就是有一些函數(shù)內(nèi)部并未實(shí)現(xiàn),比如services_init() 。
Main 函數(shù)的整體初始化流程都是通用。

[cpp]?view plain?copy ? ?
  • int?main(void)??
  • {??
  • ????uint32_t?err_code;??
  • ????bool?erase_bonds;??
  • ????//?Initialize.??
  • ????timers_init();??
  • ????buttons_leds_init(&erase_bonds);??
  • ????ble_stack_init();??
  • ????device_manager_init(erase_bonds);??
  • ????gap_params_init();??
  • ????advertising_init();??
  • ????services_i?nit();??
  • ????conn_params_init();??
  • ????//?Start?execution.??
  • ????application_timers_start();??
  • ????err_code?=?ble_advertising_start(BLE_ADV_MODE_FAST);??
  • ????APP_ERROR_CHECK(err_code);??
  • ????//?Enter?main?loop.??
  • ????for?(;;)??
  • ????{??
  • ????????power_manage();??
  • ????}??
  • }??

  • 這一講我們來在該模板上創(chuàng)建個(gè)使用最少資源的服務(wù)。
    我們只是創(chuàng)建一個(gè)服務(wù)這個(gè)服務(wù)具有可寫和通知的特性。從而實(shí)現(xiàn)手機(jī)發(fā)數(shù) 這個(gè)服務(wù)具有可寫和通知的特性。從而實(shí)現(xiàn)手機(jī)發(fā)數(shù) 據(jù)給設(shè)備,然后對(duì)數(shù)做 加 1操作 后再返回給手機(jī)。所以我們沒有使用:定時(shí)器、按鍵定時(shí)器、按鍵led、綁定功能、鏈接參數(shù)、更新操作、所以上面的main函數(shù)我們精簡成如下:

    [cpp]?view plain?copy ? ?
  • int?main(void)??
  • {??
  • ????uint32_t?err_code;??
  • ????bool?erase_bonds;??
  • ????ble_stack_init();??
  • ????gap_params_?init();??
  • ????advertising_init();??
  • ????services_init();??
  • ????err_code?=?ble_advertising_start(BLE_ADV_MODE_FAST);??
  • ????APP_ERROR_CHECK(err_code);??
  • ????//?Enter?main?loop.??
  • ????for?(;;)??
  • ????{??
  • ????????power_manage();??
  • ????}??
  • }??

  • 這個(gè)時(shí)候編譯工程下載到板子后是可以搜索設(shè)備的。只是連接后并沒有服務(wù),下面我們來創(chuàng)建一個(gè)服務(wù)。 要實(shí)現(xiàn)的就是上面services_init() 函數(shù)。首先我們需要定義一個(gè)自己的服務(wù)結(jié)構(gòu)體來記錄這相關(guān)些信息。直接在 main.c 文件的上面定義如下結(jié)構(gòu)體。
    [cpp]?view plain?copy ? ?
  • typedef?struct?BlkMyServiceTag{??
  • ????uint16_t?conn_handle;??????????????//?連接后用?來記錄下句柄,供續(xù)使連接后用??
  • ????uint16_t?service_handle;???????????//?保存服務(wù)的句柄??
  • ????ble_gatts_char_handles_t?handle;???//?保存特性句柄??
  • }BlkMyService;??

  • 然后定義一個(gè)全局變量
    BlkMyService my_service; // 這個(gè)全局變量保存了我們的服務(wù)相關(guān)信息

    然后實(shí)現(xiàn) service_init() 函數(shù)。
    這里不使用模板工程中?建議的初始化方法,為簡單起見我 們就直接在該函數(shù)里面調(diào)用服務(wù)添加和特征值。

    為方便也是直接就在 main.c 文件中實(shí)現(xiàn)如下函數(shù)
    [cpp]?view plain?copy ? ?
  • void?services_init(void){??
  • ????ble_uuid_t?service_uuid;??
  • ????service_uuid.type?=?BLE_UUID_TYPE_BLE;??
  • ????service_uuid.uuid?=?MY_UUID;??
  • ??
  • ????//?添加服務(wù)??
  • ????sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,&service_uuid,&my_service.service_handle);??
  • ??
  • ????ble_gatts_char_?md_t?char_md;??
  • ????ble_gatts_attr_t?attr_char_value;??
  • ????ble_gatts_attr_md_t?cccd_md;??
  • ????ble_gatts_attr_md_t?attr_md;??
  • ??
  • ????BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);??
  • ????BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);??
  • ??
  • ????cccd_md.vloc???????????=?BLE_GATTS_VLOC_?STACK;??
  • ????char_md.p_cccd_md??????=?&cccd_md;??
  • ????char_md.props.notify???=?1;??
  • ????char_md.props.write????=?1;??
  • ????char_md.p_pf???????????=?NULL;??
  • ????char_md.p_user_desc????=?NULL;??
  • ????char_md.p_sccd_md??????=?NULL;??
  • ????char_md.p_user_desc_md?=?NULL;??
  • ??
  • ????attr_md.rd_auth?=?0;??
  • ????attr_md.wr_auth?=?0;??
  • ????BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);??
  • ????BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);??
  • ????attr_md.vloc?=?BLE_GATTS_VLOC_STACK;??
  • ????attr_md.vlen?=?1;??
  • ??
  • ????ble_uuid_t?val_uuid;??
  • ????val_uuid.type???=?BLE_UUID_TYPE_BLE;??
  • ????val_uuid.uu?id??=?0x5678;??
  • ??
  • ????attr_char_value.p_uuid?????=?&val_uuid;??
  • ????attr_char_value.p_md???????=?&attr_md;??
  • ????attr_char_value.init_len???=?sizeof(uint8_t);??
  • ????attr_char_value.init_offs??=?0;??
  • ????attr_char_value.max_len????=?20;??
  • ?????//?添加特征值。??
  • ????sd_ble_gatts_characteristic_add(my_service.servi?ce_handle,?&char_md,?attr_value,&my_service.handle);??
  • }??
  • ?到這里服務(wù)以及其中的特征值都已經(jīng)創(chuàng)建好了。編譯工程下載后,手機(jī)連接設(shè)備可以看到服務(wù)列表中已經(jīng)有了我們添加的服務(wù)uuid 為0x1234,點(diǎn)擊服務(wù)也可以看到其中的特征值 uuid 為0x5678;服務(wù)創(chuàng)建完后就是與手機(jī)通信了。我們要實(shí)現(xiàn)的是手機(jī)發(fā)送一個(gè)數(shù)據(jù),設(shè)備收到后對(duì)數(shù)據(jù)做加 1 操作后再發(fā)回給手機(jī)。

    手機(jī)發(fā)給設(shè)備的數(shù)據(jù)最終會(huì)被打包成一個(gè)寫事件結(jié)構(gòu)然后交給 app 。
    先實(shí)現(xiàn)對(duì)寫事件的處理。就是將數(shù)據(jù)加一然后在發(fā)送回給手機(jī)。
    當(dāng)然發(fā)送數(shù)據(jù)給手機(jī)之前,我們要知道之前,我們要知道 conn_handle,這在手機(jī)連接的時(shí)候 app 會(huì)收到這個(gè)事件,記錄下句柄就可以了。

    我們針對(duì)寫事件實(shí) 我們實(shí)現(xiàn)如下的數(shù)據(jù)操作和發(fā)送函(為方便都是直接在 main.c 文件中實(shí)現(xiàn) )

    [cpp]?view plain?copy ? ?
  • void?service_write_handle(ble_evt_t?*p_evt){??
  • ????uint16_t?data_len;??
  • ????uint8_t?data;??
  • ????data_len?=?sizeof(uint8_t);??
  • ????data?=?p_ble_evt?->evt.gatts_params.write.data[0];??
  • ????data++;??
  • ????ble_gatts_hvx_params_t?params;??
  • ????hvx_params.handle???=?my_service.char_handle.val?ue_handle;??
  • ????hvx_params.offset???=?0;??
  • ????hvx_params.p_data???=?&data;??
  • ????hvx_params.p_len????=?&data_len;??
  • ????hvx_params.type?????=?BLE_GATT_HVX_NOTIFICATION;??
  • ????sd_ble_gatts_hvx(my_service.conn_handle,&hvx_params);??
  • }??



  • 然后實(shí)現(xiàn)的服務(wù)處理函數(shù)如下
    [cpp]?view plain?copy ? ?
  • void?my_server_handler(ble_evt_t?*p_evt){??
  • ????switch?(p_ble_evt?->header.evt_id)??
  • ????{??
  • ????????case?BLE_GAP_EVT_CONNECTED:??
  • ????????????my_service.conn_handl?=p_ble_evt?->evt.gap_conn_handle;??
  • ????????????break;??
  • ????????case?BLE_GATTS_EVT_WRITE:??
  • ????????????service_write_handle(p_ble_evt);??
  • ????????????break?;??
  • ????????default:??
  • ????????????//?No?implementation?needed.??
  • ????????????break;??
  • ????}??
  • }??
  • 最后我們將這個(gè) 服務(wù)事件處理函數(shù) 添加到事件派發(fā)函數(shù)中
    [cpp]?view plain?copy ? ?
  • static?void?ble_evt_dispatch(t?*?p_evt)??
  • {??
  • ????dm_ble_evt_handler(p_evt);??
  • ????ble_conn_params_on_evt(p_evt);??
  • ????bsp_btn_ble_on_b?le_evt(p_ble_evt);??
  • ????on_ble_evt(p_evt);??
  • ????ble_advertising_on_evt(p_evt);??
  • ????//?添加到這里??
  • ????my_server_handler(p_ble_evt);??
  • }??
  • 編譯工程下載后 ,手機(jī)連接上進(jìn)入服務(wù)的特征值勾選使能 notify 功能, 然后發(fā)送數(shù)據(jù)就可以看到收加 1 的數(shù)據(jù)了

    總結(jié)

    以上是生活随笔為你收集整理的BLE-NRF51822教程6-创建一个自己的服务的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。