主页 > 手机  > 

STM32---FreeRTOS中断管理试验

STM32---FreeRTOS中断管理试验
一、实验

实验目的:学会使用FreeRTOS的中断管理

创建两个定时器,一个优先级为4,另一个优先级为6;注意:系统所管理的优先级范围 :5~15

现象:两个定时器每1s,打印一段字符串,当关中断时,停止打印,开中断时持续打印。 

实验设计:创建两个任务:start_task、task1

2个任务的功能如下:

start_task:用于创建task1任务

task1:中断测试任务,任务中将调到用关中断和开中断函数来体现对中断的管理。

代码:

main.c

#include "stm32f10x.h" #include "FreeRTOS.h" #include "task.h" #include "freertos_demo.h" #include "Delay.h" #include "sys.h" #include "usart.h" #include "Timer.h" #include "delay.h" int main(void) { uart_init(9600); Timer_Init(); delay_init(); // 创建任务 FrrrRTOS_Demo(); }

freertos_demo.c

#include "FreeRTOS.h" #include "task.h" #include "usart.h" #include "Timer.h" #include "delay.h" /******************************************************************任务配置****************************************************/ //任务优先级 #define START_TASK_PRIO 1 //任务堆栈大小 #define START_TASK_STACK_SIZE 64 //任务句柄 TaskHandle_t StartTask_Handler; //任务函数 void start_task(void *pvParameters); //任务优先级 #define TASK1_PRIO 2 //任务堆栈大小 #define TASK1_STACK_SIZE 64 //任务句柄 TaskHandle_t Task1_Handler; //任务函数 void task1(void *pvParameters); /******************************************************************任务函数****************************************************/ void FrrrRTOS_Demo(void) { //创建开始任务 xTaskCreate((TaskFunction_t )start_task, //任务函数 ( char* )"start_task", //任务名称 (uint16_t )START_TASK_STACK_SIZE, //任务堆栈大小 (void* )NULL, //传递给任务函数的参数 (UBaseType_t )START_TASK_PRIO, //任务优先级 (TaskHandle_t* )&StartTask_Handler); //任务句柄 // 启动任务调度 vTaskStartScheduler(); } void start_task(void *pvParameters) { taskENTER_CRITICAL(); //进入临界区 //创建LED0任务 xTaskCreate((TaskFunction_t )task1, (const char* )"task1", (uint16_t )TASK1_STACK_SIZE, (void* )NULL, (UBaseType_t )TASK1_PRIO, (TaskHandle_t* )&Task1_Handler); vTaskDelete(StartTask_Handler); //删除开始任务 taskEXIT_CRITICAL(); //退出临界区 } // 任务1函数 void task1(void *pvParameters) { uint8_t task1_num = 0; while(1) { if(++task1_num == 5) { task1_num = 0; printf("关中断\r\n"); portDISABLE_INTERRUPTS(); delay_xms(5000); //不可以使用vTaskDelay()函数:因为此函数会在内部开启中断引起任务切换 printf("开中断\r\n"); portENABLE_INTERRUPTS(); } vTaskDelay(1000); } }

Timer.c

#include "stm32f10x.h" // Device header #include "usart.h" void Timer_Init(void) { //RCC打开时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //选择时基单元的时钟,内部时钟一般默认初始化可以写可以不写 TIM_InternalClockConfig(TIM2); TIM_InternalClockConfig(TIM3); //配置时基单元 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure; //TIM_CKD_DIV1代表1分屏 TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; //代表向上计数 TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInitStructure.TIM_Period = 10000 - 1; //72MHZ分频7200,就是10k,10k计10000个数就是1s TIM_TimeBaseInitStructure.TIM_Prescaler = 7200 - 1; //高级定时器才有,现在是通用定时器给0 TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStructure); TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure); //如果不加入这一句,会导致复位之后从1开始计数 TIM_ClearFlag(TIM2, TIM_FLAG_Update); TIM_ClearFlag(TIM3, TIM_FLAG_Update); //TIM_IT_Update代表更新中断,中断控制,用来控制某个中断能不能通往NIVC TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStructure); NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 15; //新版RTOS可管理的NVIC中断:11~15 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_Init(&NVIC_InitStructure); //启动定时器 TIM_Cmd(TIM2, ENABLE); TIM_Cmd(TIM3, ENABLE); } void TIM2_IRQHandler(void) { if (TIM_GetITStatus(TIM2, TIM_IT_Update) == SET) { printf("优先级4\r\n"); TIM_ClearITPendingBit(TIM2, TIM_IT_Update); } } void TIM3_IRQHandler(void) { if (TIM_GetITStatus(TIM3, TIM_IT_Update) == SET) { printf("优先级15\r\n"); TIM_ClearITPendingBit(TIM3, TIM_IT_Update); } } 二、实验现象

三、重点 

开中断和关中断函数:

portDISABLE_INTERRUPTS(); //关中断 portENABLE_INTERRUPTS(); //开中断

关中断之后不能使用vTaskDelay()函数,此函数中会打开中断。(Delay函数不能使用的可以找找我的文章,有专门修改后适用于FreeRTOS操作系统的延迟函数)

FreeRTOS可管理的中断优先级,版本不一样,可管理的优先级就不一样;

是由FreeRTOSConfig.h文件里面的宏决定:

#define configKERNEL_INTERRUPT_PRIORITY 255  // 内核中断优先级(最低优先级) #define configMAX_SYSCALL_INTERRUPT_PRIORITY 191  

// 允许调用 FreeRTOS API 的最高中断优先级(优先级 11)

//可管理的中断优先级:11 到 15

 适用于STM32F103C8T6项目带注释完整的FreeRTOSConfig.h文件:

/* * FreeRTOS V202212.01 * Copyright (C) 2020 Amazon , Inc. or its affiliates. All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy of * this software and associated documentation files (the "Software"), to deal in * the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * * .FreeRTOS.org * github /FreeRTOS * */ #ifndef FREERTOS_CONFIG_H #define FREERTOS_CONFIG_H // 如果需要支持操作系统,可以取消注释以下宏定义 //#define SYSTEM_SUPPORT_OS 1 /*----------------------------------------------------------- * 应用程序特定的定义。 * * 这些定义应根据您的硬件和应用程序需求进行调整。 * * 这些参数在 FreeRTOS API 文档的“配置”部分中有详细描述, * 文档可在 FreeRTOS.org 网站上找到。 * * 参见 http:// .freertos.org/a00110.html *----------------------------------------------------------*/ // 将 FreeRTOS 的中断处理函数映射到 CMSIS 标准的中断处理函数 #define xPortPendSVHandler PendSV_Handler // PendSV 中断处理函数 //#define xPortSysTickHandler SysTick_Handler // SysTick 中断处理函数(注释掉,使用自定义的 SysTick_Handler) #define vPortSVCHandler SVC_Handler // SVC 中断处理函数 // 启用获取当前任务句柄的 API #define INCLUDE_xTaskGetCurrentTaskHandle 1 /*-------------------------------- FreeRTOS 内核配置 --------------------------------*/ #define configUSE_PREEMPTION 1 // 启用抢占式调度 #define configUSE_IDLE_HOOK 0 // 禁用空闲任务钩子函数 #define configUSE_TICK_HOOK 0 // 禁用时钟节拍钩子函数 #define configCPU_CLOCK_HZ ( ( unsigned long ) 72000000 ) // CPU 时钟频率,72MHz #define configTICK_RATE_HZ ( ( TickType_t ) 1000 ) // 系统节拍频率,1000Hz(1ms 一个节拍) #define configMAX_PRIORITIES ( 5 ) // 最大任务优先级数 #define configMINIMAL_STACK_SIZE ( ( unsigned short ) 128 ) // 空闲任务的最小堆栈大小 #define configTOTAL_HEAP_SIZE ( ( size_t ) ( 17 * 1024 ) ) // 系统堆的总大小,17KB #define configMAX_TASK_NAME_LEN ( 16 ) // 任务名称的最大长度 #define configUSE_TRACE_FACILITY 0 // 禁用可视化跟踪调试功能 #define configUSE_16_BIT_TICKS 0 // 使用 32 位 Tick 计数器 #define configIDLE_SHOULD_YIELD 1 // 空闲任务在有同等优先级的用户任务时主动让出 CPU /*-------------------------------- FreeRTOS API 包含配置 --------------------------------*/ // 以下宏定义用于控制是否包含特定的 FreeRTOS API 函数 #define INCLUDE_vTaskPrioritySet 1 // 包含任务优先级设置函数 #define INCLUDE_uxTaskPriorityGet 1 // 包含获取任务优先级函数 #define INCLUDE_vTaskDelete 1 // 包含任务删除函数 #define INCLUDE_vTaskCleanUpResources 0 // 不包含任务资源清理函数 #define INCLUDE_vTaskSuspend 1 // 包含任务挂起函数 #define INCLUDE_vTaskDelayUntil 1 // 包含绝对延时函数 #define INCLUDE_vTaskDelay 1 // 包含相对延时函数 #define INCLUDE_vTaskResumeFromISR 1 // 包含从中断恢复任务函数 #define INCLUDE_xTaskGetSchedulerState 1 // 包含获取调度器状态函数 /*-------------------------------- 中断优先级配置 --------------------------------*/ /*-------------------------------- 可管理的中断优先级:11 到 15(对应 NVIC 优先级 191 到 255) --------------------------------*/ // Cortex-M3/M4 的 NVIC 中断优先级配置 #define configKERNEL_INTERRUPT_PRIORITY 255 // 内核中断优先级(最低优先级) // configMAX_SYSCALL_INTERRUPT_PRIORITY 不能设置为 0 // 参见 http:// .FreeRTOS.org/RTOS-Cortex-M3-M4.html #define configMAX_SYSCALL_INTERRUPT_PRIORITY 191 // 允许调用 FreeRTOS API 的最高中断优先级(优先级 11) // STM32 库使用的中断优先级范围是 0-15,15 对应最低优先级 255 #define configLIBRARY_KERNEL_INTERRUPT_PRIORITY 15 // 内核中断优先级(最低优先级) #endif /* FREERTOS_CONFIG_H */

标签:

STM32---FreeRTOS中断管理试验由讯客互联手机栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“STM32---FreeRTOS中断管理试验