BLE NRF51822教程15 BLE位址

2021-09-12 17:34:28 字數 3497 閱讀 3805

51822的 ble的裝置位址 可以通過如下函式函式來獲得

位址的設定可以呼叫如下函式設定。

官方的demo工程中,都是沒有主動呼叫過 sd_ble_gap_address_set函式來設定裝置位址的。所以 demo工程中使用的都是預設位址。

這個預設位址就是 晶元出廠是設定的,出廠時燒寫在ficr暫存器中的。

所以藍芽晶元啟動後,如果你沒有主動呼叫 sd_ble_gap_address_set函式來設定位址的話, 協議棧就會使用 ficr 中的暫存器deviceaddr 中的值來設定 ble位址。但是並不是直接用,官方工程預設都是使用靜態隨機位址,所以位址的最高兩位必須要是 1 1,所以協議棧會使用該暫存器中的位址,但是會將最高兩bit的值都設定為1.

例如: 讀取出來的

deviceaddr[0] = 0xd104b111

deviceaddr[1] = 0x691c89cf

根據手冊說明

所以裝置位址為 89 cf d1 04 b1 11

有官方demo預設使用靜態隨機位址,所以位址的最高 兩bit需要為1.

所以協議棧將89 改為了c9

也就是最終的 ble位址為c9 cf d1 04 b1 11

將裝置隨便燒錄乙個跑協議棧的程式,對比發現 其位址的設定就是和上面是一樣的。

有興趣的可以寫個裸機程式 自己讀一下這個暫存器裡的值,在和ble的廣播位址比較下看是不是區別僅僅是最高兩bit改為了1

明白了協議棧如何使用預設ble位址後,再來看如果需要自己設定一些特定的藍芽位址應該怎麼使用sd_ble_gap_address_set函式來設定自己的ble位址。

首先需要介紹些 ble各種裝置位址的區別。

公共位址和隨機位址。

而隨機位址細分又有 靜態隨機位址和隱私位址(private address)

如圖所示:

有那麼多型別的位址,那麼如何區分各種位址型別的呢。

廣播通道pdu資料前面有2位元組的頭 格式如下

其中的txadd表示傳送方的位址型別 (0為public,1為random)

rxadd表示接收方的位址型別。

ps:這兩個域並不是一直都有效的。比如對於普通廣播來說,只有txadd的指示是有效的,表示廣播傳送者的第一型別。  而對於定向廣播來說。txadd 和rxadd都是有效的,txadd表示廣播傳送者的位址型別,rxadd表示廣播接受者的位址型別。

所以 對於是 public型別位址還是random型別位址,直接通過 廣播通道pdu中的的 資料頭 中的 txadd或者rxadd來判斷就可以了。

但是這裡有個問題,只是區分出了 random位址後,又怎麼知道是靜態隨機位址,還是可解析的隱私位址,或者不可解析的隱私位址呢。

這就要了解 各種位址型別的格式。

public位址的格式比較簡單,高24位是公司標示,低24位公司內部自己賦值。

靜態隨機位址的格式如下圖所示,需要滿足

1:最高2位為1

2:隨機部分不能全0或者全1

另外對於靜態隨機位址,位址的設定是在裝置上電初始化時進行的,一旦設定後本次執行過程中 自己的靜態隨機位址都不能再改變,除非重新上電。

1:最高2位為0

2:隨機部分不能為全1或全0

1:最高位0次高位為1

2:隨機部分不能為全0或全1

可解析的隨機位址的生成需要使用到 irk, 位址由兩部分組成,

hansh和prand(包含最高固定2位和22位隨機部分)。

其中  hash = ah(irk, prand)   ah就是產生隨機位址的函式。

既然是可解析位址,那麼如何解析呢? 解析的過程也是一樣的。接收方可能存在多個irk,接收方收到乙個位址型別是 隨機位址,並且最高2位是01那麼,接收方就會 用他有的irk對接收到的位址的高24位做ah(irk, prand)運算,得到localhash,然後將localhash和接收到位址的低24位的hash對比,如果相同則認為這個位址 和 該irk是相關連的。

如果不同則繼續 用下乙個irk做上面的過程,知道找到乙個關聯的irk或者乙個沒找到。

如果是11就是靜態隨機位址,位址型別確定

如果是00表示為不可解析隱私位址,型別確定

如果是01表示為可解析的私有位址,並執行上面說過的ah方法,找到與該可   解析位址相關的irk(可能找不到)。

最後 介紹一下 51822中怎麼設定各種型別的位址。

uint32_t sd_ble_gap_address_set  (uint8_t addr_cycle_mode, const ble_gap_addr_t * p_addr )

addr_cycle_mode 引數為:ble_gap_addr_cycle_mode_auto:

該模式下,會忽略第二個位址引數p_addr 中給的位址addr。協議棧內部會自動週期性根據 p_addr中addr_type指定的位址型別來 生成可解析的或者不可解析的位址。

addr_cycle_mode 引數為:ble_gap_addr_cycle_mode_none:

該模式下,可以使用public位址和自己設定的 static random位址。

如果第二個引數p_addr中的addr_type為staic random型別,則addr中存放的位址的最高2位必須為1,不然這個位址會被認為無效並自動替換,51822會自動替換為藍芽mac位址。(跟沒有呼叫sd_ble_gap_address_set函式的效果是一樣的,看教程最上面的說明)

static random address 只有在每次 重新上電後才可改變。

可解析和不可解析的位址可在正常執行過程中週期性改變

其他使用該函式需要注意的地方看 sdk中該函式的說明就行了

BLE NRF51822教程 RSSI獲取

當手機和裝置連線上後,裝置端可以通過獲取rssi來 在一定程度上判斷手機離裝置的相對距離的遠近。獲取函式很簡單直接呼叫sd ble gap rssi get介面函式就行了,傳入連線控制代碼和buff就能獲取到 最近一次連線事件中的 接收訊號強度。呼叫該函式之前需要先呼叫sd ble gap rssi...

BLE NRF51822教程8 動態廣播

本講接收如何實現動態廣播。教程基於 9.0 sdk中的 uart例子。實現動態廣播的方法是 廣播 停止廣播 修改引數 重啟廣播 所以我們通過乙個定時器來週期性的 關閉廣播然後再修改廣播資料之後再開啟廣播。sdk 9.0中的廣播搞了好幾個模式,做的有點麻煩,所以我對他做了比較大的改動。首先 在main...

BLE NRF51822教程8 動態廣播

ble nrf51822教程8 動態廣播 2015 12 29 17 38 35 分類 嵌入式 本講接收如何實現動態廣播。教程基於 9.0 sdk中的 uart例子。實現動態廣播的方法是 廣播 停止廣播 修改引數 重啟廣播 所以我們通過乙個定時器來週期性的 關閉廣播然後再修改廣播資料之後再開啟廣播。...