嵌入式——中断(NVIC)补充

本文详细介绍了STM32的中断机制,包括中断的定义与理解、异常类型(如系统异常和外部中断)、NVIC中断控制器的功能、中断优先级的配置、抢占优先级和子优先级的概念,以及中断服务函数的编写和管理。

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

目录

一、认识中断

1.理解

2.异常类型

3.NVIC简介

二、中断优先级

1.定义

2.优先级分组

3.中断服务函数


一、认识中断

1.理解

        STM32中断非常强大,每个外设都可以产生中断。异常就是中断,中断就是异常,二者相同。

2.异常类型

        F103在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断。其中系统异常有8个(如果把 Reset 和Hard Faut 也算上的话就是10个)。外部中断有60个除了个别异常的优先级被定死外,其他异常的优先级都是可编程的。有关具体的系统异常和外部中断可在标准库文件 stm32f10x.h头文件中查询到,在IRQn_Type这个结构体里面包含了 F103系列全部的异常声明。

3.NVIC简介

        NVIC是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。但是各个芯片厂商在设计芯片的时候会对 Cortex-M3 内核里面的NVIC 进行裁剪,把不需要的部分去掉,所以说STM32中的NVIC是 Cortex-M3的NVIC的一个子集。

        在固件库中,NVIC的结构体定义给每个寄存器都预留了很多位,为的是日后扩展功能。在配置中断的时候一般只用ISER、 ICER和IP这3个寄存器,ISER用来使能中断,ICER 用来清除中断,IP用来设置中断优先级

二、中断优先级

1.定义

        在NVIC中有一个专门的寄存器:中断优先级寄存器NVIC_IPRx,用来配置外部中断的优先级,IPR宽度为8位,原则上每个外部中断可配置的优先级为0~255数值越小,优先级越高。但是绝大多数CM3芯片都会精简设计,以致实际上支持的优先级数减少,在F103中,只使用了高4位。

        用于表达优先级的这4位,又被分成抢占优先级和子优先级两组。如果有多个中断同时响应,抢占优先级高的就会先于抢占优先级低的,优先得到执行,如果抢占优先级相同,就比较子优先级。如果抢占优先级和子优先级都相同的话,就比较它们的硬件中断编号,编号越小,优先级越高。

2.优先级分组

        优先级的分组由内核外设 SCB的应用程序中断及复位控制寄存器AIRCR的PRIGROUP[10:8]位决定。F103分为了5组(主优先级=抢占优先级)。

3.中断服务函数

        在启动文件 startup_stm32f10x_hd.s中,以预先为每个中断都写了一个中断服务函数,只是这些中断函数都为空,为的只是初始化中断向量表。实际的中断服务函数都需要我们重新编写,为了方便管理把中断服务函数统一写在stm32f10x_it.c这个库文件中

注意:中断服务函数的函数名必须与启动文件里面预先设置的一样,如果写错,系统就在中断向量表中找不到中断服务函数的入口,直接跳转到启动文件里面预先写好的空函数,并且在里面无限循环,实现不了中断。

更多内容请看:http://t.csdnimg.cn/tgrA3icon-default.png?t=N7T8http://t.csdnimg.cn/tgrA3

### 蓝桥杯嵌入式比赛中外部中断按键的学习 #### 外部中断简介 在嵌入式开发中,外部中断是一种常见的机制,用于响应来自硬件设备的事件。当特定条件满足时(例如按下按钮),微控制器会暂停当前执行的任务并处理该事件。 #### STM32中的外部中断配置 STM32系列单片机支持通过EXTI (External Interrupt Line) 来实现外部中断功能。每个GPIO引脚都可以被配置成触发一次或多次外部中断请求。为了使能某个IO口作为外部中断源,在初始化阶段需要完成以下设置: 1. **启用相应外设时钟** 需要开启对应端口以及SYSCFG模块的RCC时钟。 2. **配置GPIO模式** 将目标管脚设定为输入模式,并根据需求选择上拉、下拉电阻状态。 3. **映射到指定线路上** 使用`SYSCFG_EXTILineConfig()`函数将物理引脚连接至对应的EXTI线路。 4. **编写NVIC优先级分组及初始化** 设置中断优先级别并通过调用`NVIC_Init()`来激活此中断向量表项。 5. **注册回调函数** 定义ISR(Interrupt Service Routine),即当中断发生时所执行的一段代码逻辑。 以下是基于STM32 HAL库的一个简单例子,展示了如何利用PA0作为外部下降沿触发的中断信号源[^1]。 ```c // 初始化部分 void MX_GPIO_Init(void){ __HAL_RCC_GPIOA_CLK_ENABLE(); // 开启GPIOA时钟 GPIO_InitTypeDef GPIO_InitStruct = {0}; /* PA0配置 */ GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; // 下降沿触发 GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); } int main(void){ HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); while (1){ // 主循环体... } } ``` #### 中断服务程序(ISR) 每当检测到PA0上的电平变化时,CPU将会跳转至此处定义的服务例程内运行: ```c void EXTI0_IRQHandler(void){ if (__HAL_GPIO_EXTI_GET_FLAG(GPIO_PIN_0)){ // 清除标志位以防再次误触 __HAL_GPIO_EXTI_CLEAR_FLAG(GPIO_PIN_0); // 用户自定义操作... printf("Button pressed!\r\n"); } } ``` 上述代码片段实现了基本的功能——每当用户按下一个接于PA0引脚上的开关时,串口打印一条消息通知开发者已捕捉到了这一动作。 #### 实际应用建议 考虑到实际竞赛环境中可能遇到的情况复杂度更高,因此除了掌握基础理论之外还需要积累更多实践经验。可以尝试构建一些小型项目练习使用不同类型的传感器或其他外围电路元件配合外部中断工作;另外也要熟悉Keil MDK集成环境下BSP包管理工具Chain CubeMX辅助生成框架代码等功能特性[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值