)
目录1 中断1.1 什么是中断1.2 特点1.3 中断三要素1.4 中断流程2 NVIC中断系统2.1 NVIC配置2.1.1 抢占优先级和响应优先级2.1.2 中断优先级分组2.1.3 程序示例3 EXTI外部中断/事件控制器3.1 中断/事件线3.2 EXTI配置的完整流程以按键触发中断为例1 中断1.1 什么是中断中断 是 CPU 在执行程序过程中由于发生了某个需要立即处理的事件暂时停止当前程序转而去执行一个专门的中断服务函数处理完后再回来继续执行原来的程序。也可以将一个程序的中断理解成主程序睡觉中断事件闹钟响了中断服务函数打开手机关闭闹钟返回主程序继续睡觉。1.2 特点中断具有异步性、优先性、可嵌套和实时性等特点异步性中断发生的时间是“随机”的不可预测。优先性当有多个中断同时发生时优先级高的先进行处理。可嵌套在处理中断任务1时可以被优先级更高的中断2打断并执行中断任务2。实时性紧急事件配置中断后可以通过中断及时响应。1.3 中断三要素中断源、中断向量、中断优先级中断源谁触发了中断是按键按下还是定时器溢出也可以理解为手机响了是有人打电话还是闹钟响了中断向量中断函数的入口地址如EXTI0_IRQHandler、USART1_IRQHandler。也可以理解成是电话还是闹钟程序中断优先级决定哪个中断先处理在STM32中数值越小优先级越高。1.4 中断流程当主程序正在正常运行时中断事件发生如按键按下、定时器溢出中断源NVIC向CPU提交中断向量地址运行中断服务函数处理事件处理完成后返回主程序。2 NVIC中断系统NVIC嵌套向量中断控制器任何已使能中断功能的外设在其内部事件发生时会向NVIC输出一个中断请求信号。NVIC会持续检测所有活动的中断请求当检测到多个请求时其内部的优先级仲裁单元会根据可编程的优先级配置裁决出当前优先级最高的中断。随后NVIC会向CPU内核提交该中断的向量地址完成中断请求的响应和授权。也就是说只要需要使用中断就必须通过NVIC在程序设计时必须对NVIC进行配置。2.1 NVIC配置2.1.1 抢占优先级和响应优先级管理中断执行顺序的关键。它们共同决定了中断是否可以嵌套和同优先级中断的执行顺序。抢占优先级决定一个中断能否打断正在执行的另一个中断。数值越小优先级越高。高抢占优先级的中断可以嵌套低抢占优先级的中断。响应优先级在抢占优先级相同的前提下决定多个同时到达的中断的执行顺序。数值越小优先级越高。它不能引发中断嵌套只是用于排序。可以理解为多个中断请求在优先级判定中首先比较抢占优先级数值越小就优先执行数值相同则比较响应优先级数值越小则优先执行如果抢占优先级相同和响应优先级也相同则根据请求的先后顺序进行执行优先请求优先执行。例事件A抢占优先级2响应优先级2事件B抢占优先级2响应优先级2事件C抢占优先级2响应优先级1事件D抢占优先级1响应优先级3当事件A、B都向NVIC输出中断请求信号两事件抢占优先级和响应优先级都相等如果事件A早于事件B请求则先处理事件A如果事件B早于事件A请求则先处理事件B;当事件A、C都向NVIC输出中断请求信号则先比较抢占优先级22优先级相同再比较响应优先级21事件C响应优先级小于事件A事件C优先执行。当事件A、D都向NVIC输出中断请求信号则先比较抢占优先级21事件D响应优先级小于事件A事件D优先执行。当事件A正在执行此时事件D向NVIC输出中断请求比较抢占优先级21事件D抢占优先级小于事件A此时打断正在执行的事件A开始执行抢占优先级更高的事件D等待事件D执行完再回到事件A中继续执行。2.1.2 中断优先级分组在STM32中中断优先级分组被分为5个组而每个组对应抢占优先级和响应优先级取值范围可根据实际进行分组每个工程只需进行一次分组即可。分组时直接调用NVIC_PriorityGroupConfig();函数实现。2.1.3 程序示例/*配置NVIC中断分组为NVIC_PriorityGroup_2*/ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /*定义一个NVIC初始化结构体变量用于存储中断配置参数*/ NVIC_InitTypeDef NVIC_InitStructure; /*指定要配置的中断通道(这里的“XXX_IRQn”需自行配置)*/ NVIC_InitStructure.NVIC_IRQChannel XXX_IRQn; /*使能XXX_IRQn通道*/ NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; /*设置抢占优先级为2*/ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 2; /*设置响应优先级为1*/ NVIC_InitStructure.NVIC_IRQChannelSubPriority 1; /*调用NVIC初始化函数将上面设置的结构体参数写入硬件寄存器*/ NVIC_Init(NVIC_InitStructure);3 EXTI外部中断/事件控制器管理STM32的中断/事件线每个中断/事件线都对应一个边沿检测器。EXTI核心作用是将GPIO引脚的外部信号变化如按键按下转换为中断。图片截至官方文档3.1 中断/事件线EXTI有20个中断/事件线每个GPIO都可以被设置为输入线GPIO占用EXTI0-15EXTI16-19由其他外设触发。3.2 EXTI配置的完整流程以按键触发中断为例该示例同“STM32/重映射和AFIO复用功能”一致void Key_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; EXTI_InitTypeDef EXTI_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; /*步骤一使能GPIOA和AFIO时钟EXTI必须使能AFIO*/ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); /*步骤二配置PA1为上拉输入模式*/ GPIO_InitStructure.GPIO_Mode GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Pin GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); /*步骤三将PA1映射到EXTI线1*/ GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource1); /*步骤四配置EXTI */ /*选择EXTIX线1 */ EXTI_InitStructure.EXTI_Line EXTI_Line1; /*中断模式*/ EXTI_InitStructure.EXTI_Mode EXTI_Mode_Interrupt; /*下降沿触发*/ EXTI_InitStructure.EXTI_Trigger EXTI_Trigger_Falling; /*使能*/ EXTI_InitStructure.EXTI_LineCmd ENABLE; /*调用EXTI初始化函数将上面设置的结构体参数写入EXTI寄存器*/ EXTI_Init(EXTI_InitStructure); /*步骤五配置NVIC*/ NVIC_InitStructure.NVIC_IRQChannel EXTI1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 2; NVIC_InitStructure.NVIC_IRQChannelSubPriority 2; NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; NVIC_Init(NVIC_InitStructure); } /*步骤六编写中断服务函数*/ void EXTI1_IRQHandler(void) { KEY_STA 1; //标志位用于外部判断按键是否按下 EXTI_ClearITPendingBit(EXTI_Line1); }注以上内容适用于STM32F10xx系列仅供参考。注以上内容仅个人理解不具备唯一性和绝对正确性仅供参考。