You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

241 lines
9.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/* FreeRTOS头文件 */
#include "FreeRTOS.h"
#include "task.h"
#include "rgb.h"
#include "usart.h"
/**************************** 任务句柄 ********************************/
/*
* 任务句柄是一个指针,用于指向一个任务,当任务创建好之后,它就具有了一个任务句柄
* 以后我们要想操作这个任务都需要通过这个任务句柄,如果是自身的任务操作自己,那么
* 这个句柄可以为NULL。
*/
static TaskHandle_t AppTaskCreate_Handle = NULL;/* 创建任务句柄 */
static TaskHandle_t Test_Task_Handle = NULL;/* LED任务句柄 */
static TaskHandle_t KEY_Task_Handle = NULL;/* KEY任务句柄 */
/********************************** 内核对象句柄 *********************************/
/*
* 信号量,消息队列,事件标志组,软件定时器这些都属于内核的对象,要想使用这些内核
* 对象,必须先创建,创建成功之后会返回一个相应的句柄。实际上就是一个指针,后续我
* 们就可以通过这个句柄操作这些内核对象。
*
* 内核对象说白了就是一种全局的数据结构,通过这些数据结构我们可以实现任务间的通信,
* 任务间的事件同步等各种功能。至于这些功能的实现我们是通过调用这些内核对象的函数
* 来完成的
*
*/
/******************************* 全局变量声明 ************************************/
/*
* 当我们在写应用程序的时候,可能需要用到一些全局变量。
*/
/*
*************************************************************************
* 函数声明
*************************************************************************
*/
static void AppTaskCreate(void);/* 用于创建任务 */
static void Test_Task(void* pvParameters);/* Test_Task任务实现 */
static void KEY_Task(void* pvParameters);/* KEY_Task任务实现 */
static void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
//配置时钟源HSE/HSI/LSE/LSI
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
// RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_8MHz; //配置HSI输出时钟为8MHz
//RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_4MHz; //配置HSI输出时钟为4MHz
//RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_16MHz; //配置HSI输出时钟为16MHz
//RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_22p12MHz; //配置HSI输出时钟为22.12MHz
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_24MHz; //配置HSI输出时钟为24MHz
RCC_OscInitStruct.HSEState = RCC_HSE_ON; //开启HSE
RCC_OscInitStruct.HSEFreq = RCC_HSE_16_32MHz; //HSE工作频率范围16M~32M
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.LSIState = RCC_LSI_ON; //开启LSI
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) //初始化RCC振荡器
{
// Error_Handler();
}
//初始化CPU,AHB,APB总线时钟
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1; //RCC系统时钟类型
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; //SYSCLK的源选择为HSE
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; //APH时钟不分频
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; //APB时钟2分频
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) //初始化RCC系统时钟(FLASH_LATENCY_0=24M以下;FLASH_LATENCY_1=48M)
{
// Error_Handler();
}
}
/**
* @brief 初始化外设相关
*/
static void BSP_Init(void)
{
/* LED 初始化 */
RGB_Init();
/* 串口初始化 */
USART_Config();
}
/*****************************************************************
* @brief 主函数
* @param 无
* @retval 无
* @note 第一步:开发板硬件初始化
第二步创建APP应用任务
第三步启动FreeRTOS开始多任务调度
****************************************************************/
int main(void)
{
BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值默认为pdPASS */
SystemClock_Config();
HAL_Init();
/* 开发板硬件初始化 */
BSP_Init();
/* 创建AppTaskCreate任务 */
xReturn = xTaskCreate((TaskFunction_t )AppTaskCreate, /* 任务入口函数 */
(const char* )"AppTaskCreate",/* 任务名字 */
(uint16_t )configMINIMAL_STACK_SIZE, /* 任务栈大小 */
(void* )NULL,/* 任务入口函数参数 */
(UBaseType_t )1, /* 任务的优先级 */
(TaskHandle_t* )&AppTaskCreate_Handle);/* 任务控制块指针 */
/* 启动任务调度 */
if(pdPASS == xReturn)
vTaskStartScheduler(); /* 启动任务,开启调度 */
else
return -1;
while(1); /* 正常不会执行到这里 */
}
/***********************************************************************
* @ 函数名 AppTaskCreate
* @ 功能说明: 为了方便管理,所有的任务创建函数都放在这个函数里面
* @ 参数
* @ 返回值
**********************************************************************/
static void AppTaskCreate(void)
{
BaseType_t xReturn = pdPASS;/* 定义一个创建信息返回值默认为pdPASS */
taskENTER_CRITICAL(); //进入临界区
/* 创建Test_Task任务 */
xReturn = xTaskCreate((TaskFunction_t )Test_Task, /* 任务入口函数 */
(const char* )"Test_Task",/* 任务名字 */
(uint16_t )configMINIMAL_STACK_SIZE, /* 任务栈大小 */
(void* )NULL, /* 任务入口函数参数 */
(UBaseType_t )2, /* 任务的优先级 */
(TaskHandle_t* )&Test_Task_Handle);/* 任务控制块指针 */
if(pdPASS == xReturn) {
printf("创建Test_Task任务成功!\r\n");
}
/* 创建KEY_Task任务 */
xReturn = xTaskCreate((TaskFunction_t )KEY_Task, /* 任务入口函数 */
(const char* )"KEY_Task",/* 任务名字 */
(uint16_t )configMINIMAL_STACK_SIZE, /* 任务栈大小 */
(void* )NULL,/* 任务入口函数参数 */
(UBaseType_t )3, /* 任务的优先级 */
(TaskHandle_t* )&KEY_Task_Handle);/* 任务控制块指针 */
if(pdPASS == xReturn) {
printf("创建KEY_Task任务成功!\r\n");
}
vTaskDelete(AppTaskCreate_Handle); //删除AppTaskCreate任务
taskEXIT_CRITICAL(); //退出临界区
}
int test = 0;
/**********************************************************************
* @ 函数名 Test_Task
* @ 功能说明: Test_Task任务主体
* @ 参数
* @ 返回值
********************************************************************/
static void Test_Task(void* parameter)
{
(void)parameter;
while (1) {
test = configCPU_CLOCK_HZ;
HAL_GPIO_WritePin(LED4_GPIO_PORT, LED4_PIN, GPIO_PIN_RESET);
printf("Test_Task Running,LED1_ON\r\n");
vTaskDelay(pdMS_TO_TICKS(500)); /* 延时500个tick */
HAL_GPIO_WritePin(LED4_GPIO_PORT, LED4_PIN, GPIO_PIN_SET);
printf("Test_Task Running,LED1_OFF\r\n");
vTaskDelay(500); /* 延时500个tick */
}
}
/**********************************************************************
* @ 函数名 Test_Task
* @ 功能说明: Test_Task任务主体
* @ 参数
* @ 返回值
********************************************************************/
static void KEY_Task(void* parameter)
{
(void)parameter;
static uint8_t key_flag = 0;
while (1) {
/* 等待按键按下 */
// if(BSP_PB_GetState(BUTTON_USER))
// {
// vTaskDelay(20);/* 延时20个tick */
// continue;
// }
key_flag = key_flag ? 0 : 1;
// if(key_flag) {
// printf("挂起Test任务\n");
// vTaskSuspend(Test_Task_Handle);/* 挂起LED任务 */
// printf("挂起Test任务成功\n");
// }
//
// if(!key_flag) {/* K2 被按下 */
// printf("恢复Test任务\n");
// vTaskResume(Test_Task_Handle);/* 恢复LED任务 */
// printf("恢复Test任务成功\n");
// }
vTaskDelay(20);/* 延时20个tick */
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t* file, uint32_t line)
{
(void)file;
(void)line;
/* User can add their own implementation here */
while (1) {
/* Infinite loop - you could also log the error or trigger a system reset */
}
}
#endif
/********************************END OF FILE****************************/