概要
CubeMX STM32 SystemTimer 简单任务调度
本文主要介绍一下使用CubeMX+Stm32芯片运行简单的任务调度系统的实现过程。
STM32中任务调度的意义
1、提高系统实时性
定时任务调度允许STM32以精确的时间间隔执行特定任务,满足实时系统的严格要求。例如,在工业控制中,传感器数据采集和电机控制需要严格的时间同步,定时调度确保这些任务按时执行,避免延迟导致的系统不稳定。
2、优化资源利用率
通过合理调度任务,STM32可以避免CPU资源浪费。空闲时间可用于低优先级任务或进入低功耗模式,从而提升整体能效。例如,在电池供电设备中,定时唤醒和任务调度可显著延长电池寿命。
3、简化复杂任务管理
对于多任务系统,定时调度器(如FreeRTOS的定时器功能)能简化任务协调。周期性任务(如数据上传、状态检测)无需手动管理时序,只需配置调度器即可自动执行,降低代码复杂度。
实现思路
硬件定时器配置
使用STM32的硬件定时器(如SystemTimer)配合HAL库实现任务调度。配置定时器基础中断频率(如1ms),在中断回调函数或main函数中维护任务队列。
CubeMX配置图
如图所示,正常配置时钟树和系统定时器即可。


代码实现
Task.c
/****************************************************************************************
* @file Task.c
* @brief 时间片轮询
* @author lwz
* @date 2025/10/24
* @version V1.0.0
* @note
****************************************************************************************/
/*头文件添加区*/
#include "Task.h"
/*宏定义定义区*/
/*外部变量引用区*/
/*全局变量定义区*/
TaskList g_taskList = {0};//任务列表
/*函数声明区*/
/*函数定义区*/
/***************************************************************************************
* @brief 时间片轮询的主要调度任务
* @param void
* @retval void
* @note
***************************************************************************************/
void TaskScheduler(void)
{
uint8_t taskId = 0;
if(g_taskList.taskNum == 0)
return;
for(; taskId<g_taskList.taskNum; taskId++)
{
if(HAL_GetTick() - g_taskList.taskListArr[taskId].lastRunTick >= g_taskList.taskListArr[taskId].taskCycTime)
{//当前时间与上次任务结束时间差值大于该任务的运行周期就运行该任务
g_taskList.taskListArr[taskId].lastRunTick = HAL_GetTick();//记录当前最后一次运行时间
g_taskList.taskListArr[taskId].TaskFunc();
}
}
};
/***************************************************************************************
* @brief 添加任务至任务表
* @param taskFunc 要添加的任务结构体
taskCycTime 任务执行周期
* @retval 成功返回1 失败返回0
* @note
***************************************************************************************/
uint8_t AddTaskToList(void (*taskFunc)(void), uint16_t taskCycTime)
{
if(g_taskList.taskNum >= MAX_TASK_NUM)
{
return 0;
}
g_taskList.taskListArr[g_taskList.taskNum].TaskFunc = taskFunc;
g_taskList.taskListArr[g_taskList.taskNum].lastRunTick = 0;
g_taskList.taskListArr[g_taskList.taskNum].taskCycTime = taskCycTime;
g_taskList.taskNum++;
g_taskList.taskListArr[g_taskList.taskNum].taskId = g_taskList.taskNum;
return 1;
}
Task.h
#ifndef _TASK_H
#define _TASK_H
#include "main.h"
#define MAX_TASK_NUM 32
typedef void (*TaskFunc)(void);
//任务结构体
typedef struct
{
uint8_t taskId; //任务编号
uint16_t taskCycTime; //任务执行频率
void (*TaskFunc)(void); //要执行的任务
uint32_t lastRunTick; //上次运行结束时间
}TaskType;
//任务列表结构体
typedef struct
{
TaskType taskListArr[MAX_TASK_NUM]; //任务数组
uint8_t taskNum; //当前列表中的任务数量
}TaskList;
void TaskScheduler(void);
uint8_t AddTaskToList(void (*TaskFunc)(void), uint16_t taskCycTime);
#endif
main.c
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 */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
/* USER CODE BEGIN 2 */
AddTaskToList(TaskFunc1, TIME4MS);//添加执行周期为4MS的定时任务
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
TaskScheduler();//任务调度
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
1522

被折叠的 条评论
为什么被折叠?



