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 阅读(333) 评论(0) 编辑 收藏 举报