[ 附件影像 RECORD ]
FreeRTOS学习笔记 · 第二十讲:8.2任务通知使用示例

FreeRTOS学习笔记 · 第二十讲:8.2任务通知使用示例

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

依旧使用上次代码改写。

任务通知传递数据

C
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc){
  if(hadc->Instance == ADC1){
    // adc_value = HAL_ADC_GetValue(hadc);
    //printf("ADC Conversion Completed!\r\n");
    BaseType_t highter_priority_task_woken = pdFALSE;
    if(Task_showADCHandle != NULL){ // 确保任务句柄已创建
      // 直接将ADC值作为通知值发送给显示任务
      xTaskNotifyFromISR(Task_showADCHandle, HAL_ADC_GetValue(hadc), eSetValueWithOverwrite,&highter_priority_task_woken);
      portYIELD_FROM_ISR(highter_priority_task_woken);  
    }
     
  }
}
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);

  lcd_dma2d_show_eubf_str(0, 32,(char*)"ADC Value:", "BoutiqueBitmap7x7_Circle_Dot", 30, WHITE);
  uint32_t show_adc_value = 0;
  // 等待应用启动完成
  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(;;)
  {
    // 等待数据准备就绪
    if(xTaskNotifyWait(0,0XFFFFFFFF, &show_adc_value, portMAX_DELAY) == pdTRUE){
      // 数据已准备好,继续执行
      // 显示ADC值
      char adc_str[16];
      // 格式化输出,保留4位
      snprintf(adc_str, sizeof(adc_str), "%04lu", show_adc_value);
      // 转换为RGB565颜色
      uint16_t rgb565 = (uint16_t)((((show_adc_value >> 8) & 0xF) * 0x21 << 10) | (((show_adc_value >> 4) & 0xF) * 0x44 << 4) | ((show_adc_value & 0xF) * 0x21 >> 4));
      
      lcd_dma2d_fill(0, 32, 160, 65, BLACK);
      lcd_dma2d_show_eubf_str(0, 64,(char*)adc_str, "BoutiqueBitmap7x7_Circle_Dot", 32, rgb565);
      lcd_dma2d_update_screen();
      osDelay(1);
    }
    osDelay(1);
    
  }
  /* USER CODE END App_Task_showADC */
}

任务通知做信号量

C
void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc){
  // 这里可以添加定时器事件处理代码
  
  if(Task_CheckInHandle != NULL){ // 确保任务已创建
    BaseType_t highter_priority_task_woken = pdFALSE;
    vTaskNotifyGiveFromISR(Task_CheckInHandle, &highter_priority_task_woken);
    portYIELD_FROM_ISR(highter_priority_task_woken);
  }
}
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);

  
  char temp_str[30];
  UBaseType_t last_count = 0xFFFFFFFF; 
  UBaseType_t current_count = 0;

  osDelay(1500); 

  //sprintf(temp_str, "%lu", uxSemaphoreGetCount(CountingSem_TableHandle));
  
  // 等待应用启动完成
  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);
  // 第一行:Y=32 (0~32)
  lcd_dma2d_show_eubf_str(160, 32, (char*)"TOTAL_TABLE:", "BoutiqueBitmap7x7_Scan_Line", 22, YELLOW);
  // 第二行:Y=64 (32~64)
  lcd_dma2d_show_eubf_str(160, 64, "无限个!∞!", "BoutiqueBitmap7x7_Scan_Line", 32, GREEN);
  // 第三行:Y=96 (64~96)
  lcd_dma2d_show_eubf_str(160, 96, (char*)"AVAILABLE:", "BoutiqueBitmap7x7_Scan_Line", 24, RED);
  
  // 第一次推送到屏幕
  lcd_dma2d_update_screen();

  /* Infinite loop */
  for(;;)
  {
    
    // 按键处理
    if(myGetKeyPressStateByID(KEY_UP)){
      // 清除第五行 (占据 128~160)
      lcd_dma2d_fill(160, 128, 320, 160+1, BLACK); 
      
      if(ulTaskNotifyTake(pdFALSE, 0) > 0){
        lcd_dma2d_show_eubf_str(160, 160, (char*)"CheckIn OK", "BoutiqueBitmap7x7_Scan_Line", 24, GREEN);
      } else {
        lcd_dma2d_show_eubf_str(160, 160, (char*)"CheckIn Failed", "BoutiqueBitmap7x7_Scan_Line", 24, RED);
      }
      lcd_dma2d_update_screen();
    }

    // 按需刷新
    current_count = ulTaskNotifyValueClear(NULL, 0x00);
    if(current_count != last_count)
    {
      sprintf(temp_str, "%lu", (unsigned long)current_count);
      
      // 清除第四行 (占据 96~128)
      lcd_dma2d_fill(160, 96, 320, 128+1, BLACK); 
      // 绘制第四行数字
      lcd_dma2d_show_eubf_str(160, 128, temp_str, "BoutiqueBitmap7x7_Scan_Line", 32, current_count?GREEN:RED);
      
      lcd_dma2d_update_screen();
      last_count = current_count;
    }
    
    osDelay(100);
    

  }
  /* USER CODE END App_Task_CheckIn */
}

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

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


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