5,FreeRTOS中断管理

发布于:2025-06-28 ⋅ 阅读:(11) ⋅ 点赞:(0)

一、实验目标


        创建两个动态任务,栈空间大小均为128字。startTask、Task1。startTask仅运行一次,负责task1任务的创建,startTask任务的删除。Task1负责5S关闭一次中断,5S开启一次中断。

注:本实验基于正点原子FreeRTOS教程的学习总结。

  二、实验准备

1.FreeRTOS的Keil动态任务创建与删除程序

2.STM3F407开发板

3.HAL_Init()函数修改

        在main()函数中找到HAL_Init()函数,并跳转到函数定义位置,在函数中找到NVIC中断分组函数设置为第四组,即NVIC_PRIORITYGROUP_4。

  /* Set Interrupt Group Priority */
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

        设置为NVIC_PRIORITYGROUP_4是因为FreeRTOS仅能管理优先级为5-15的中断,而STM32的优先级分组方式4,设置中断优先级为0-15,这样方便FreeRTOS管理中断。

4.基本定时器中断初始化

        需要添加基本定时器.c文件,并在mian函数中初始化基本定时器中断。

4.1btim.h头文件修改

        首先,在.h文件中添加基本定时的配置信息。这里使用定时器6/7,分别定时为1S输出一次信息。

#define BTIM_TIM6_INT                       TIM6
#define BTIM_TIM6_INT_IRQn                  TIM6_DAC_IRQn
#define BTIM_TIM6_INT_IRQHandler            TIM6_DAC_IRQHandler
#define BTIM_TIM6_INT_CLK_ENABLE()          do{ __HAL_RCC_TIM6_CLK_ENABLE(); }while(0)  /* TIM6 时钟使能 */


#define BTIM_TIM7_INT                       TIM7
#define BTIM_TIM7_INT_IRQn                  TIM7_IRQn
#define BTIM_TIM7_INT_IRQHandler            TIM7_IRQHandler
#define BTIM_TIM7_INT_CLK_ENABLE()          do{ __HAL_RCC_TIM7_CLK_ENABLE(); }while(0)  /* TIM7 时钟使能 */
/******************************************************************************************/

void btim_tim6_int_init(uint16_t arr, uint16_t psc);    /* 基本定时器 定时中断初始化函数 */
void btim_tim7_int_init(uint16_t arr, uint16_t psc);    /* 基本定时器 定时中断初始化函数 */

 4.2btim.c源文件修改

        定义两个定时器句柄,并进行中断初始化。

TIM_HandleTypeDef g_tim6_handler;         /* 定时器参数句柄 */
TIM_HandleTypeDef g_tim7_handler;         /* 定时器参数句柄 */
//定时器6中断初始化函数
void btim_tim6_int_init(uint16_t arr, uint16_t psc)
{
    g_tim6_handler.Instance = BTIM_TIM6_INT;                      /* 定时器x */
    g_tim6_handler.Init.Prescaler = psc;                          /* 分频 */
    g_tim6_handler.Init.CounterMode = TIM_COUNTERMODE_UP;         /* 递增计数模式 */
    g_tim6_handler.Init.Period = arr;                             /* 自动装载值 */
    HAL_TIM_Base_Init(&g_tim6_handler);
    
    HAL_TIM_Base_Start_IT(&g_tim6_handler);                       /* 使能定时器x和定时器更新中断 */
}
//定时器7中断初始化函数
void btim_tim7_int_init(uint16_t arr, uint16_t psc)
{
    g_tim7_handler.Instance = BTIM_TIM7_INT;                      /* 定时器x */
    g_tim7_handler.Init.Prescaler = psc;                          /* 分频 */
    g_tim7_handler.Init.CounterMode = TIM_COUNTERMODE_UP;         /* 递增计数模式 */
    g_tim7_handler.Init.Period = arr;                             /* 自动装载值 */
    HAL_TIM_Base_Init(&g_tim7_handler);
    
    HAL_TIM_Base_Start_IT(&g_tim7_handler);                       /* 使能定时器x和定时器更新中断 */
}

        定义底层驱动。设置定时器6抢占优先级为6,定时器7抢占优先级为4。

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == BTIM_TIM6_INT)
    {
        BTIM_TIM6_INT_CLK_ENABLE();                     /* 使能TIMx时钟 */
        HAL_NVIC_SetPriority(BTIM_TIM6_INT_IRQn, 6, 0); /* 抢占6 */
        HAL_NVIC_EnableIRQ(BTIM_TIM6_INT_IRQn);         /* 开启ITMx中断 */
    }
		if (htim->Instance == BTIM_TIM7_INT)
    {
        BTIM_TIM7_INT_CLK_ENABLE();                     /* 使能TIMx时钟 */
        HAL_NVIC_SetPriority(BTIM_TIM7_INT_IRQn, 4, 0); /* 抢占4 */
        HAL_NVIC_EnableIRQ(BTIM_TIM7_INT_IRQn);         /* 开启ITMx中断 */
    }
}

         添加中断服务函数与中断回调函数。

//中断服务函数
void BTIM_TIM6_INT_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&g_tim6_handler);  /* 定时器回调函数 */
}
void BTIM_TIM7_INT_IRQHandler(void)
{
    HAL_TIM_IRQHandler(&g_tim7_handler);  /* 定时器回调函数 */
}
//回调函数
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
    if (htim->Instance == BTIM_TIM6_INT)
    {
        printf("TIME6正在运行,优先级为6!!\r\n");
    }
    else if (htim->Instance == BTIM_TIM7_INT)
    {
        printf("TIME7正在运行,优先级为4!!!!\r\n");
    }
}

5.mian函数初始化

6.所需API函数介绍

        portDISABLE_INTERRUPTS函数用来关闭FreeRTOS所管理的中断。

    #define portDISABLE_INTERRUPTS()                  vPortRaiseBASEPRI()

         portENABLE_INTERRUPTS函数用来开启FreeRTOS所管理的中断。

    #define portENABLE_INTERRUPTS()                   vPortSetBASEPRI( 0 )

  三、代码编写

3.1修改Task1的任务函数内容

        Task1实现5S关中断,5S开中断。

//任务1,实现5S关中断,5S开中断
void task1(void *pvParameters)
{
	uint8_t task1_num = 0;
	while(1)
	{
			if(++task1_num == 5)
			{
					task1_num = 0;
					portDISABLE_INTERRUPTS();
					printf("关中断\r\n");
					delay_ms(5000);
					portENABLE_INTERRUPTS();
					printf("开中断\r\n");
					delay_ms(5000);
			}
			vTaskDelay(100);
	}
}

四、实验现象

        系统复位后,实现5S关中断,5S开中断。关闭中断时,被FreeRTOS管理的优先级为6的定时器6停止工作,而优先级为4的定时器7不受影响。


网站公告

今日签到

点亮在社区的每一天
去签到