zoukankan      html  css  js  c++  java
  • 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中断
    ");
     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中断
    ");
    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("关闭中断.............
    ");
    89                 portDISABLE_INTERRUPTS(); //关闭中断 
    90                 delay_xms(5000); //延时 5s 
    91                 printf("打开中断.............
    "); //打开中断
    92                 portENABLE_INTERRUPTS(); //退出中断
    93             }
    94 
    95        vTaskDelay(1000);  //延时1000个时钟节拍,就是1s   configTICK_RATE_HZ
    96      }
    97          
    98  }

    执行结果:

  • 相关阅读:
    go语言基础学习
    VBA汇总同目录下的所有工作簿数据到另一个工作簿,并进行统计
    彻底关闭win10后台同步数据(转自技术社区)
    在WIN10上安装ESXI-Comstomer (转自技术社区)
    squid代理允许FTP访问设置
    Powershell 脚本判断制定路径下文件是否存在(来源于网络-转载)
    Python集合(set)类型的操作 (转)
    python3.5.2中文字符乱码问题解决
    Debian 中文环境设置
    Python 列表推导实例
  • 原文地址:https://www.cnblogs.com/darren-pty/p/14164530.html
Copyright © 2011-2022 走看看