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

歡迎訪問 生活随笔!

生活随笔

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

BLE-NRF51822教程11-手机动态修改设备名

發(fā)布時(shí)間:2025/3/21 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BLE-NRF51822教程11-手机动态修改设备名 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

該教程講解如何實(shí)現(xiàn)用手機(jī)來動(dòng)態(tài)修改設(shè)備名,達(dá)到手機(jī)連接設(shè)備后修改設(shè)備名稱,然后斷開連接再掃描能夠看到新的設(shè)備名。

?

教程基于sdk9.0?下的uartdemo,如下目錄中xxx\Keil_v5\ARM\Pack\NordicSemiconductor\nRF_Examples\9.0.0\ble_peripheral\ble_app_uart

?

Nordic的協(xié)議棧實(shí)現(xiàn)中默認(rèn)都會(huì)有一個(gè)?Generic Access服務(wù)和Generic Attribute服務(wù)(有的BLE app可能顯示不了名字,只顯示這兩個(gè)服務(wù)的UUID,分別是0x1800和0x1801)。

即一個(gè)工程中即使沒有定義任何服務(wù),燒寫到板子上后,手機(jī)連接上也能看到這兩個(gè)服務(wù)。

?

我們動(dòng)態(tài)修改設(shè)備名就是利用了第一個(gè)服務(wù)Generic Access。

該服務(wù)為通用屬性規(guī)范服務(wù),改服務(wù)為設(shè)備提供了一種確定信息的方式,包括設(shè)備自身的名稱,外觀特性,首先連接參數(shù)等。

使用其中的 設(shè)備名屬性,就能實(shí)現(xiàn)我們需要的動(dòng)態(tài)修改設(shè)備名。

實(shí)現(xiàn)方式就是??手機(jī)連接上設(shè)備后訪問這個(gè)服務(wù)下的設(shè)備名屬性,然后通過這個(gè)屬性寫新的名字,設(shè)備這邊判斷手機(jī)發(fā)送過來的寫是不是對Generic Access服務(wù)下的 設(shè)備名 屬性的寫操作。如果是就保存名字到flash中。并且更新設(shè)備名,這樣當(dāng)設(shè)備重啟或者斷開連接后 手機(jī)這邊再掃描就能看到新的設(shè)備名字了。

?

PS:當(dāng)然你也可以專門建立一個(gè)服務(wù)然后添加一個(gè)特征值用來當(dāng)做修改名字用。接收手機(jī)發(fā)送過來的新名字然后存儲(chǔ)修改。 不過既然默認(rèn)存在的Generic Access服務(wù)中已經(jīng)有了設(shè)備名屬性,這里就直接用,不再去專門創(chuàng)建服務(wù)

?

?

因?yàn)樯婕暗絝lash的存儲(chǔ)首先 添加flash相關(guān)的處理(關(guān)于flash的操作看前面的教程 如何在協(xié)議棧中使用flash)

?

//添加?sys_evt事件處理

static void sys_evt_dispatch(uint32_t sys_evt)

{

??? pstorage_sys_event_handler(sys_evt);

}

?

//協(xié)議棧初始化中注冊上面的派發(fā)函數(shù)

static void ble_stack_init(void)

{

??? uint32_t err_code;

???

??? // Initialize SoftDevice.

??? SOFTDEVICE_HANDLER_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, NULL);

??? ………………

??? ………………

??? ………………

??? // Subscribe for BLE events.

??? err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);

??? APP_ERROR_CHECK(err_code);

???

?? //添加?sys_evt事件處理函數(shù) 注冊。?flash需要用到

?? err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);

??? APP_ERROR_CHECK(err_code);

}

?

?

首先初始化flash,并且定義自己的flash操作完成后的回調(diào)函數(shù),在main.c文件的最上面添加如下代碼

?

//第一個(gè)字節(jié)存放的是標(biāo)識(shí)符表示?flash中的數(shù)據(jù)是否是有效的?name

//device_name[0]=0xAA 表示是有效name,device_name[1]表示name的長度

?

#define NAME_SIZE 32

uint8_t device_name[NAME_SIZE];

pstorage_handle_t my_name_addr; //記錄name存放的flash地址

?

?

//flash操作完成后的回調(diào)函數(shù)。 并沒有做什么有用的事,但是注冊flash塊//的時(shí)候需要有回調(diào)函數(shù)所以這里需要定義

static void my_cb(pstorage_handle_t? * handle,

?????????????????????????????? uint8_t????????????? op_code,

?????????????????????????????? uint32_t???????????? result,

?????????????????????????????? uint8_t??????????? * p_data,

?????????????????????????????? uint32_t???????????? data_len)

{

??? switch(op_code)

??? {??????

?????? case PSTORAGE_UPDATE_OP_CODE:

?????????? if (result == NRF_SUCCESS)

?????????? {

?????????? ?? printf("update end");?

?????????? }

?????????? break;

??? }

}

?

?

//定義flash初始化函數(shù)

void my_flash_init(void){

??? uint32_t err_code;

??? pstorage_module_param_t param;

//申請一個(gè)塊 用來存放name

??? param.block_count = 1;

??? param.block_size = NAME_SIZE;

??? param.cb = my_cb;

???

??? err_code = pstorage_init();

??? printf("init err_code:%d\r\n",err_code);

??? err_code = pstorage_register(&param, &my_name_addr);

??? printf("register err_code:%d\r\n",err_code);

??? //加載flash內(nèi)容。后面會(huì)判斷name是否有效,如果有效就會(huì)用改name

??? //否則使用默認(rèn)name

??? err_code = pstorage_load(device_name, &my_name_addr, NAME_SIZE, 0);

??? printf("load err_code:%d\r\n",err_code);

?

}

?

?

然后將該flash初始化函數(shù)放到main函數(shù)中

?

int main(void)

{

??? uint32_t err_code;

??? bool erase_bonds;

??? uint8_t? start_string[] = START_STRING;

???

??? // Initialize.

??? APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_MAX_TIMERS, APP_TIMER_OP_QUEUE_SIZE, false);

????uart_init();

???

?? //添加flash初始化,因?yàn)橛玫搅舜蛴⌒枰诺?/span>uart_init函數(shù)之后

?? //因?yàn)?/span>gap_params_init函數(shù)中會(huì)判斷使用flash中的名字還是默認(rèn)名字

?? //所以需要放到該函數(shù)之前

???my_flash_init();

???

??? buttons_leds_init(&erase_bonds);

??? ble_stack_init();

????gap_params_init();

??? services_init();

? ??advertising_init();

??? conn_params_init();

?? ?printf("%s\r\n",start_string);

??? err_code = ble_advertising_start(BLE_ADV_MODE_FAST);

??? APP_ERROR_CHECK(err_code);

??? // Enter main loop.

??? for (;;)

??? {

??????? power_manage();

??? }

}

?


然后修改?main函數(shù)中調(diào)用的gap_params_init函數(shù)。該函數(shù)中判斷my_flash_init?函數(shù)中加載的flash內(nèi)容是否是有效name,是就使用,不是就用默認(rèn)name.

?

static void gap_params_init(void)

{

??? uint32_t??????????????? err_code;

??? ble_gap_conn_params_t?? gap_conn_params;

??? ble_gap_conn_sec_mode_t sec_mode;

??? BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);

???

?

??? //flash數(shù)據(jù)有效則使用flash中的名字

??? if ( device_name[0] == 0xaa ){

?????? //有效 使用新名字

?????? //device_name[1]為名字長度

?????? printf("update name\r\n");

?????? err_code = sd_ble_gap_device_name_set(&sec_mode,

?????????? ?????????????????????????(const uint8_t *) device_name+2,

???????? ??????????????????????????????device_name[1]);

???

??? }else{

?????? printf("default name\r\n");

?????? err_code = sd_ble_gap_device_name_set(&sec_mode,

????????????? ?????????????????????????(const uint8_t *) DEVICE_NAME,

????????????????????????????????????????? strlen(DEVICE_NAME));

??? }

?????????????????????????????????? ?

??? APP_ERROR_CHECK(err_code);

?? ? memset(&gap_conn_params, 0, sizeof(gap_conn_params));
? ? gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
? ? gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;


?? ……………

??? …………

}

?

?

關(guān)于flash中的內(nèi)容添加完了,然后是處理手機(jī)發(fā)送過來的新名字。

定義事件處理函數(shù)

?

static void name_change(ble_evt_t * p_ble_evt)

{

??? ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;

???

??? //通過UUID來判斷事件是不是寫Generic Access服務(wù)中的名字屬性

??? if((p_evt_write->context.char_uuid.uuid == BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME) &&?
?????????????????????(p_ble_evt->header.evt_id == BLE_GATTS_EVT_WRITE))

??? {

?????? printf("name change \r\n");

?????? device_name[0] = 0xaa;

?????? device_name[1] = p_evt_write->len;

?????? memcpy(device_name+2, p_evt_write->data, p_evt_write->len);

?????? pstorage_update(&my_name_addr, device_name, NAME_SIZE, 0 );

?

??? }

?

}

?

?


然后再將這個(gè)事件處理函數(shù)加到 事件派發(fā)函數(shù)ble_evt_dispatch中

static void ble_evt_dispatch(ble_evt_t * p_ble_evt)

{

????name_change(p_ble_evt);

???

??? ble_conn_params_on_ble_evt(p_ble_evt);

??? ble_nus_on_ble_evt(&m_nus, p_ble_evt);

??? on_ble_evt(p_ble_evt);

??? ble_advertising_on_ble_evt(p_ble_evt);

??? bsp_btn_ble_on_ble_evt(p_ble_evt);?

}

?

到這里基本實(shí)現(xiàn)了 手機(jī)修改設(shè)備名字。不過連接上修改名字后斷開然后點(diǎn)擊掃描發(fā)現(xiàn)名字并未更新,需要復(fù)位一下硬件設(shè)備才能看到設(shè)備名字變了。

?

想在不復(fù)位的情況下,斷開連接然后點(diǎn)掃描就能看到新的設(shè)備名還需要在斷開連接后重新初始化 廣播數(shù)據(jù)。

?

?

繼續(xù)修改事件派發(fā)函數(shù)ble_evt_dispatch

?

//應(yīng)為該函數(shù)是在下面定義的,這里使用到,所以要聲明一下

void advertising_init(void);

?

static void ble_evt_dispatch(ble_evt_t * p_ble_evt)

{

????name_change(p_ble_evt);

???

????//添加代碼,在斷開連接事件后初始化廣播數(shù)據(jù)

?? if ( p_ble_evt->header.evt_id == BLE_GAP_EVT_DISCONNECTED ){

????? advertising_init();

?? }

??

??? ble_conn_params_on_ble_evt(p_ble_evt);

??? ble_nus_on_ble_evt(&m_nus, p_ble_evt);

??? on_ble_evt(p_ble_evt);

??? ble_advertising_on_ble_evt(p_ble_evt);

??? bsp_btn_ble_on_ble_evt(p_ble_evt);

? ?

}

?

?

現(xiàn)在編譯后燒寫到板子,手機(jī)連接后進(jìn)入?Generic Access服務(wù)(有的可能只看到UUID 0x1800),然后點(diǎn)擊device name(UUID?0x2A00)屬性,寫新名字。

然后斷開連接。 點(diǎn)擊掃描按鍵就可以看到新的設(shè)備名字了

總結(jié)

以上是生活随笔為你收集整理的BLE-NRF51822教程11-手机动态修改设备名的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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