FreeRTOS中断测试实验

描述

FreeRTOS 中断测试实验

设定: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 恢复运行,蓝框所示部分。

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分