1、实现功能
通过两个按键任务分别控制不同的点灯案例
创建 4 个任务:在点灯任务的基础上在创建两个按键任务:
Task_led:间隔 500ms 闪烁 LE1;
Task_led2:间隔 1000ms 闪烁 LED2;
Task_key:如果 Task_led存在,则按下 KEY 后删除 Task_led,否则创建 Task_led;
Task_key2:如果 Task_led2正常运行,则按下 KEY2 后挂起 Task_led2,否则恢复 Task_led2
2、CubeMX配置
2.1 GPIO初始化
2.2 任务建立
3、KEIL 5代码编写
3.1 main.h初始化
#define LED_ON HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_SET)
#define LED_OFF HAL_GPIO_WritePin(LED_GPIO_Port,LED_Pin,GPIO_PIN_RESET)
#define LED2_ON HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET)
#define LED2_OFF HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET)
#define key HAL_GPIO_ReadPin(key_GPIO_Port,key_Pin)
#define key2 HAL_GPIO_ReadPin(key2_GPIO_Port,key2_Pin)
3.2 功能实现
任务1:
void StartTask_led(void const * argument)
{/* USER CODE BEGIN StartTask_led *//* Infinite loop */for(;;){LED_ON;osDelay(500);LED_OFF;osDelay(500);}/* USER CODE END StartTask_led */
}
任务2:
void StartTask_led2(void const * argument)
{/* USER CODE BEGIN StartTask_led2 *//* Infinite loop */for(;;){LED2_ON;osDelay(1000);LED2_OFF;osDelay(1000);}/* USER CODE END StartTask_led2 */
}
任务3:
void StartTask_key(void const * argument)
{/* USER CODE BEGIN StartTask_key *//* Infinite loop */for(;;){if(key==0){ osDelay(20);if(key==0){printf("key按下\r\n");if(Task_ledHandle == NULL){osThreadDef(Task_led, StartTask_led, osPriorityNormal, 0, 128);Task_ledHandle = osThreadCreate(osThread(Task_led), NULL);if(Task_ledHandle != NULL){printf("task_1成功\r\n");}}else{printf("detele\r\n");osThreadTerminate(Task_ledHandle);Task_ledHandle = NULL;}}while(key==0);}osDelay(10);}/* USER CODE END StartTask_key */
}
任务4:
void StartTask_key2(void const * argument)
{/* USER CODE BEGIN StartTask_key2 */static int flag = 0;/* Infinite loop */for(;;){if(key2==0){ osDelay(20);if(key2==0){printf("key2按下\r\n");if(flag == 0){osThreadSuspend(Task_led2Handle);printf("任务2以暂停\r\n");flag=1;}else{osThreadResume(Task_led2Handle);printf("任务2恢复\r\n");flag=0;}}while(key2==0);}osDelay(10);} /* USER CODE END StartTask_key2 */
}
整个freertos.c代码如下:
/* USER CODE BEGIN Header */
/********************************************************************************* File Name : freertos.c* Description : Code for freertos applications******************************************************************************* @attention** Copyright (c) 2023 STMicroelectronics.* All rights reserved.** This software is licensed under terms that can be found in the LICENSE file* in the root directory of this software component.* If no LICENSE file comes with this software, it is provided AS-IS.********************************************************************************/
/* USER CODE END Header *//* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes *//* USER CODE END Includes *//* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD *//* USER CODE END PTD *//* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD *//* USER CODE END PD *//* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM *//* USER CODE END PM *//* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables *//* USER CODE END Variables */
osThreadId Task_ledHandle;
osThreadId Task_led2Handle;
osThreadId Task_keyHandle;
osThreadId Task_key2Handle;/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes *//* USER CODE END FunctionPrototypes */void StartTask_led(void const * argument);
void StartTask_led2(void const * argument);
void StartTask_key(void const * argument);
void StartTask_key2(void const * argument);void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) *//* GetIdleTaskMemory prototype (linked to static allocation support) */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize );/* USER CODE BEGIN GET_IDLE_TASK_MEMORY */
static StaticTask_t xIdleTaskTCBBuffer;
static StackType_t xIdleStack[configMINIMAL_STACK_SIZE];void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize )
{*ppxIdleTaskTCBBuffer = &xIdleTaskTCBBuffer;*ppxIdleTaskStackBuffer = &xIdleStack[0];*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;/* place for user code */
}
/* USER CODE END GET_IDLE_TASK_MEMORY *//*** @brief FreeRTOS initialization* @param None* @retval None*/
void MX_FREERTOS_Init(void) {/* USER CODE BEGIN Init *//* USER CODE END Init *//* USER CODE BEGIN RTOS_MUTEX *//* add mutexes, ... *//* USER CODE END RTOS_MUTEX *//* USER CODE BEGIN RTOS_SEMAPHORES *//* add semaphores, ... *//* USER CODE END RTOS_SEMAPHORES *//* USER CODE BEGIN RTOS_TIMERS *//* start timers, add new ones, ... *//* USER CODE END RTOS_TIMERS *//* USER CODE BEGIN RTOS_QUEUES *//* add queues, ... *//* USER CODE END RTOS_QUEUES *//* Create the thread(s) *//* definition and creation of Task_led */osThreadDef(Task_led, StartTask_led, osPriorityNormal, 0, 128);Task_ledHandle = osThreadCreate(osThread(Task_led), NULL);/* definition and creation of Task_led2 */osThreadDef(Task_led2, StartTask_led2, osPriorityBelowNormal, 0, 128);Task_led2Handle = osThreadCreate(osThread(Task_led2), NULL);/* definition and creation of Task_key */osThreadDef(Task_key, StartTask_key, osPriorityNormal, 0, 128);Task_keyHandle = osThreadCreate(osThread(Task_key), NULL);/* definition and creation of Task_key2 */osThreadDef(Task_key2, StartTask_key2, osPriorityNormal, 0, 128);Task_key2Handle = osThreadCreate(osThread(Task_key2), NULL);/* USER CODE BEGIN RTOS_THREADS *//* add threads, ... *//* USER CODE END RTOS_THREADS */}/* USER CODE BEGIN Header_StartTask_led */
/*** @brief Function implementing the Task_led thread.* @param argument: Not used* @retval None*/
/* USER CODE END Header_StartTask_led */
void StartTask_led(void const * argument)
{/* USER CODE BEGIN StartTask_led *//* Infinite loop */for(;;){LED_ON;osDelay(500);LED_OFF;osDelay(500);}/* USER CODE END StartTask_led */
}/* USER CODE BEGIN Header_StartTask_led2 */
/**
* @brief Function implementing the Task_led2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask_led2 */
void StartTask_led2(void const * argument)
{/* USER CODE BEGIN StartTask_led2 *//* Infinite loop */for(;;){LED2_ON;osDelay(1000);LED2_OFF;osDelay(1000);}/* USER CODE END StartTask_led2 */
}/* USER CODE BEGIN Header_StartTask_key */
/**
* @brief Function implementing the Task_key thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask_key */
void StartTask_key(void const * argument)
{/* USER CODE BEGIN StartTask_key *//* Infinite loop */for(;;){if(key==0){ osDelay(20);if(key==0){printf("key按下\r\n");if(Task_ledHandle == NULL){osThreadDef(Task_led, StartTask_led, osPriorityNormal, 0, 128);Task_ledHandle = osThreadCreate(osThread(Task_led), NULL);if(Task_ledHandle != NULL){printf("task_1成功\r\n");}}else{printf("detele\r\n");osThreadTerminate(Task_ledHandle);Task_ledHandle = NULL;}}while(key==0);}osDelay(10);}/* USER CODE END StartTask_key */
}/* USER CODE BEGIN Header_StartTask_key2 */
/**
* @brief Function implementing the Task_key2 thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartTask_key2 */
void StartTask_key2(void const * argument)
{/* USER CODE BEGIN StartTask_key2 */static int flag = 0;/* Infinite loop */for(;;){if(key2==0){ osDelay(20);if(key2==0){printf("key2按下\r\n");if(flag == 0){osThreadSuspend(Task_led2Handle);printf("任务2以暂停\r\n");flag=1;}else{osThreadResume(Task_led2Handle);printf("任务2恢复\r\n");flag=0;}}while(key2==0);}osDelay(10);} /* USER CODE END StartTask_key2 */
}/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application *//* USER CODE END Application */