CC2541藍牙BLE4.0主從透傳工程


.前言

  小弟初來乍到,這是小弟的第一篇博客,暫時還在上學,沒有什么工作經驗,本篇博客主要記錄我在這幾天學習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調試吧

 然后主機的程序,稍等


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM