完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
当多个中断来临的时候处理器应该响应哪--个中断是由中断的优先级来决定的,高优先级的中断(优先级编号小)肯定是首先得到响应,而且高优先级的中断可以抢占低优先级的中断,这个就是中断嵌套。Cortex-M 处理器的有些中断是具有固定的优先级的,比如复位、NMI、HardFault,这些中断的优先级都是负数,优先级也是最高的。
Cortex-M处理器有三个固定优先级和256个可编程的优先级,最多有128 个抢占等级,但是实际的优先级数量是由芯片厂商来决定的。但是,绝大多数的芯片都会精简设计的,以致实.际上支持的优先级数会更少,如8级、16级、32级等,比如STM32就只有16级优先级。在设计芯,片的时候会裁掉表达优先级的几个低端有效位,以减少优先级数,所以不管用多少位来表达优先级,都是MSB对齐的,如图4.1.3.1 就是使用三位来表达优先级。 在图4.1.3.1中, Bit0~Bit4没有实现,所以读它们总是返回零,写如它们的话则会忽略写入的值。因此,对于3个位的情况,可是使用的优先级就是8个:0X00(最高优先级)、0X20、0X40、0X60、0X80、0XA0、0XC0和0XE0。注意,这个是芯片厂商来决定的!不是我们能决定的,比如STM32就选择了4位作为优先级! 有读者可能就会问,优先级配置寄存器是8位宽的,为什么却只有128个抢占等级8位不应该是256个抢占等级吗?为了使抢占机能变得更可控,Cortex-M处理器还把256个优先级按位分为高低两段:抢占优先级(分组优先级)和亚优先级(子优先级),NVIC 中有一个寄存器是.“应用程序中断及复位控制寄存器(AIRCR)”,AIRCR寄存器里面有个位段名为“优先级组”, 如表4.1.3.1所示: 软件实现: #include "sys.h" #include "delay.h" #include "usart.h" #include "led.h" #include "FreeRTOS.h" #include "task.h" #include "key.h" #include "timer.h" #define TASK_START_SIZE 120 #define TASK_START_PAR 1 TaskHandle_t TaskStartHandle; void task_start(void * pvParameters); #define LED_TASK_SIZE 120 #define LED_TASK_PAR 3 TaskHandle_t LedTaskHandle; void led_task(void * pvParameters); #define KEY_TASK_SIZE 120 #define KEY_TASK_PAR 2 TaskHandle_t KeyTaskHandle; void key_task(void * pvParameters); #define INT_TASK_SIZE 120 #define INT_TASK_PAR 2 TaskHandle_t IntTaskHandle; void interrupt_task(void * pvParameters); int main(void) { Cache_Enable(); //打开L1-Cache HAL_Init(); //初始化HAL库 Stm32_Clock_Init(432,25,2,9); //设置时钟,216Mhz delay_init(216); //延时初始化 uart_init(115200); //串口初始化 LED_Init(); //初始化LED KeyGpioInit(); //按键初始化 TIME3_Init(10000, 10800); TIME5_Init(10000, 10800); xTaskCreate((TaskFunction_t) task_start, //创建任务 (char *) "task_start", //任务名字 (uint16_t) TASK_START_SIZE, //任务内存大小 (void *) NULL, //指针任务函数中的参数 (UBaseType_t) TASK_START_PAR, //任务优先级 (TaskHandle_t *) &TaskStartHandle); //任务设置句柄 vTaskStartScheduler(); //开启任务调度 } #if 1 //RTOS中断开启关闭实验 void task_start(void * pvParameters) { xTaskCreate((TaskFunction_t) interrupt_task, //创建任务 (char *) "interrupt_task", //任务名字 (uint16_t) INT_TASK_SIZE, //任务内存大小 (void *) NULL, //指针任务函数中的参数 (UBaseType_t) INT_TASK_PAR, //任务优先级 (TaskHandle_t *) &IntTaskHandle); //任务设置句柄 vTaskDelete(TaskStartHandle); //任务删除,如果是删除自身可以用NULL // vTaskDelete(NULL); } void interrupt_task(void * pvParameters) { static u32 total_num=0; while(1) { total_num+=1; if(total_num==5) { printf("关闭中断.............rn"); portDISABLE_INTERRUPTS(); //关闭中断 delay_xms(5000); //延时5s printf("打开中断.............rn"); //打开中断 portENABLE_INTERRUPTS(); total_num = 0; } LED0_Toggle; vTaskDelay(1000); } } 显示结果: |
|
|
|
只有小组成员才能发言,加入小组>>
3314 浏览 9 评论
2995 浏览 16 评论
3494 浏览 1 评论
9059 浏览 16 评论
4088 浏览 18 评论
1179浏览 3评论
605浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
599浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2335浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1896浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 15:36 , Processed in 1.544071 second(s), Total 81, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号