抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

事件

事件是一种任务间通信的技术,和信号量不同,可以实现一对多,多对多的通信,但是不涉及数据的传输。

  1. configUSE_16_BIT_TICKS​ 开启后,uxEventBits​为16位,8位存储事件组;未开启时,uxEventBits​为32位,24位存储事件组。
  2. 事件只与任务相关联,事件之间彼此独立。
  3. 事件只同于同步,不涉及数据传输。
  4. 事件无队列消息性质,多次向同一任务发送事件,若未被读取,则视为一次事件。
  5. 支持事件等待超时机制。

事件运行机制

1
2
3
4
5
//中断事件组
#define configUSE_TIMERS 0
#define INCLUDE_xTimerPendFunctionCall 0
//软件定时器优先级
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1)
  1. 事件接收成功后,需要使用xClearOnExit()​来清除事件类型,否则不会清除已接收的事件,需要手动显示清除。
  2. 24位存储事件中,1​表示事件已发生,0​表示事件未发生

  1. 任务唤醒遵循事件的或与逻辑

事件常见函数

  1. xEventGroupCreate()​创建事件组,返回一个句柄
  2. xEventGroupDelete()​删除事件
  3. xEventGroupSetBits()​置位事件组中指定的位,置位后,阻塞该位的任务会被解锁。
  4. xEventGroupSetBitsFromISR()​中断置位事件组,需要开启configUSE_TIMERS 1​和INCLUDE_xTimerPendFunctionCall 1​宏定义
  5. xEventGroupWaitBits()​等待事件,获取事件标志位。
  6. xEventGroupClearBits()​清除事件组置位
  7. xEventGroupClearBitsFromISR()​中断清除事件组置位

创建事件

创建2个Btn​任务控制LED​任务,当只按下BTN1​时,不亮,接着按下BTN2​后,亮。此时相当于标志位变得和设定相同。

开启宏定义

1
2
3
4
5
//中断事件组
#define configUSE_TIMERS 0
#define INCLUDE_xTimerPendFunctionCall 0
//软件定时器优先级
#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-1)

事件句柄,创建一个引用,并不是创建一个真实的事件

1
2
3
4
5
//事件句柄
static EventGroupHandle_t Event_Handle=NULL;

#define KEY1_EVENT (0x01 << 0) //设置掩码的位0
#define KEY2_EVENT (0x01 << 1) //设置掩码的位1

创建一个真实的事件

1
2
//创建事件句柄
Event_Handle = xEventGroupCreate();

LED任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
static void LED0_Event_Task(void *paramter)
{
EventBits_t r_event;
while (1)
{
r_event = xEventGroupWaitBits(
Event_Handle, //事件句柄
KEY1_EVENT | KEY2_EVENT, //接收感兴趣事件
pdTRUE, //退出时清除事件位
pdTRUE, //满足感兴趣的所有事件
portMAX_DELAY); //超时一直等待

if (r_event & (KEY1_EVENT | KEY2_EVENT) == (KEY1_EVENT | KEY2_EVENT))
{
printf("KEY1和KEY2都按下\r\n");
LED0_Turn();
}else
{
printf("事件错误\r\n");
}
}
}

Key任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
static void KEY_Event_Task(void *paramter)
{
while (1)
{
if(Key_BTN(BTN1)==KEY_ON)
{
printf("KEY1按下\r\n");
xEventGroupSetBits(Event_Handle,KEY1_EVENT);
}
if (Key_BTN(BTN2)==KEY_ON)
{
printf("KEY2按下\r\n");
xEventGroupSetBits(Event_Handle,KEY2_EVENT);
}
vTaskDelay(20);
}

}

当BTN1和BTN2都按下后,才会翻转信号