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的写就是了

全部完成,最后编译前还需要修改一些东西,IAR的配置,加上HAL_UART=TRUE还有在低功耗POWER_SAVING前加个x,也就是宏定义的是xPOWER_SAVING,而不是POWER_SAVING,也就不会进去低功耗,你前面加个a,abcd,123都随意。

最后,编译,下载,手机下个fastBLE调试吧

 然后主机的程序,稍等

猜你喜欢

转载自www.cnblogs.com/-zhj-blog/p/9238162.html