STM32外部中断 中断优先级讲解及配置

文章详细阐述了微控制器中的中断概念,包括中断的执行过程、中断服务函数的注意事项、中断的相关专业术语如中断源、中断优先级等。特别讨论了STM32中的中断分类和优先级管理,强调了中断的使能和EXTI中断配置。此外,还介绍了中断优先级的抢占和响应优先级机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.概念

对于几乎所有的微控制器,中断都是一种常见的特性。中断一般是由硬件(如外设和外部输入引脚)产生的事件,它会引起程序流偏离正常的流程(如给外设提供服务),转去执行其他的流程。

CPU在正常执行程序的过程中,由于内部/外部事件的触发或程序的预先安排引起CPU暂停当前正在运行的程序,而转去执行中断服务子程序,待中断服务子程序执行完毕后,CPU继续执行原来的程序,这一过程称为中断;

2.中断执行过程

 图1 中断执行过程说明

1、外设发出中断请求

2、处理器暂停当前执行的任务,保护现场(拓展:CPU内部有R0-R15寄存器,中断发生时会保存里边的值),将当前位置的PC地址压栈;

3、程序跳转到中断服务程序,执行中断服务程序;

4、恢复现场,将栈顶的值回送给PC;

5、跳转到被中断的位置开始执行下一个指令

中断服务函数:相对于正常子函数,中断服务函数有以下需要注意的地方:

1、中断服务函数不能传入参数;

2、中断服务函数不能有返回值;

3、中断服务函数应该做到短小精悍,快入快出,禁止延时性的过程。

4、不要在中断函数中使用printf函数,会带来重入和性能问题,不要出现浮点运算。

       printf是一个无法重入的函数:

   中断重入:就是在一个中断程序执行过程中又被另一个中断打断,转而又去执行另一个中断程序。

3.中断的部分专业术语

中断源:引起中断的原因,或者能够发出中断请求信号的来源统称为中断源

中断优先级:中断同时到来,谁先执行。数字越小,优先级越高。

中断响应:中断事件发生,Cortex-M3内核准备执行该事件,即为中断响应。

中断嵌套:可嵌套的内核   -- 中断可以被其他中断打断。(Cortex-M)

不可嵌套的内核 -- 不可以打断。

中断挂起:中断事件发生了,但是Cortex-M内核还没准备去执行。

中断服务函数: 中断发生后,要执行的程序。(固定格式

<think>好的,用户想了解STM32外部中断优先级与寄存器的相关配置。首先,我需要回忆一下STM32中断系统结构。STM32使用NVIC(嵌套向量中断控制器)来管理中断优先级,而外部中断属于其中的一部分。用户提到了寄存器的配置,这可能涉及到NVIC的IPR(中断优先级寄存器)以及EXTI(外部中断)相关的寄存器。 根据引用内容,STM32中断优先级由NVIC_IPR寄存器配置,而CM3内核支持256级优先级,但实际可能被精简为更少,比如8级或16级。同时,优先级的分组设置也很重要,这涉及到抢占优先级和子优先级的划分。例如,引用[2]提到优先级配置以MSB对齐,这可能影响如何设置优先级值。 接下来,外部中断的具体配置步骤需要结合GPIO和EXTI的设置。引用[4]指出,需要先使能GPIO和复用功能时钟,设置GPIO模式,然后配置EXTI的中断源和触发方式。之后,通过NVIC配置中断优先级,包括抢占和子优先级,并启用中断。 用户可能需要具体的寄存器操作步骤,比如如何设置EXTI_IMR(中断屏蔽寄存器)来使能外部中断线,EXTI_RTSR和EXTI_FTSR设置触发方式,以及如何通过NVIC_IPRx寄存器配置优先级。同时,优先级分组寄存器SCB->AIRCR也需要配置,以确定抢占和子优先级的位数。 另外,HAL库的使用简化了部分配置,如引用[3]提到,HAL库只需配置IO模式、中断源、优先级和使能中断。但用户可能想知道底层寄存器的操作,因此需要结合库函数和寄存器级别的说明。 需要注意的是,不同STM32型号可能有不同的中断映射,需要参考具体的数据手册。例如,外部中断线EXTI0到EXTI15对应的中断服务函数可能不同,配置时需确保正确映射到对应的GPIO引脚。 最后,用户可能需要了解如何验证中断配置的正确性,比如通过编写中断服务函数并测试触发情况。同时,常见问题如优先级冲突、中断使能未打开等也需要提及。</think>### STM32外部中断优先级与寄存器配置详解 #### 一、外部中断优先级配置原理 1. **优先级分组规则** STM32采用$4\text{bit}$表示中断优先级,通过`SCB->AIRCR`寄存器的`PRIGROUP`字段划分抢占优先级和子优先级: $$ \text{优先级} = \text{抢占优先级} \times 2^{(4-n)} + \text{子优先级} $$ 例如选择分组2时,$2\text{bit}$抢占优先级 + $2\text{bit}$子优先级[^2]。 2. **NVIC_IPR寄存器结构** 每个中断源对应$8\text{bit}$优先级字段(实际仅高4位有效): ```c NVIC->IP[x] = (抢占优先级 << (8 - n)) | (子优先级 << (8 - m)) // n+m=4 ``` #### 二、寄存器级配置步骤 1. **配置GPIO与复用功能** ```c RCC->APB2ENR |= 1 << 2; // 使能GPIOA时钟 GPIOA->CRL &= ~(0xF << 4); // 清空PA1配置 GPIOA->CRL |= 0x08 << 4; // 设置PA1为上拉输入(二进制1000) ``` 2. **配置EXTI中断源** ```c AFIO->EXTICR[0] |= 0x0000; // 选择PA1作为EXTI1源 EXTI->IMR |= 1 << 1; // 使能EXTI1中断屏蔽 EXTI->RTSR |= 1 << 1; // 设置上升沿触发 ``` 3. **配置NVIC优先级** ```c NVIC->IP[EXTI1_IRQn] = 0x70; // 优先级7(假设分组为0) NVIC->ISER[0] |= 1 << (EXTI1_IRQn & 0x1F); // 使能中断 ``` #### 三、HAL库配置示例 ```c GPIO_InitTypeDef GPIO_InitStruct = {0}; GPIO_InitStruct.Pin = GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; // 上升沿触发 GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); HAL_NVIC_SetPriority(EXTI1_IRQn, 1, 0); // 抢占1,子优先级0 HAL_NVIC_EnableIRQ(EXTI1_IRQn); ``` #### 四、验证与调试要点 1. 检查`SCB->AIRCR`寄存器是否已配置正确的优先级分组 2. 使用`__NVIC_GetPriorityGrouping()`读取当前分组 3. 通过调试器观察`NVIC->IP[]`寄存器的实际写入值 #### 五、典型问题解决方案 1. **中断无法触发** - 确认`AFIO`时钟已使能(`RCC->APB2ENR |= 1<<0`) - 检查`EXTI->IMR`对应位是否置1 2. **优先级冲突** - 使用`NVIC_GetPriority()`验证实际优先级值 - 确保不同中断的抢占优先级不全部相同
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值