.前言
小弟初來乍到,這是小弟的第一篇博客,暫時還在上學,沒有什么工作經驗,本篇博客主要記錄我在這幾天學習BLE協議協議棧的一點心得體會,並用一個主從透傳的實驗來記錄過程,如有錯誤之處,還望各位大佬多多包涵
二.工程環境
- CC2541核心板 * 2
- CC Debugger * 1
- USB轉TTL串口模塊 * 2
- BLE-1.4.2協議棧
- IAR For 8051 10.20.1
- 腦子+核桃仁
三.實驗過程
1.簡介
說簡單點就是,低功耗(號稱一顆紐扣電池用一年,沒量過我也不曉得),然后可以用主機和從機數據傳輸(廢話)。
2.工程說明
本次工程是主從透傳實驗,也就是兩塊CC2541的板子通過USB-TTL連接到PC,PC打開兩個串口助手,且一個串口助手發送的信息可以被另一個串口助手接收到,這就叫串口透傳(大神繞道)。
BLE4.0是TI公司在OSAL這個系統上開發的一款協議棧,已經將底層的一些操作全部封裝成Lib庫,用戶是看不到底層的,我們只需要大致了解以及學會使用就可以了。
本博客不講原理,只講實際。
3.從機協議棧配置
首先要打開一個BLE的例程(當然你得先裝好BLE的協議棧和IAR,IAR的版本不限制,這個自行百度吧),如下圖所示:
沒啥講究,雙擊打開,粗暴點.....
這個工程是從機的工程
如果使用的是高版本的IAR,請打開工程后選擇如下圖所示的最上面的一行,右擊----Option-----General Opyions-----Number of Virtual修改為8,否則會出現編譯錯誤。
首先我們了解一下特征,特征值這些玩意兒
在藍牙BLE中做一個不恰當的比喻,有兩個人,路人甲和路人乙,路人甲前面有n個簍子,比如4個吧,然后路人乙可以拿簍子里的東西或者向簍子里放東西,
但路人甲有規定
第一個簍子只能拿不能放
第二個簍子能拿能放
第三個簍子不能拿只能放
第四個簍子不太一樣,路人甲自己放東西進去后,他會通知路人乙里邊放了什么東西,路人乙只能放,不能主動拿。
以上兩個人,路人乙代表是藍牙通訊中的主機,或者叫客戶端
路人甲代表的是藍牙通訊中的從機,或者叫服務器
以上4個簍子,每個簍子代表一個特征
簍子里的東西代表的就是特征值,也就是每個特征的數據,
路人甲的規定(能拿,能放,能夠通知路人乙有什么東西)就代表了特征的屬性(可寫,可讀,可通知)
所以,一個特征由特征值,屬性等一些東西組成,而一個BLE從機可以有幾個特征
這個不恰當的比喻大致就簡單的描述了一下藍牙BLE通訊的內容。
好,那么我們開始為從機添加一個簍子,也就是一個特征(TI給的協議棧例程里本身就有5個特征值,我們自己再添加一個)
添加數據一般在GATT層,也就是simpleGATTprofile.c文件里增加特征(此文件在IAR左邊的文件樹里的Profile文件夾下)
首先添加特征的UUID和數據的容量,通俗的講就是簍子的編號和簍子最多能放多少東西(不理解的話不要緊,往后慢慢就懂了,先定義了就是),還有我使用的是Visual Studio,看代碼修改代碼方便一點,貼的圖不大一樣,你們用IAR一樣修改,不用管。
接下來,進入到simpleGATTprofile.c,增加UUID的變量,直接復制上邊Characteristic 5 UUID就可以,然后粘貼,改一下就好(方便)
在接下來,我們添加屬性,下圖我們可以看到,
1.我們Char6的屬性,權限是GATT_PROP_NOTIFY | GATT_PROP_WRITE即可通知,可寫(也就是路人乙可以向簍子里放東西,路人甲可以通知路人乙,簍子里有哪些東西)(專業點:主機可以往特征值里寫入數據,不能主動讀取數據,從機可以隨時通知主機,我這個特征的特征值是啥,當然主機要獲得通知,必須打開從機的通知開關,這個下面會講,暫時不管)
2.我們的char6特征的特征值是多少,即簍子里最大能放多少東西
static uint8 simpleProfileChar6[SIMPLEPROFILE_CHAR6_LEN] = { 0 };
也就是說CHAR6這個特征內定義了一個數組,數組長度我們開頭定義了是10,就是說簍子的容量就是10個字節;
3.static gattCharCfg_t *simpleProfileChar6Config,這個比較特殊,只要特征是可通知的,也就是GATT_PROP_NOTIFY ,那么必須要這一個變量,里邊保存了通知開關的狀態,入打開了通知或關閉通知。
4.就是個名字
下面我們把屬性添加進屬性表里,屬性表其實是一個數組,我們在下圖添加了4個數組元素,那么我們就要先把數組的元素個數改一下,我們加了4個,所以改成17+4=21,這四個屬性拷貝上面的,然后復制下來再修改就好了,這里用的GATT_PERMIT別看錯了,這里就不說了,就是把剛剛定義的那些屬性加入到一張表里,就這樣
接下來修改SimpleProfile_SetParameter函數,這個函數的作用是寫入特征值(只有從機有,從機可以隨時讀寫所有特征值)
怎么修改,在case sIMPLEPROFILE_CHAR5這一塊操作下面添加CHAR6的操作,如下圖所示,注釋寫好了。
接下來修改SimpleProfile_GetParameter,這個函數的作用就是從機獲取指定特征的特征值,這個就沒啥好說的,一目了然。
接下來是兩個回調函數,一個讀回調,一個寫回調,也就是說,主機向從機的特征中寫入數據,那么從機會馬上跳進寫入的回調函數,主機讀取從機的特征值,從機就馬上跳進讀回調函數,就是這樣
第一個,讀回調函數:添加一個case是CHAR6的,如下圖紅框所示,直接照搬上面CHAR5的,改個數字,完事兒,置於哪里把數據發送給主機的一會兒說(這個是協議棧自動發給主機的,不需要我們寫什么代碼,只要把數據放到pValue中就行了)
第二個,寫回調函數:在函數中再加一個case,CHAR6的,如下圖,作用就是,主機要寫入從機的特征值,這個函數會被調用,然后由這個函數,將主機發來的數據拷貝到從機本身的特征值中(當然你也可以有騷操作,就不寫入特征值,直接對數據進行騷操作)
好的,到這里,GATT層已經寫完了
下面就是應用層的修改了,例程的應用層源文件是simpleBLEPeripheral.c
一進去就先看SimpleBLEPeripheral_Init,很明顯,初始化函數,是OSAL系統來后,應用層第一個調用的函數,初始化,這里修改的東西不多,就一個串口初始化,和特征值初始化,很簡單,不廢話貼圖
串口初始化:UART_CB是串口接收到數據后的回調函數
我們來看看NPI_InitTransport的實現,這里也需要修改一些東西:
在npi.c文件中,我們需要修改波特率和關閉流控,兩個宏定義改成右邊這樣就好了,波特率115200,流控FALSE
,再看下圖,BLE的串口使用的是DMA+超時(其實我不大確定),所以,判斷一下event&HAL_UART_TIMEOUT看看是不是接收到數據了,如果收到了,使用OSAL提供的發起事件函數啟動發送數據的事件,再往下看事件
這個就是剛剛回調中發送的事件在uint16 SimpleBLEPeripheral_ProcessEvent(uint8 task_id, uint16 events)函數中
大致做了以下幾個事情:①用NPI_RxBufLen讀取串口緩存區內的收到的數據長度,如果有數據就使用NPI_ReadTransport讀取數據到定義的數組內,然后通過SimpleProfile_SetParameter寫入CHAR6的特征值,然后回到上面這個函數的實現那里看看,是不是會將寫入的數用通知發送給主機?這樣子是不是就順理成章了?(當然如果主機沒有打開從機的通知,這里就只是寫入特征值,不會通知特征值給主機)
好了,到這里,我們就實現了,我們PC通過串口寫數據給CC2541從機,然后從機將數據發送給主機的過程
我們還需要在用戶層對主機發來的數據進行一些處理,也就是將主機數據打印到串口,實現透傳
我們已經修改過了GATT層的回調,但GATT層的回調並不是最后的回調函數,調用玩GATT層的回調函數后,會繼續回調應用層的一個回調函數:static void simpleProfileChangeCB( uint8 paramID )
我們應用層的操作都在這里,很明顯TI的例程已經寫了幾個,我們不去管它,粗暴的添加一個CHAR6,做了什么呢?
首先SimpleProfile_GetParameter(SIMPLEPROFILE_CHAR6, Char6Buff);這個GATT層的函數已經在前面實現過了,很明顯獲得CHAR6的特征值,保存到Char6Buff里,
然后NPI_WriteTransport(Char6Buff, strlen(Char6Buff));,把數據發送到串口,完成了,這就好了,主機發過來數據直接傳到串口。
到這兒我們完成了主機發來的CHAR6數據轉發到串口的任務。
最后,我們還需要添加一點點小配置,我不確定不配置會不會有什么影響,但最好還是配置吧,不多
在simpleGATTprofile.c中,初始化通知吧......兩個紅框,模仿char4的寫就是了
還有一個處理主機發來的打開通知的請求,這個case在GATT層的寫回調函數里simpleProfile_WriteAttrCB,收到主機請求打開通知是,調用函數打開通知開關,就好了,這一段是必須的,
全部完成,最后編譯前還需要修改一些東西,IAR的配置,加上HAL_UART=TRUE還有在低功耗POWER_SAVING前加個x,也就是宏定義的是xPOWER_SAVING,而不是POWER_SAVING,也就不會進去低功耗,你前面加個a,abcd,123都隨意。
最后,編譯,下載,手機下個fastBLE調試吧
然后主機的程序,稍等