什么是中断
F103 在内核水平上搭载了一个异常响应系统,支持为数众多的系统异常和外部中断,外部中断有 60 个。除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。直白点讲就是中断当前在main函数里的任务然后去执行中断函数的任务,类似于突然跳转到其他地方执行任务。
NVIC–嵌套向量中断控制器
NVIC 是嵌套向量中断控制器,控制着整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设
这是NVIC相关的寄存器,可以看到它主要用于使能中断以及确定优先级
优先级
中断优先级寄存器 NVIC_IPRx,用来配置外部中断的优先级,IPR宽度为 8bit,原则上每个外部中断可配置的优先级为 0~255,数值越小,优先级越高。用于表达优先级的这 4bit,又被分组成抢占优先级和子优先级。如果有多个中断同时响应,抢占优先级高的就会抢占抢占优先级低的优先得到执行,如果抢占优先级相同,就比较子优先级。如果抢占优先级和子优先级都相同的话,就比较他们的硬件中断编号,编号越小,优先级越高。
打开hal库的头文件可以看到有外设中断的结构体,这些就是片上外设的中断,那么问题来了我们是否可以利用按键产生中断呢?下面我们便要引入EXTI外部事件中断这一概念
ADC1_IRQn = 18,
EXTI9_5_IRQn = 23,
TIM1_BRK_TIM15_IRQn = 24,
TIM1_UP_TIM16_IRQn = 25,
TIM1_TRG_COM_TIM17_IRQn = 26,
TIM1_CC_IRQn = 27,
TIM2_IRQn = 28,
TIM3_IRQn = 29,
TIM4_IRQn = 30,
I2C1_EV_IRQn = 31,
I2C1_ER_IRQn = 32,
I2C2_EV_IRQn = 33,
I2C2_ER_IRQn = 34,
SPI1_IRQn = 35,
SPI2_IRQn = 36,
USART1_IRQn = 37,
USART2_IRQn = 38,
USART3_IRQn = 39,
EXTI15_10_IRQn = 40,
RTCAlarm_IRQn = 41,
CEC_IRQn = 42,
TIM12_IRQn = 43,
TIM13_IRQn = 44,
TIM14_IRQn = 45,
TIM5_IRQn = 50,
SPI3_IRQn = 51,
UART4_IRQn = 52,
UART5_IRQn = 53,
TIM6_DAC_IRQn = 54,
TIM7_IRQn = 55,
DMA2_Channel1_IRQn = 56,
DMA2_Channel2_IRQn = 57,
DMA2_Channel3_IRQn = 58,
DMA2_Channel4_5_IRQn = 59,
DMA2_Channel5_IRQn = 60。
EXTI功能框图
EXTI 可分为两大部分功能,一个是产生中断,另一个是产生事件
红色线路是产生中断的,绿色线路是产生EXTI外部事件中断的。
产生中断线路目的是把输入信号输入到 NVIC,进一步会运行中断服务函数,实现功能,这样是
软件级的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用,并且是电路级别的信号
传输,属于硬件级的。
8 这个脉冲信号可以给其他外设电路使用,比如定时器 TIM、模拟数字转换器 ADC 等等,这样的脉冲信号一般用来触发 TIM 或者 ADC开始转换
EXTI外部中断控制器
EXTI 有 20 个中断/事件线,每个 GPIO 都可以被设置为输入线,占用 EXTI0 至 EXTI15,,通过编程控制可以实现任意一个 GPIO 作为 EXTI 的输入源
用CUBEMX配置
实现按键中断
设置优先级
接下来就是编写中断服务函数
打开keil后可以看到有个stm32f1xx.it,拉到下面可以看到这个中断服务函数,右键跳转
继续右键进入回调函数,可以看到有个虚函数
这个函数就是写中断服务函数的,可以复制到main函数里,方便看。如下
记得要区分GPIO_Pin,因为所有的服务函数都是写在这个函数里的