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  }

    执行结果:

  • 相关阅读:
    关于Maya Viewport 2.0 API 开发的介绍视频
    春节大假
    Some tips about the life cycle of Maya thread pool
    Can I compile and run Dx11Shader for Maya 2015 on my side?
    How to get current deformed vertex positions in MoBu?
    想加入全球首届的 欧特克云加速计划吗?
    三本毕业(非科班),四次阿里巴巴面试,终拿 offer(大厂面经)
    mac、window版编辑器 webstorm 2016... 永久破解方法。
    node 搭载本地代理,处理web本地开发跨域问题
    js 一维数组,转成嵌套数组
  • 原文地址:https://www.cnblogs.com/darren-pty/p/14164530.html
Copyright © 2011-2022 走看看