Darren_pty

导航

6-FreeRTOS开关中断函数测试

注意事项:

 ①临界区、中断服务函数、开关中断中不能使用vTaskDelay

 

 

 

需求:

①开启定时器TIM6和TIM7,两个定时器每隔1s串口打印一次

②设置TIM6中断优先级为4,TIM7中断优先级为5

③设置FreeRTOS系统可管理的最高中断优先级为5,#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5       //自由设置  系统可管理的最高中断优先级, 高于 5 的优先级(优先级数小于 5)不归 FreeRTOS 管理!

 

这样的话,TIM6不归FreeRTOS管理,在关闭中断时,低于优先级5的都会被关闭,高于或者等于优先级5的都会被关闭。

 

代码:

①定时器实现:

  1 //1/(72 000 000÷psc)×arr~5ms
  2 void TIM6_Time_Init(u16 arr,u16 psc)//如arr=49 psc=7199 ---10khz(0.1ms)--5ms
  3 {
  4     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  5     NVIC_InitTypeDef         NVIC_InitStructure;
  6     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6,ENABLE); //72M
  7         
  8         
  9     NVIC_InitStructure.NVIC_IRQChannel =TIM6_IRQn;  
 10     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 4;  //抢占优先级
 11     NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;  //响应优先级
 12     NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE; 
 13     NVIC_Init(&NVIC_InitStructure);
 14     
 15     TIM_TimeBaseStructure. TIM_Period = arr;//自动重装值
 16     TIM_TimeBaseStructure.TIM_Prescaler =psc; //时钟预分频数
 17     TIM_TimeBaseInit(TIM6,&TIM_TimeBaseStructure); //初始化TIM6
 18     TIM_ClearFlag(TIM6,TIM_FLAG_Update); //清除计数器中断标志位
 19     
 20     TIM_ITConfig(TIM6,TIM_IT_Update, ENABLE );//TIM中断使能
 21   TIM_Cmd(TIM6, ENABLE); //使能定时器
 22 }
 23 
 24 
 25 void TIM7_Time_Init(u16 arr,u16 psc)//如arr=49 psc=7199 ---10khz(0.1ms)--5ms
 26 {
 27     NVIC_InitTypeDef         NVIC_InitStructure;
 28     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
 29     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM7,ENABLE); //72M
 30 
 31     NVIC_InitStructure.NVIC_IRQChannel =TIM7_IRQn;  
 32     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 5;  //抢占优先级
 33     NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;  //响应优先级
 34     NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE; 
 35     NVIC_Init(&NVIC_InitStructure);
 36     
 37     TIM_TimeBaseStructure. TIM_Period = arr;//自动重装值
 38     TIM_TimeBaseStructure.TIM_Prescaler =psc; //时钟预分频数
 39     TIM_TimeBaseInit(TIM7,&TIM_TimeBaseStructure); //初始化TIM6
 40     TIM_ClearFlag(TIM7,TIM_FLAG_Update); //清除计数器中断标志位
 41     
 42     TIM_ITConfig(TIM7,TIM_IT_Update, ENABLE );//TIM中断使能
 43   TIM_Cmd(TIM7, ENABLE); //使能定时器
 44 }
 45 
 46 
 47 //10ms     100Hz
 48 void TIM1_Configuration(void)
 49 {
 50     TIM_TimeBaseInitTypeDef  TIM1_TimeBaseStructure;
 51     TIM_OCInitTypeDef        TIM1_OCInitStructure;
 52 
 53     TIM_DeInit(TIM1);
 54     GPIO_PinRemapConfig(GPIO_FullRemap_TIM1,ENABLE);
 55     RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1|RCC_APB2Periph_AFIO, ENABLE);
 56 
 57     TIM1_TimeBaseStructure.TIM_Prescaler = 4000-1;
 58     TIM1_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数
 59     TIM1_TimeBaseStructure.TIM_Period = 180-1;//周期10ms
 60     TIM1_TimeBaseStructure.TIM_ClockDivision = 0x00;  //设置时钟分割
 61     TIM1_TimeBaseStructure.TIM_RepetitionCounter = 0x00;//周期计数值
 62     TIM_TimeBaseInit(TIM1,&TIM1_TimeBaseStructure);//初始化TIM1的时间基数单位
 63 
 64 
 65     TIM1_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;//PWM模式2
 66     TIM1_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;//正向通道有效 PE9 完全重映像
 67     TIM1_OCInitStructure.TIM_OutputNState = TIM_OutputState_Enable;//反向通道也有效
 68     TIM1_OCInitStructure.TIM_Pulse = 18-1;//占空比时间  180中有18的时间为低,互补的输出正好相反  即:占空比10%
 69     TIM1_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;   //输出极性
 70     TIM1_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;//互补输出极性
 71     TIM1_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
 72     TIM1_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
 73     TIM_OC1Init(TIM1,&TIM1_OCInitStructure); 
 74     
 75     TIM_ARRPreloadConfig(TIM4,ENABLE);                                //使能TIM4的寄存器ARR的预装载功能,DISABLE时将会使改变ARR值时立即生效
 76     TIM_OC4PreloadConfig(TIM4,TIM_OCPreload_Enable);                //使能TIM4通道1的CCR的预装载功能,DISABLE时将会使改变CRR值时立即生效
 77 
 78 
 79     TIM_Cmd(TIM1,ENABLE);  //TIM1 counter enable        
 80     TIM_CtrlPWMOutputs(TIM1,ENABLE);  //TIM1 main Output Enable  高级定时器一定要开启这个   开启PWM才能输出
 81 }
 82 
 83 
 84 
 85 void TIM6_IRQHandler(void)   
 86 {
 87     
 88   if(TIM_GetITStatus(TIM6, TIM_IT_Update)) //是否产生中断
 89    {  
 90 
 91          printf("TIM6中断\r\n");
 92          TIM_ClearITPendingBit(TIM6,TIM_IT_Update);//清除中断标志位
 93    }
 94 }
 95 
 96 
 97 void TIM7_IRQHandler(void)
 98 {
 99   if(TIM_GetITStatus(TIM7, TIM_IT_Update)) //是否产生中断
100    {  
101          printf("TIM7中断\r\n");
102          TIM_ClearITPendingBit(TIM7,TIM_IT_Update);//清除中断标志位
103    }
104     
105 }

②任务创建

 1 //----------------------------------------任务优先级
 2  #define START_TASK_PRIO     1 
 3  #define KEY_TASK_PRIO       2
 4  #define TASK1_PRIO          3 
 5  #define TASK2_PRIO          4 //优先级高
 6  
 7  
 8  //----------------------------------------任务堆栈大小
 9  #define START_STK_SIZE 128 
10  #define TASK1_STK_SIZE 128 
11  #define TASK2_STK_SIZE 128 
12  #define KEY_STK_SIZE   128 
13  
14  //----------------------------------------任务句柄
15  TaskHandle_t Task1_Handler; 
16  TaskHandle_t Task2_Handler; 
17  TaskHandle_t StartTask_Handler; 
18  TaskHandle_t KeyTask_Handler; //任务句柄
19  
20  
21  //----------------------------------------任务函数
22  void start_task(void *pvParameters); 
23  void task1_task(void *pvParameters); 
24  void task2_task(void *pvParameters); 
25  void key_task(void *pvParameters); //任务函数
26 
27  
28  int main(void)
29  {
30    BaseType_t OS;
31    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);  
32    User_GPIO_Init();
33 //     Exit_Init();
34      Delay_init();
35      USART_Config();
36      
37    TIM6_Time_Init(9999,7199);//定时1s
38    TIM7_Time_Init(9999,7199);//定时1s
39  
40      
41      OS= xTaskCreate(
42                                             (TaskFunction_t        ) start_task,       //任务函数
43                                             (const char *          )  "start_task",    //任务名
44                                             (configSTACK_DEPTH_TYPE) START_STK_SIZE,   //堆栈大小
45                                             (void *                )NULL,              //传递给任务函数的参数
46                                             (UBaseType_t           ) START_TASK_PRIO,  //任务优先级
47                                             (TaskHandle_t *        ) &StartTask_Handler  //任务句柄
48                     );
49                                   
50      if(OS==pdPASS) 
51          GPIO_SetBits(GPIOA, GPIO_Pin_8);
52          
53      vTaskStartScheduler(); //开启任务调度
54      
55  }
56  
57  
58  void start_task(void *pvParameters)
59  {
60   
61          taskENTER_CRITICAL(); //进入临界区
62          
63        //创建任务Task1
64 xTaskCreate((TaskFunction_t )task1_task, //任务函数
65          (const char* )"task1_task", //任务名称
66          (uint16_t )TASK1_STK_SIZE, //任务堆栈大小
67          (void* )NULL,
68          (UBaseType_t )TASK1_PRIO, //任务优先级
69          (TaskHandle_t* )&Task1_Handler); //任务句柄
70  
71            
72                  
73          vTaskDelete(StartTask_Handler); //vTaskDelete(NULL)也可以   删除开始任务
74          taskEXIT_CRITICAL();            //退出临界区
75  }
76  
77  
78  //任务1
79  void task1_task(void *pvParameters)
80  {  
81      uint8_t count_num=0; 
82      while(1)
83      {
84        count_num++;
85              
86       if(count_num==5) 
87             {
88                 printf("关闭中断.............\r\n");
89                 portDISABLE_INTERRUPTS(); //关闭中断 
90                 delay_xms(5000); //延时 5s 
91                 printf("打开中断.............\r\n"); //打开中断
92                 portENABLE_INTERRUPTS(); //退出中断
93             }
94 
95        vTaskDelay(1000);  //延时1000个时钟节拍,就是1s   configTICK_RATE_HZ
96      }
97          
98  }

 

执行结果:

 

posted on 2020-12-20 18:52  Darren_pty  阅读(326)  评论(0编辑  收藏  举报