https://blog.csdn.net/dldw8816/article/details/50910911//外部中断
https://www.jianshu.com/p/3b0502f116b6//内部中断
https://blog.csdn.net/BH_firege/article/details/80980653
https://www.cnblogs.com/firege/p/5805706.html
其实上面那些基本概念和知识只是对STM32的中断系统有一个大概的认识,用程序说话将会更能够加深如何使用中断。使用外部中断的基本步骤如下:
-
设置好相应的时钟;
-
设置相应的中断;
-
IO口初始化;
-
把相应的IO口设置为中断线路(要在设置外部中断之前)并初始化;
-
在选择的中断通道的响应函数中中断函数
内部中断:
1、
使能外设某个中断,这个具体由每个外设的相关中断使能位控制。
比如串口有发送完成中断,接收完成中断,这两个中断都由串口控制寄存器的相关中断使能位控制。
2、
初始化NVIC_InitTypeDef结构体,配置中断优先级分组,设置抢占优先级和子优先级,使能中断请求
1)NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来确定,具体参考表格 16 优先级分组真值表
2)NVIC_IRQChannelCmd:中断使能(ENABLE)或者失能(DISABLE)。操作的是NVIC_ISER和NVIC_ICER这两个寄存器。
//例子
//中断配置结构体赋值------即选择中断触发的模式
EXTI_InitStructure.EXTI_Line=EXTI_Line3; //lin3中断线
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; //中断使能
EXTI_Init(&EXTI_InitStructure); //根据 EXTI_InitStruct 中指定的
//中断触发时指向的中断服务子程序
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; //使能按键外部中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级 2,
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02; //子优先级 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道
NVIC_Init(&NVIC_InitStructure); //中断优先级分组初始
- 优先级分组 主优先级 子优先级 描述
NVIC_PriorityGroup_0 0 0-15 主-0bit,子-4bit
NVIC_PriorityGroup_1 0-1 0-7 主-1bit,子-3bit
NVIC_PriorityGroup_2 0-3 0-3 主-2bit,子-2bit
NVIC_PriorityGroup_3 0-7 0-1 主-3bit,子-1bit
NVIC_PriorityGroup_4 0-15 0 主-4bit,子-0bit
3、
编写中断服务函数
在启动文件startup_stm32f429_439xx.s中我们预先为每个中断都写了一个中断服务函数,只是这些中断函数都是为空,为的只是初始化中断向量表。实际的中断服务函数都需要我们重新编写,中断服务函数我们统一写在stm32f4xx_it.c这个库文件中。
关于中断服务函数的函数名必须跟启动文件里面预先设置的一样,如果写错,系统就在中断向量表中找不到中断服务函数的入口,直接跳转到启动文件里面预先写好的空函数,并且在里面无限循环,实现不了中断。
void EXTI2_IRQHandler(void)
{
//逻辑代码;
EXTI_ClearITPendingBit(EXTI_Line2);
GPIO引脚 中断标志位 中断处理函数
PA0~PG0 EXTI0 EXTI0_IRQHandler
PA1~PG1 EXTI1 EXTI1_IRQHandler
PA2~PG2 EXTI2 EXTI2_IRQHandler
PA3~PG3 EXTI3 EXTI3_IRQHandler
PA4~PG4 EXTI4 EXTI4_IRQHandler
PA5~PG5 EXTI5 EXTI9_5_IRQHandler
PA6~PG6 EXTI6
PA7~PG7 EXTI7
PA8~PG8 EXTI8
PA9~PG9 EXTI9
PA10~PG10 EXTI10 EXTI15_10_IRQHandler
PA11~PG11 EXTI11
PA12~PG12 EXTI12
PA13~PG13 EXTI13
PA14~PG14 EXTI14
PA15~PG15 EXTI15
EXTI_InitStructure
EXTI_Line 值
EXTI_Line0 外部中断线 0
EXTI_Line1 外部中断线 1
EXTI_Line2 外部中断线 2
EXTI_Line3 外部中断线 3
EXTI_Line4 外部中断线 4
EXTI_Line5 外部中断线 5
EXTI_Line6 外部中断线 6
EXTI_Line7 外部中断线 7
EXTI_Line8 外部中断线 8
EXTI_Line9 外部中断线 9
EXTI_Line10 外部中断线 10
EXTI_Line11 外部中断线 11
EXTI_Line12 外部中断线 12
EXTI_Line13 外部中断线 13
EXTI_Line14 外部中断线 14
EXTI_Line15 外部中断线 15
EXTI_Line16 外部中断线 16
EXTI_Line17 外部中断线 17
EXTI_Line18 外部中断线 18
EXTI_Mode 设置了被使能线路的模式。Table 133. 给出了该参数可取的值
EXTI
Table 133. EXTI_Mode 值
EXTI_Mode 描述
EXTI_Mode_Event 设置 EXTI 线路为事件请求
EXTI_Mode_Interrupt 设置 EXTI 线路为中断请求
EXTI_Trigger
EXTI_Trigger 设置了被使能线路的触发边沿。Table 134. 给出了该参数可取的值
EXTI_Trigger 描述
EXTI_Trigger_Falling 设置输入线路下降沿为中断请求
EXTI_Trigger_Rising 设置输入线路上升沿为中断请求
EXTI_Trigger_Rising_Falling 设置输入线路上升沿和下降沿为中断请求
EXTI_LineCmd
EXTI_LineCmd 用来定义选中线路的新状态。它可以被设为 ENABLE 或者 DISABLE。
例:
/* Enables external lines 12 and 14 interrupt generation on falling
edge */
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line12 | EXTI_Line14;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);