0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于STM32F407的FreeRTOS学习笔记(10)

CHANBAEK 来源:实在太懒于是不想取名 作者: 电路小白 2023-11-08 11:10 次阅读

在介绍二进制信号量时曾经讲过,二进制信号量可以代替我们裸机开发中的标志位来使用。在裸机开发中我们使用标志位来表示某个事件是否发生,并且其他程序利用标记位的状态来判断程序是否可以继续进行。但是这种大量使用标记位的情况会导致代码的逻辑异常的复杂。

图片

虽然使用二进制信号量可以很好的实现标志位的实现以及相应的任务安排,但是二进制信号量并不适用于大量的标志位。因为一个二进制信号量只能表示一个事件,假如我们的程序有大量的事件那有没有办法不用二进制信号量可以很好的管理这些事件呢?

这就是本期介绍的内容:事件位和事件组

图片

FreeRTOS中我们把一个用作判断事件是否发生的情况作为事件位,用0或1表示。它可以用来表示一个事件是否发生。比如函数Test是否被调用,用户是否按下按键等等事件。

图片

这些由多个事件位构成的集合则被称为事件组。事件组中不同的位编号代表不同的事件位。例如位编号0(0x00)用来代表函数Test是否被调用,事件组位编号1(0x01)代表用户是否按下按钮……

图片

FreeRTOS 通过相对应的宏定义来确定事件组的长度(包含多少事件位)例如config_16_BIT_TICKS为0的话则代表一个事件组可以包含24位事件位。

使用事件组

和之前的其他内容一样,使用事件组的准备也要包含相关头文件、定义相对应的宏定义、调用创建函数。

图片

事件组的创建函数非常简单,只需要定义一个事件组的句柄来接收事件组创建函数的返回值即可。事件组的长度前面说过利用宏定义来确定时间组长度。

图片

等待事件组的函数和信号量相似,设置我们需要等待事件发生的位并且设置超时时间。但是注意的是我们选择需要等待的位不能设置为0

第三个参数用来设置等到事件位触发后是否清空数据位。

其中的第四个参数xWaitForAllBits则是用来 确定位之间的与或关系 ,例如如果我的位设置是0x03即第0和第1位,如果xWaitForAllBits是pdTRUE则需要第0和第1位同时为1,如果是pdFalse则第0和第1只要有一个事件触发就执行。

图片

该函数用来设置事件位,需要注意的是该函数的返回值是事件组各位的值,但是如果有更高优先级的任务在等待则会立刻清空事件位,所以会导致事件位返回时被清空。

测试实验

首先我们创建一个事件组,宏定义中定义这个事件组总共有24个事件位。

EventHandler = xEventGroupCreate();

接着我们创建一个按键检测任务,当按钮一按下时,将事件组第0位置1,当按钮二按下时,将事件组第1位置1;

void Low_Task(void * pvParameters)//参数为 void * pvParameters
{
  while(1)
  {
    if(KEY_Scan(0)==1)
    {
        xEventGroupSetBits(EventHandler,1< < 0);//1< < 0是0x01
    }
    if(KEY_Scan(0)==2)
    {
      xEventGroupSetBits(EventHandler,1< < 1);//1< < 1是0x02
    }    
    vTaskDelay(10);
  }
}

最后我们设置一个轮询事件组的语句,并且设置第四个参数为pdFlase,当有一个按键按下时,LED翻转。

void Mid_Task(void * pvParameters)//参数为 void * pvParameters
{
  BaseType_t err;
  while(1)
  {
    err = xEventGroupWaitBits(
                       (const EventGroupHandle_t) EventHandler,
                       (const EventBits_t) 0x03,
                       (const BaseType_t) pdTRUE,
                       (const BaseType_t) pdFALSE,
                       (TickType_t) portMAX_DELAY  );
      HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);

    vTaskDelay(10);
  }
}

接着我们把pdFlase改成pdTRUE,当两个按钮(事件)都触发过的时候,才能执行任务。

void Mid_Task(void * pvParameters)//参数为 void * pvParameters
{
  BaseType_t err;
  while(1)
  {
    err = xEventGroupWaitBits(
                       (const EventGroupHandle_t) EventHandler,
                       (const EventBits_t) 0x03,
                       (const BaseType_t) pdTRUE,
                       (const BaseType_t) pdTRUE,
                       (TickType_t) portMAX_DELAY  );
      HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_10);

    vTaskDelay(10);
  }
}

其中xEventGroupWaitBits返回值会根据不同的情况而改变。

图片

如果因为事件组全部触发而完成的函数的话,err返回函数清空前的事件组的值。

图片

如果因为超时而导致阻塞结束的话,err返回的则是当前事件组的值。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 二进制
    +关注

    关注

    2

    文章

    707

    浏览量

    41250
  • 函数
    +关注

    关注

    3

    文章

    3881

    浏览量

    61310
  • FreeRTOS
    +关注

    关注

    12

    文章

    473

    浏览量

    61348
  • STM32F407
    +关注

    关注

    15

    文章

    187

    浏览量

    28977
  • 信号量
    +关注

    关注

    0

    文章

    53

    浏览量

    8257
收藏 人收藏

    评论

    相关推荐

    基于STM32F407FreeRTOS学习笔记(9)

    在嵌入式编程中,定时器是一个非常重要且强大的功能,用来帮我们定时性的调用中断服务函数来帮助我们处理程序。定时器通常是用硬件来实现的,例如STM32F407就有8个硬件定时器。
    的头像 发表于 11-08 11:08 416次阅读
    基于<b class='flag-5'>STM32F407</b>的<b class='flag-5'>FreeRTOS</b><b class='flag-5'>学习</b><b class='flag-5'>笔记</b>(9)

    stm32f407

    请问学习stm32f407哪个视频教程比较好?
    发表于 04-03 19:06

    STM32F407时钟配置学习

    STM32F407时钟配置学习
    发表于 08-04 07:14

    FreeRTOS移植到STM32F407

    FreeRTOS,接下来我们就把FreeRTOS移植到我们所使用的平台上,我们使用的板子是STM32F407。02. 预备工作要移植FreeRTOS,肯定需要一个基础工程,基础工程越
    发表于 08-24 06:07

    如何使用STM32F407去移植FreeRTOS

    如何使用STM32F407去移植FreeRTOS呢?有哪些操作步骤?
    发表于 10-21 09:45

    STM32F407 FreeRTOS开发指南

    参考资料:正点原子《littleVGL 开发指南》正点原子《STM32F407 FreeRTOS 开发指南》硬件平台:stm32f407开发板(或最小系统)、4.3寸TFTLCD以正点原子的例程为
    发表于 01-05 06:55

    STM32F407标准库学习

    STM32F407标准库学习笔记-AFIO- 头文件 gpio.h#define GPIO_PinSource0((uint8_t)0x00)#define GPIO_PinSource1
    发表于 01-24 06:42

    STM32F407开发板用户手册】第13章 STM32F407启动过程详解

    STM32F407开发板用户手册】第13章 STM32F407启动过程详解
    发表于 11-23 18:06 70次下载
    【<b class='flag-5'>STM32F407</b>开发板用户手册】第13章 <b class='flag-5'>STM32F407</b>启动过程详解

    STM32F407标准库学习笔记-RCC

    STM32F407标准库学习笔记-RCC- rcc.htypedef struct{ uint32_t SYSCLK_Frequency; /*!< SYSCLK clock
    发表于 11-29 15:51 13次下载
    <b class='flag-5'>STM32F407</b>标准库<b class='flag-5'>学习</b><b class='flag-5'>笔记</b>-RCC

    STM32F407标准库学习笔记-GPIO

    STM32F407标准库学习笔记-GPIO头文件 gpio.h枚举-列举同一寄存器的不同选项typedef enum{ GPIO_Low_Speed = 0x00, /*!<
    发表于 11-29 15:51 46次下载
    <b class='flag-5'>STM32F407</b>标准库<b class='flag-5'>学习</b><b class='flag-5'>笔记</b>-GPIO

    STM32F407开发板用户手册】第14章 STM32F407的电源,复位和时钟系统

    STM32F407开发板用户手册】第14章 STM32F407的电源,复位和时钟系统
    发表于 12-02 16:21 39次下载
    【<b class='flag-5'>STM32F407</b>开发板用户手册】第14章 <b class='flag-5'>STM32F407</b>的电源,复位和时钟系统

    STM32F407开发板用户手册】第1章   初学STM32F407的准备工作

    STM32F407开发板用户手册】第1章   初学STM32F407的准备工作
    发表于 12-04 13:36 73次下载
    【<b class='flag-5'>STM32F407</b>开发板用户手册】第1章   初学<b class='flag-5'>STM32F407</b>的准备工作

    STM32F407开发板用户手册】第19章 STM32F407的GPIO应用之按键FIFO

    STM32F407开发板用户手册】第19章 STM32F407的GPIO应用之按键FIFO
    发表于 12-05 15:21 32次下载
    【<b class='flag-5'>STM32F407</b>开发板用户手册】第19章 <b class='flag-5'>STM32F407</b>的GPIO应用之按键FIFO

    stm32f407原理图

    stm32f407原理图
    发表于 07-14 16:07 169次下载

    STM32F407 FreeRTOS开发手册 V1.1

    STM32F407 FreeRTOS开发手册_V1.1PDF文件下载。
    发表于 07-31 11:16 44次下载