STM32_实现双线程控制LED交替闪烁(UCOS)

线程定义函数

cpp 复制代码
void  OSTaskCreate (OS_TCB        *p_tcb,
                    CPU_CHAR      *p_name,
                    OS_TASK_PTR    p_task,
                    void          *p_arg,
                    OS_PRIO        prio,
                    CPU_STK       *p_stk_base,
                    CPU_STK_SIZE   stk_limit,
                    CPU_STK_SIZE   stk_size,
                    OS_MSG_QTY     q_size,
                    OS_TICK        time_quanta,
                    void          *p_ext,
                    OS_OPT         opt,
                    OS_ERR        *p_err)

OSTaskCreate 函数的这种形式看起来像是来自μC/OS-III实时操作系统。这个函数用于创建一个任务,并且提供了更多的配置选项。下面是对每个参数的解释:

  1. p_tcb:指向任务控制块(TCB)的指针。TCB是操作系统用来管理任务的所有信息的结构,包括任务的当前状态、优先级、栈指针等。

  2. p_name:任务的名称,通常是一个以null结尾的字符串,用于调试和识别任务。

  3. p_task:任务函数的指针,这是任务执行的入口点。

  4. p_arg:传递给任务函数的参数的指针。

  5. prio:任务的优先级。在μC/OS-III中,优先级越高,任务越先被执行。

  6. p_stk_base:指向任务栈底的指针。任务栈是任务执行时用于存储局部变量和上下文切换信息的一段内存。

  7. stk_limit:栈的限制大小,用于栈溢出检测。

  8. stk_size:栈的大小,指定了任务栈的容量。

  9. q_size:任务消息队列的大小,如果任务使用消息队列来接收消息,这个参数指定队列可以容纳的最大消息数。

  10. time_quanta:时间片大小,用于时间分片调度。在时间分片调度中,每个任务在被抢占之前可以执行的时间量。

  11. p_ext:指向任务扩展数据的指针,可以用于存储用户定义的数据。

  12. opt:创建任务的选项,可以是位字段,用于指定如何创建任务,例如是否立即启动任务等。

  13. p_err:指向错误码的指针,用于返回函数执行的结果。如果任务创建成功,错误码将为OS_ERR_NONE,否则将是一个错误代码,指示失败的原因。

将定义好的线程提交给内核

cpp 复制代码
void  OSStart (OS_ERR  *p_err)

main.c文件

cpp 复制代码
/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 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 "main.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "os.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

#define TASK_STACK_SIZE 1024
OS_ERR      p_err1;

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
//创建任务栈
static CPU_STK TasK1StK[TASK_STACK_SIZE];
static CPU_STK TasK2StK[TASK_STACK_SIZE];

//创建任务控制块
static OS_TCB Task1TCB;
static OS_TCB Task2TCB;
// 任务函数
void Task1(void *p_arg) {
    MX_GPIO_Init();
    while (1) {
        // 点亮LED1
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_3);
        // 延时
        OSTimeDlyHMSM(0, 0, 1, 0,OS_OPT_TIME_HMSM_STRICT,&p_err1);
		//HAL_Delay(500);
    }
}

void Task2(void *p_arg) {
    MX_GPIO_Init();
    while (1) {
        // 点亮LED2
        HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_5);
        // 延时
        OSTimeDlyHMSM(0, 0, 0, 500,OS_OPT_TIME_HMSM_STRICT,&p_err1);
    }
}

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */


/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{

  /* USER CODE BEGIN 1 */
	
  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */
	
	//初始化ucos
	OSInit(&p_err1);
  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */
  
  Mem_Init();
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */

		OSTaskCreate(
				(OS_TCB*)&Task1TCB,//任务块名称
				(CPU_CHAR*)"task 1",//任务名称:调试的时候有用
				(OS_TASK_PTR)Task1,//任务函数
				(void*)0,//传递给任务入口函数的参数的指针
				(OS_PRIO)5,//优先级:数字越低,优先级越高
				(CPU_STK*)&TasK1StK[0],//
				(CPU_STK_SIZE)TASK_STACK_SIZE/10,
				(CPU_STK_SIZE)TASK_STACK_SIZE,
				(OS_MSG_QTY)0,
				(OS_TICK)5,
				(void*)0,
				(OS_OPT)(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
				(OS_ERR*)&p_err1//错误指针
				);
				
		OSTaskCreate(
				(OS_TCB*)&Task2TCB,//任务块名称
				(CPU_CHAR*)"task 2",//任务名称:调试的时候有用
				(OS_TASK_PTR)Task2,//任务函数
				(void*)0,//传递给任务入口函数的参数的指针
				(OS_PRIO)1,//优先级:数字越低,优先级越高
				(CPU_STK*)&TasK2StK[0],//
				(CPU_STK_SIZE)TASK_STACK_SIZE/10,
				(CPU_STK_SIZE)TASK_STACK_SIZE,
				(OS_MSG_QTY)0,
				(OS_TICK)5,
				(void*)0,
				(OS_OPT)(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
				(OS_ERR*)&p_err1//错误指针
				);
					
				
		OSStart(&p_err1);//启动多任务调度
				
  
	  
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  
  /* USER CODE END 3 */
}

/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }

  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

注意

设置内存大小根据主板而定,太小的化有可能个别线程不可运行

具体如何设置我暂时不清楚,有知道的大佬可以在评论区中讲一下吗

我是写一个值,程序能运行就不改了

相关推荐
东胜物联13 分钟前
探寻5G工业网关市场,5G工业网关品牌解析
人工智能·嵌入式硬件·5g
stm32发烧友16 分钟前
基于STM32的智能家居环境监测系统设计
stm32·嵌入式硬件·智能家居
hairenjing11238 小时前
使用 Mac 数据恢复从 iPhoto 图库中恢复照片
windows·stm32·嵌入式硬件·macos·word
模拟IC攻城狮10 小时前
华为海思招聘-芯片与器件设计工程师-模拟芯片方向- 机试题-真题套题题目——共8套(每套四十题)
嵌入式硬件·华为·硬件架构·芯片
IT B业生10 小时前
51单片机教程(六)- LED流水灯
单片机·嵌入式硬件·51单片机
一枝小雨10 小时前
51单片机学习心得2(基于STC89C52):串口通信(UART)
单片机·嵌入式硬件·51单片机
IT B业生11 小时前
51单片机教程(一)- 开发环境搭建
单片机·嵌入式硬件·51单片机
u01015265812 小时前
STM32F103C8T6学习笔记2--LED流水灯与蜂鸣器
笔记·stm32·学习
海绵波波10713 小时前
Webserver(4.8)UDP、广播、组播
单片机·网络协议·udp
好想有猫猫13 小时前
【51单片机】串口通信原理 + 使用
c语言·单片机·嵌入式硬件·51单片机·1024程序员节