【CC2640R2F】香瓜CC2640R2F之自定义周期事件



本文最后修改时间:2017年10月16日 03:45

 

一、本节简介

本节以simple_peripheral工程为例,介绍如何使用定时器启动周期事件。


二、实验平台

1)CC2640R2F平台

①协议栈版本:CC2640R2 SDK v1.40.00.45

②编译软件:CCS7.3.0.00019

③硬件平台:香瓜CC2640R2F开发板

④仿真器:香瓜XDS100V3下载器


三、版权声明

1)作者:甜甜的大香瓜

2)声明:喝水不忘挖井人,转载请注明出处。

3)纠错/业务合作:[email protected]

4)香瓜BLE之CC2640R2F群:557278427

5)本文出处:原创连载资料《简单粗暴学蓝牙5》

6)完整开源资料下载地址(电脑端打开):

https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

7)香瓜CC2640R2F开发板购买链接:

https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4023-16963296339.8.21bfc58419sWKt&id=558653143169

8)香瓜XDS100V3下载器购买链接:

https://item.taobao.com/item.htm?spm=a230r.1.14.1.1d150040zvJBco&id=558356989143&ns=1&abbucket=6#detail


四、实验前提

1、在进行本文步骤前,请先阅读以下章节:

1)《简单粗暴学蓝牙5》的“第一章至第四章”章节​。

 

2、在进行本文步骤前,请先实现以下章节:

1)《简单粗暴学蓝牙5》的“第三章 软件的安装及使用”章节。

2) 《简单粗暴学蓝牙5》的《香瓜CC2640R2F之LED》:http://blog.csdn.net/feilusia/article/details/78087346

3) 《简单粗暴学蓝牙5》的《香瓜CC2640R2F之自定义按键》:http://blog.csdn.net/feilusia/article/details/78239447


五、基础知识

1、为什么要用定时器来启动事件?

答:由于蓝牙通信的实时性要求较高,如果在协议栈中使用了“for、delay”等延时代码,则很容易出现“无广播、蓝牙连接断开”等异常现象。

因此工程师在开发过程中禁止使用延时代码。

取而代之的是用协议栈提供的定时器,如:点亮1个led后,启动2S的定时器,在2S后执行熄灭该led的定时器处理函数。


2、什么是任务(TASK)、事件(EVENT)、消息(MESSAGE)?

答:

举个简单的例子:

如果协议栈是一栋楼,则任务是楼层,事件是房间,消息是包裹。香瓜在顶层的7楼8号房间等待接收包裹。

而快递员携一堆包裹一楼开始派送,一层一层往上,最终到7楼,再一间一间地判断是否为8号房间,是8号房间则将包裹给香瓜。

以上例子要注意几点:

1)越底层的任务优先级越高。

2)每个事件可占有的时间是有限的,如果用了延时代码导致事件时间过长,协议栈的正常运作将会被破坏,会造成“无广播、蓝牙连接断开”等异常现象。

3)任务与任务之间、事件与事件之间,都是通过消息进行传递信息。

4)通常一个工程中我们不需要增减任务,只需要增减事件(如增加led闪烁时间、增加周期性广播事件)。


六、硬件原理

暂无


七、实验步骤

1、定义周期事件

1)定义周期事件的宏(simple_peripheral.c中)

//GUA
#define SBP_GUA_PERIODIC_EVT                  Event_Id_02           //香瓜周期事件
#define SBP_GUA_ALL_EVENTS                    SBP_GUA_PERIODIC_EVT  //所有事件的集合
//GUA
注意:

①由于协议栈本身使用了Event_Id_00和Event_Id_01,则香瓜从Event_Id_02开始使用。

②如果有多个事件,需要通过“|”写到SBP_GUA_ALL_EVENTS事件中,如“SBP_GUA_PERIODIC_EVT | SBP_GUA_PERIODIC_2_EVT”。


2)添加周期事件的处理(simple_peripheral.c的SimpleBLEPeripheral_taskFxn中)

//GUA
      //香瓜周期事件
      if (events & SBP_GUA_PERIODIC_EVT)
      {
        //再次启动定时器
        //Util_startClock(&GUA_periodicClock);

        //香瓜周期处理函数
        GUA_performPeriodicTask();
      }
//GUA
紧接着其他事件之后即可。

定时器默认只执行一次,如果希望重复进入定时器事件,则可把上方代码中香瓜注释的语句利用起来。

3)添加周期事件的执行权限(simple_peripheral.c的SimpleBLEPeripheral_taskFxn中)

    events = Event_pend(syncEvent, Event_Id_NONE, SBP_ALL_EVENTS,
                        ICALL_TIMEOUT_FOREVER);
替换成

    //GUA
    events = Event_pend(syncEvent, Event_Id_NONE, SBP_ALL_EVENTS | SBP_GUA_ALL_EVENTS,
                        ICALL_TIMEOUT_FOREVER);
    //GUA
如果没有这一步,香瓜周期事件将被过滤掉而无法执行。

2、定义及声明周期事件的处理函数

1)定义周期事件的处理函数(simple_peripheral.c中)

//GUA
//**********************************************************************
//name:         GUA_performPeriodicTask
//introduce:    香瓜周期事件的处理函数
//parameter:    none
//return:       none
//author:       甜甜的大香瓜
//email:        [email protected]
//QQ group:     香瓜BLE之CC2640R2F(557278427)
//shop:
//https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i
//changetime:   2017.10.15
//**********************************************************************
static void GUA_performPeriodicTask(void)
{
    GUA_Led_Set(GUA_LED_NO_ALL, GUA_LED_MODE_OFF);  //LED全灭
}
//GUA
这里将LED灯全部熄灭。

2)声明周期事件的处理函数(simple_peripheral.c中)

//GUA
static void GUA_performPeriodicTask(void);
//GUA

3、初始化定时器 

1)定义定时器结构体数据(simple_peripheral.c中)

//GUA
static Clock_Struct GUA_periodicClock;
//GUA

2)设置定时时间(simple_peripheral.c中)

//GUA
#define SBP_GUA_PERIODIC_EVT_PERIOD           100                   //香瓜定时时间
//GUA
这里设置为100ms。


3)初始化定时事件(simple_peripheral.c的SimpleBLEPeripheral_init函数末尾中)

//GUA
    //初始化定时器
    Util_constructClock(&GUA_periodicClock, SimpleBLEPeripheral_clockHandler,
                        SBP_GUA_PERIODIC_EVT_PERIOD, 0, false, SBP_GUA_PERIODIC_EVT);
//GUA
注意:这里仅仅是对定时器初始化函数,还需要一个“Util_startClock”函数(启动定时器函数)。必须两个都有,定时器才能被启动起来。

本文中的“Util_startClock”函数在下文的按键处理函数中被调用。


4、启动定时器(替换simple_peripheral.c的GUA_HandleKeys函数)

//GUA
//**********************************************************************
//name:         GUA_HandleKeys
//introduce:    应用层按键处理函数
//parameter:    GUA_Keys:键值
//return:       none
//author:       甜甜的大香瓜
//email:        [email protected]
//QQ group:     香瓜BLE之CC2640R2F(557278427)
//shop:
//https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i
//changetime:   2017.10.08
//**********************************************************************
static void GUA_HandleKeys(uint8 GUA_Keys)
{
  //UP按键
  if(GUA_Keys & GUA_KEY_UP_VALUE)
  {
    //LED
    GUA_Led_Set(GUA_LED_NO_1, GUA_LED_MODE_ON);     //LED1亮

    //启动定时器
    Util_startClock(&GUA_periodicClock);
  }

  //DOWN按键
  if(GUA_Keys & GUA_KEY_DOWN_VALUE)
  {
    //LED
    GUA_Led_Set(GUA_LED_NO_2, GUA_LED_MODE_ON);     //LED2亮

    //启动定时器
    Util_startClock(&GUA_periodicClock);
  }

  //LEFT按键
  if(GUA_Keys & GUA_KEY_LEFT_VALUE)
  {
    //LED
    GUA_Led_Set(GUA_LED_NO_3, GUA_LED_MODE_ON);     //LED3亮

    //启动定时器
    Util_startClock(&GUA_periodicClock);
  }

  //RIGHT按键
  if(GUA_Keys & GUA_KEY_RIGHT_VALUE)
  {
    //LED
    GUA_Led_Set(GUA_LED_NO_4, GUA_LED_MODE_ON);     //LED4亮

    //启动定时器
    Util_startClock(&GUA_periodicClock);
  }

  //SELECT按键
  if(GUA_Keys & GUA_KEY_SELECT_VALUE)
  {
    //LED
    GUA_Led_Set(GUA_LED_NO_ALL, GUA_LED_MODE_ON);   //LED全亮

    //启动定时器
    Util_startClock(&GUA_periodicClock);
  }
}
//GUA
5个按键都可以点亮对应LED、启动一次定时器事件。

八、注意事项

暂无


九、实验结果

仿真并全速运行,分别按下5个按键,现象分别为LED1闪烁一次、LED2闪烁一次、LED3闪烁一次、LED4闪烁一次、所有LED闪烁一次。

也就是按键将对应LED点亮后,启动了100ms定时器事件熄灭所有LED。

因此,实验成功。





你可能感兴趣的:(BLE-CC2640R2F)