当前位置:   article > 正文

8.物联网操作系统之事件标志组_cubemx下事件标志组的创建和配置

cubemx下事件标志组的创建和配置

事件标志组定义

FreeRTOS事件标志组介绍

FreeRTOS事件标志组工作原理

一。事件标志组定义

信号量信号量只能实现任务与单个事件或任务间的同步。但是某些任务可能会需要与多个事件或任务进行同步,此时就可以使用事件标志组来解决。事件标志组能够实现某个任务与多个事件或任务间的同步。

 如上图所示:

        事件可以由两个或两个以上来触发运行,所以引入事件标志组定义。

2.FreeRTOS事件标志组介绍

有24个位,中断或者任务运行结束,把为SET为1,当满足条件时,运行Task2. 

3.FreeRTOS事件标志组工作原理

 任务1需要事件3与4同时运行,任务0需要事件3或者4运行,所以当事件3运行后,任务0激活,任务1不激活。当事件4发生后,任务0才激活。

二。实验:事件标志组函数的应用(上节的基础上,递归信号量)

1.功能需求

1、使用事件标志组检测多个按键输入(K3、K4、K5、K6)

2、当检测到任何一个按键按下,串口打印输出按键信息

3、当4路按键都已经按下,触发蜂鸣器报警

2.API

(1)xEventGroupCreate()创建事件标志组#include "event_groups.h"

(2) xEventGroupSetBits()在任务中设置事件标志单位

 (3)xEventGroupSetBitsFromISR()中断设置事件标志组位

 (4)xEventGroupGetBits()在任务中获取事件标志组位值

 (5)xEventGroupGetBitsFromISR()中断中获取事件标志组位的值

(6)xEventGroupWaitBits()等待事件标志组位触发

 (7)xEventGroupSync()此功能通常用于同步多个任务

3.功能需求及具体实现方法

1、使用事件标志组检测多个按键输入(K3、K4、K5、K6)

2、当检测到任何一个按键按下,串口打印输出按键信息

3、当4路按键都已经按下,触发蜂鸣器报警

4.cubemx创建工程

(1)Key3-Key6都设置成中断输出,并把上下沿都设置成可导致中断。NVIC也设置一下。

注意改名

(2)FREERTOS的配置

        上述的API接口xEventGroupSetBitsFromISR()必须要用到守护任务。

        从FREERTOS 原理图可以找到,这个函数,上面的Note中表示,必须要使能configUSE_TIMERS与INCLUDE_xTimerPendFunctionCall。如下两图所示。

设置USE_TIMERS

 设置

 

 5.步骤:

(1)创建事件标志

        根据FREERTOS的参考手册(上面也有API),创建的时候需要头文件#include "event_groups.h",自己创建一个事件标志句柄EventGroupHandle_t KeyEventGroup;如图所示。

  1. #include "event_groups.h"
  2. EventGroupHandle_t KeyEventGroup;

(2)在FREERTOS的init中创建事件标志组 

  1. //创建事件标志组
  2. KeyEventGroup = xEventGroupCreate();
  3. if(KeyEventGroup == NULL){
  4. printf("KeyEventGroup Create Error\r\n");
  5. }

(3)事件标志组用在GPIO.c,声明为外部变量

extern EventGroupHandle_t KeyEventGroup;

(4)在gpio.c的值

  1. #define KEY3_EVENT_BIT (1<<0)
  2. #define KEY4_EVENT_BIT (1<<1)
  3. #define KEY5_EVENT_BIT (1<<2)
  4. #define KEY6_EVENT_BIT (1<<3)

(5)在GPIO.c中的中断回调函数,按下就Set指定位。

  1. //按键3
  2. if(Key3_Pin == GPIO_Pin){
  3. if(HAL_GPIO_ReadPin(Key3_GPIO_Port,Key3_Pin) == GPIO_PIN_RESET){
  4. HAL_Delay(10);
  5. if(HAL_GPIO_ReadPin(Key3_GPIO_Port,Key3_Pin) == GPIO_PIN_RESET){
  6. xEventGroupSetBitsFromISR(KeyEventGroup,KEY3_EVENT_BIT,NULL);
  7. }
  8. }
  9. }
  10. //按键4
  11. if(Key4_Pin == GPIO_Pin){
  12. if(HAL_GPIO_ReadPin(Key4_GPIO_Port,Key4_Pin) == GPIO_PIN_RESET){
  13. HAL_Delay(10);
  14. if(HAL_GPIO_ReadPin(Key4_GPIO_Port,Key4_Pin) == GPIO_PIN_RESET){
  15. xEventGroupSetBitsFromISR(KeyEventGroup,KEY4_EVENT_BIT,NULL);
  16. }
  17. }
  18. }
  19. //按键5
  20. if(Key5_Pin == GPIO_Pin){
  21. if(HAL_GPIO_ReadPin(Key5_GPIO_Port,Key5_Pin) == GPIO_PIN_RESET){
  22. HAL_Delay(10);
  23. if(HAL_GPIO_ReadPin(Key5_GPIO_Port,Key5_Pin) == GPIO_PIN_RESET){
  24. xEventGroupSetBitsFromISR(KeyEventGroup,KEY5_EVENT_BIT,NULL);
  25. }
  26. }
  27. }
  28. //按键6
  29. if(Key6_Pin == GPIO_Pin){
  30. if(HAL_GPIO_ReadPin(Key6_GPIO_Port,Key6_Pin) == GPIO_PIN_RESET){
  31. HAL_Delay(10);
  32. if(HAL_GPIO_ReadPin(Key6_GPIO_Port,Key6_Pin) == GPIO_PIN_RESET){
  33. xEventGroupSetBitsFromISR(KeyEventGroup,KEY6_EVENT_BIT,NULL);
  34. }
  35. }
  36. }

(6)低优先级设置

  1. EventBits_t KeyEventBits;
  2. KeyEventBits = xEventGroupWaitBits(KeyEventGroup,
  3. KEY3_EVENT_BIT|KEY4_EVENT_BIT|KEY5_EVENT_BIT|KEY6_EVENT_BIT,
  4. pdFALSE,
  5. pdFALSE,
  6. portMAX_DELAY);
  7. printf("Key is Down Key Event Bit is %x\r\n",KeyEventBits);
  8. osDelay(10);

 (6)高优先级设置

  1. EventBits_t KeyEventBits;
  2. KeyEventBits = xEventGroupWaitBits(KeyEventGroup,
  3. KEY3_EVENT_BIT|KEY4_EVENT_BIT|KEY5_EVENT_BIT|KEY6_EVENT_BIT,
  4. pdTRUE,
  5. pdTRUE,
  6. portMAX_DELAY);
  7. if(KeyEventBits == (KEY3_EVENT_BIT|KEY4_EVENT_BIT|KEY5_EVENT_BIT|KEY6_EVENT_BIT)){
  8. printf("Buzzer is Toggle\r\n");
  9. HAL_GPIO_TogglePin(Buzzer_GPIO_Port,Buzzer_Pin);
  10. }
  11. osDelay(10);

结果:

应该是:

key3,key4,key5,key6按钮都可以触发输出,蜂鸣器触发似乎是要全部按钮按下才会消除。

KEY3,4,5,6都按下过后,蜂鸣器会响,这就是事件标志组的问题

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/353638
推荐阅读
相关标签
  

闽ICP备14008679号