[ 附件影像 RECORD ]
FreeRTOS学习笔记 · 第十八讲:7.2事件组使用示例

FreeRTOS学习笔记 · 第十八讲:7.2事件组使用示例

[ SCAN_URL ]
[ 归档时间 ]:2026-04-12 23:08 [ 课题责任人 ]:文止墨 [ 档案分类 ]:嵌入式, 文章, 编程

最大的用处就是方便我安排初始化函数和其它函数的等待时机。

C
//先定义事件组各个位是什么意思
typedef enum {
    SYSTEM_INIT_EVENT_SD_MOUNTEDBIT_BIT_POS = 0,
    SYSTEM_INIT_EVENT_USB_CONNECTED_BIT_POS = 1,
    SYSTEM_INIT_EVENT_ADC_READY_BIT_POS     = 2,
    SYSTEM_INIT_EVENT_EUBF_READY_BIT_POS    = 3,
    SYSTEM_INIT_EVENT_TIM3_READY_BIT_POS    = 4,
    SYSTEM_INIT_EVENT_USART1_READY_BIT_POS   = 5,
    SYSTEM_INIT_EVENT_SDRAM_READY_BIT_POS   = 6,
    SYSTEM_INIT_EVENT_LCD_READY_BIT_POS     = 7,
    SYSTEM_INIT_EVENT_DMA2D_READY_BIT_POS   = 8
} SystemInitEventGroupPos_t;

typedef enum
{
    //SD卡挂载完成
    SYSTEM_INIT_EVENT_SD_MOUNTED = 1<<SYSTEM_INIT_EVENT_SD_MOUNTEDBIT_BIT_POS,
    //USB连接完成
    SYSTEM_INIT_EVENT_USB_CONNECTED = 1<<SYSTEM_INIT_EVENT_USB_CONNECTED_BIT_POS,
    //ADC初始化完成
    SYSTEM_INIT_EVENT_ADC_READY = 1<<SYSTEM_INIT_EVENT_ADC_READY_BIT_POS, 
    //EUBF初始化完成  
    SYSTEM_INIT_EVENT_EUBF_READY = 1<<SYSTEM_INIT_EVENT_EUBF_READY_BIT_POS, 
    //TIM3初始化完成
    SYSTEM_INIT_EVENT_TIM3_READY = 1<<SYSTEM_INIT_EVENT_TIM3_READY_BIT_POS, 
    //USART1初始化完成
    SYSTEM_INIT_EVENT_USART1_READY = 1<<SYSTEM_INIT_EVENT_USART1_READY_BIT_POS,
    //SDRAM初始化完成
    SYSTEM_INIT_EVENT_SDRAM_READY = 1<<SYSTEM_INIT_EVENT_SDRAM_READY_BIT_POS,
    //LCD初始化完成
    SYSTEM_INIT_EVENT_LCD_READY = 1<<SYSTEM_INIT_EVENT_LCD_READY_BIT_POS,
    //DMA2D初始化完成
    SYSTEM_INIT_EVENT_DMA2D_READY = 1<<SYSTEM_INIT_EVENT_DMA2D_READY_BIT_POS,
} SystemInitEventGroupMask_t;



/* 系统初始化任务:负责按顺序初始化各个硬件外设和软件模块
   * 功能说明:
   *   1. 初始化SDRAM外部存储器
   *   2. 初始化LCD显示屏和DMA2D硬件加速模块
   *   3. 初始化USART1串口通信
   *   4. 初始化SD卡文件系统
   *   5. 初始化EUBF字体库系统
   *   6. 启动ADC1模数转换
   *   7. 启动定时器3
   * 
   * 事件组机制:
   *   - 使用xSystemInitEventGroupHandle事件组跟踪各模块初始化状态
   *   - 每完成一个模块初始化,调用xEventGroupSetBits()设置对应标志位
   *   - 当所有模块初始化完成后,调用vTaskDelete(NULL)删除当前任务
   * 
   * 参数:
   *   argument - FreeRTOS任务参数(本任务未使用)
   */
void AppTask_SYS_INIT(void *argument)
{
  /* USER CODE BEGIN AppTask_SYS_INIT */
  //==============================  初始化 SDRAM  =============================
    SDRAM_InitSequence();
    xEventGroupSetBits(xSystemInitEventGroupHandle, SYSTEM_INIT_EVENT_SDRAM_READY);
    // ============================= 初始化 LCD 屏幕 ============================= 
    lcd_init();
    lcd_clear(BLACK);
    xEventGroupSetBits(xSystemInitEventGroupHandle, SYSTEM_INIT_EVENT_LCD_READY);
    lcd_dma2d_init();     // 初始化DMA2D硬件加速模块,用于LCD图形绘制加速
    lcd_dma2d_clear(BLACK);
    xEventGroupSetBits(xSystemInitEventGroupHandle, SYSTEM_INIT_EVENT_DMA2D_READY);
    // ============================= 初始化USART1 =============================
    MyUSART_Init();
    xEventGroupSetBits(xSystemInitEventGroupHandle, SYSTEM_INIT_EVENT_USART1_READY);
    // ============================= 初始化EUBF ============================= 
    EUBF_Port_Config_t font_sd_config = {
        .Open     = SD_FastSlot_Open_UTF8,  // 文件打开接口,支持UTF-8编码
        .Close    = (void (*)(int8_t))SD_FastSlot_Close, // 文件关闭接口,类型转换避免编译警告
        .ReadAt   = SD_FastSlot_Read,       // 文件随机读取接口
        .RootPath = "0:/"                   // SD卡根目录路径
    };
    EUBF_Init(&font_sd_config);
    xEventGroupSetBits(xSystemInitEventGroupHandle, SYSTEM_INIT_EVENT_EUBF_READY);
    //============================== 启动ADC1转换 =============================
    HAL_ADC_Start_IT(&hadc1);
    xEventGroupSetBits(xSystemInitEventGroupHandle, SYSTEM_INIT_EVENT_ADC_READY);
    //============================== 启动定时器3 =============================
    HAL_TIM_Base_Start(&htim3);
    xEventGroupSetBits(xSystemInitEventGroupHandle, SYSTEM_INIT_EVENT_TIM3_READY);
  /* Infinite loop */
  for(;;)
  {
    
    // ============================= 初始化SD卡 ============================= 
    SD_Mount_StateMachine();
    if(SD_Is_Mounted() == 1){
      // SD卡挂载成功,在LCD上显示实验标题
      lcd_dma2d_show_eubf_str(0, 32, (char*)"事件组实验", "ZCOOL QingKe HuangYou", 25, WHITE);
      lcd_dma2d_update_screen();
      xEventGroupSetBits(xSystemInitEventGroupHandle, SYSTEM_INIT_EVENT_SD_MOUNTED);
    }
    
    //============================== 检查所有模块初始化状态 =============================
    if(xEventGroupGetBits(xSystemInitEventGroupHandle) == 
                                  (SYSTEM_INIT_EVENT_SDRAM_READY | 
                                  SYSTEM_INIT_EVENT_LCD_READY | 
                                  SYSTEM_INIT_EVENT_DMA2D_READY | 
                                  SYSTEM_INIT_EVENT_USART1_READY | 
                                  SYSTEM_INIT_EVENT_TIM3_READY | 
                                  SYSTEM_INIT_EVENT_SD_MOUNTED | 
                                  SYSTEM_INIT_EVENT_EUBF_READY  | 
                                  SYSTEM_INIT_EVENT_ADC_READY)){
      // 所有模块初始化完成,删除当前任务以释放系统资源
      vTaskDelete(NULL);
    }
    osDelay(1);
  }
  /* USER CODE END AppTask_SYS_INIT */
}

像这样初始化好一个外设就置相应位为 1,然后我们再需要用到外设资源的地方加上等待条件(程序内容和信号量实验相同,省略):

C
void App_Task_showADC(void *argument)
{
  /* USER CODE BEGIN App_Task_showADC */
  //等待ADC初始化完成、定时器3初始化完成、SD卡挂载完成、EUBF初始化完成、DMA2D初始化完成、LCD初始化完成
  xEventGroupWaitBits(xSystemInitEventGroupHandle, 
                        SYSTEM_INIT_EVENT_ADC_READY | 
                        SYSTEM_INIT_EVENT_TIM3_READY | 
                        SYSTEM_INIT_EVENT_SD_MOUNTED | 
                        SYSTEM_INIT_EVENT_EUBF_READY | 
                        SYSTEM_INIT_EVENT_DMA2D_READY | 
                        SYSTEM_INIT_EVENT_LCD_READY, 
                        pdFALSE,
                        pdTRUE,
                        portMAX_DELAY);
    // 等待应用启动完成(多任务同步)
    //这里就不定义了,懒了
  xEventGroupSync(xAppStartEventGroupHandle,
                  1 << 0, // APP_START_EVENT_SHOW_ADC_READY
                  1 << 0|1 << 1, // APP_START_EVENT_SHOW_ADC_READY | APP_START_EVENT_SHOW_CHECKIN_READY
                  portMAX_DELAY);
  /* Infinite loop */
  for(;;)
  {
    //省略内容
    osDelay(250);
    
  }
  /* USER CODE END App_Task_showADC */
}
C
void App_Task_CheckIn(void *argument)
{
  /* USER CODE BEGIN App_Task_CheckIn */
  //等待SD卡挂载完成、EUBF初始化完成、DMA2D初始化完成、LCD初始化完成
  xEventGroupWaitBits(xSystemInitEventGroupHandle, 
                        SYSTEM_INIT_EVENT_SD_MOUNTED | 
                        SYSTEM_INIT_EVENT_EUBF_READY | 
                        SYSTEM_INIT_EVENT_DMA2D_READY | 
                        SYSTEM_INIT_EVENT_LCD_READY, 
                        pdFALSE,
                        pdTRUE,
                        portMAX_DELAY);
  // 等待应用启动完成(多任务同步)
  xEventGroupSync(xAppStartEventGroupHandle,
                  1 << 1, // APP_START_EVENT_SHOW_CHECKIN_READY
                  1 << 0|1 << 1, // APP_START_EVENT_SHOW_ADC_READY | APP_START_EVENT_SHOW_CHECKIN_READY
                  portMAX_DELAY);
  //省略内容

  /* Infinite loop */
  for(;;)
  {
    //省略内容
    osDelay(100);
  }
  /* USER CODE END App_Task_CheckIn */
}

[ 发起通讯连接 / INITIATE COMM-LINK ]

[SYS]: 您的回传节点(邮箱)将被严格保密。带有 * 的字段为必填项。


> 终止读取并返回主控制台 <