设定:FreeRTOS 中优先级低于 configMAX_SYSCALL_INTERRUPT_PRIORITY的中断会被屏蔽掉,高于的就不会,那么我们就写个简单的例程测试一下。
使用两个定时器,一个优先级为 4,一个优先级为 5,两个定时器每隔 1s 通过串口输出一串字符串。然后在某个任务中关闭中断一段时间,查看两个定时器的输出情况。
main.c
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "FreeRTOS.h"
#include "task.h"
#define START_TASK_PRIO 1
#define START_STK_SIZE 256
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);
#define INTERRUPT_TASK_PRIO 2
#define INTERRUPT_STK_SIZE 256
TaskHandle_t INTERRUPTTask_Handler;
void interrupt_task(void *p_arg);
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
delay_init();
uart_init(115200);
LED_Init();
//起了两个定时器,不停的打印,除非中断被关闭
TIM3_Int_Init(10000-1,7200-1);
TIM5_Int_Init(10000-1,7200-1);
xTaskCreate((TaskFunction_t )start_task,
(const char* )"start_task",
(uint16_t )START_STK_SIZE,
(void* )NULL,
(UBaseType_t )START_TASK_PRIO,
(TaskHandle_t* )&StartTask_Handler);
vTaskStartScheduler();
}
void start_task(void *pvParameters)
{
taskENTER_CRITICAL();
xTaskCreate((TaskFunction_t )interrupt_task,
(const char* )"interrupt_task",
(uint16_t )INTERRUPT_STK_SIZE,
(void* )NULL,
(UBaseType_t )INTERRUPT_TASK_PRIO,
(TaskHandle_t* )&INTERRUPTTask_Handler);
vTaskDelete(StartTask_Handler);
taskEXIT_CRITICAL();
}
void interrupt_task(void *pvParameters)
{
static u32 total_num=0;
while(1)
{
printf("秒数",total_num);
total_num+=1;
if(total_num==5)
{
printf("关闭中断.............rn");
portDISABLE_INTERRUPTS();
delay_xms(5000);
printf("打开中断.............rn");
portENABLE_INTERRUPTS();
}
LED0=~LED0;
vTaskDelay(1000);
}
}
timer.c
#include "timer.h"
#include "led.h"
#include "led.h"
#include "usart.h"
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM3, ENABLE);
}
void TIM5_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
TIM_TimeBaseStructure.TIM_Period = arr;
TIM_TimeBaseStructure.TIM_Prescaler =psc;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStructure);
TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE );
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_Cmd(TIM5, ENABLE);
}
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
{
printf("TIM3输出.......rn");
}
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
void TIM5_IRQHandler(void)
{
if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET)
{
printf("TIM5输出.......rn");
}
TIM_ClearITPendingBit(TIM5,TIM_IT_Update);
}
另外还有一些延时函数和串口初始化,这个都是基础的文件,可以直接copy的,就不放出来了。
编译并下载代码到开发板中,打开串口调试助手查看数据输出:
一开始没有关闭中断,所以 TIM3 和 TIM5 都正常运行,红框所示部分。当任务 interrupt_task()运行了 5 次以后就关闭了中断,此时由于 TIM5 的中断优先级为 5,等于configMAX_SYSCALL_INTERRUPT_PRIORITY,因此 TIM5 被关闭。但是,TIM3 的中断优先级高于 configMAX_SYSCALL_INTERRUPT_PRIORITY,不会被关闭,所以 TIM3 正常运行,绿框所示部分。中断关闭 5S 以后就会调用函数 portENABLE_INTERRUPTS()重新打开中断,重新打开中断以后 TIM5 恢复运行,蓝框所示部分。
全部0条评论
快来发表一下你的评论吧 !