一、什么是中断?
打断当前的操作,执行中断需要做的事情。
中断的作用:中断机制不仅赋予了系统处理意外情况的能力,就可以“同时”完成多个任务,提高了并发“处理”能力。
和线程的区别:线程是同时执行多个任务,中断是停下来去执行其他的(注意优先级),执行完了再回来执行,
定时器才相当于线程,定一个时间,每到这个时间执行一次
二、中断概述
STM32F4并没有使用CM4内核的全部东西,而是只用了它的一部分。
STM32F40xx/STM32F41xx总共有92个中断
STM32F42xx/STM32F43xx则总共有96个中断
STM32F40xx/STM32F41xx的92个中断里面,包括10个内核中断和82个可屏蔽中断,具有16级可编程的中断优先级,而我们常用的就是这82个可屏蔽中断。
三、外部中断/事件线映射多达140个GPIO。
根据图文,发现我们的中断线总共有23根,其中16根是连接PA~PI引脚。
STM32F4供IO使用的中断线只有16个:EXTI线0~15:对应外部IO口的输入中断。
剩下的七根是分别连接专用设备的:
另外七根 EXTI 线连接方式如下:
● EXTI 线 16 连接到 PVD 输出
● EXTI 线 17 连接到 RTC 闹钟事件
● EXTI 线 18 连接到 USB OTG FS 唤醒事件
● EXTI 线 19 连接到以太网唤醒事件
● EXTI 线 20 连接到 USB OTG HS(在 FS 中配置)唤醒事件
● EXTI 线 21 连接到 RTC 入侵和时间戳事件
● EXTI 线 22 连接到 RTC 唤醒事件
四、中断服务函数分配
IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数
从表中看出,外部中断线5~9分配一个中断向量,共用一个服务函数 外部中断线10~15分配一个中断向量,共用一个中断服务函数
中断服务函数列表如下:
五、设置中断优先级的分组
1、中断优先级有两种:
抢占(占先式)优先级 --》 第一序列 响应(副)优先级 --》 第二序列
2、抢占优先级 &响应优先级区别:
高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。
抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。
抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。
如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;
3、中断优先级设置步骤
//①系统运行后先设置中断优先级分组。调用函数:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);整个系统执行中只设置一次中断分组。
//②针对每个中断,设置对应的抢占优先级和响应优先级:
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
③如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可
五、外部中断的一般配置步骤
①使能SYSCFG时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
②初始化IO口为输入。
GPIO_Init();
③设置IO口与中断线的映射关系。
void SYSCFG_EXTILineConfig();//通过设置SYSCFG寄存器,建立IO口和中断线的连接
④初始化线上中断,设置触发条件等。
EXTI_Init();
⑤配置中断分组(NVIC),并使能中断。
NVIC_Init();
⑥编写中断服务函数。
EXTIx_IRQHandler();
且清除中断标志位
EXTI_ClearITPendingBit();//清除中断标志位是为了表示中断已经开始执行,可以接收下一个中断。
代码如下:
/**********************************************
*
*功能:四个按键中断
*
**********************************************/
#include "exti.h"
//外部中断初始化程序
//初始化PE2~4,PA0为中断输入.
void EXTI4_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOA,GPIOE时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; //KEY0 KEY1 KEY2对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);//PE4 连接到中断线4
/* 配置EXTI_Line2,3,4 */
EXTI_InitStructure.EXTI_Line = EXTI_Line4;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中断线使能
EXTI_Init(&EXTI_InitStructure);//配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//外部中断4
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
NVIC_Init(&NVIC_InitStructure);//配置
}
void EXTI3_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOA,GPIOE时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //KEY0 KEY1 KEY2对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource3);//PE4 连接到中断线4
/* 配置EXTI_Line2,3,4 */
EXTI_InitStructure.EXTI_Line = EXTI_Line3;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中断线使能
EXTI_Init(&EXTI_InitStructure);//配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;//外部中断4
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
NVIC_Init(&NVIC_InitStructure);//配置
}
void EXTI2_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);//使能GPIOA,GPIOE时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //KEY0 KEY1 KEY2对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE2,3,4
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);//PE4 连接到中断线4
/* 配置EXTI_Line2,3,4 */
EXTI_InitStructure.EXTI_Line = EXTI_Line2;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中断线使能
EXTI_Init(&EXTI_InitStructure);//配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;//外部中断4
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
NVIC_Init(&NVIC_InitStructure);//配置
}
void EXTI0_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA,GPIOE时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //KEY0 KEY1 KEY2对应引脚
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;//普通输入模式
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100M
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOE2,3,4
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);//PE4 连接到中断线4
/* 配置EXTI_Line2,3,4 */
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断事件
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//中断线使能
EXTI_Init(&EXTI_InitStructure);//配置
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;//外部中断4
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x01;//抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;//子优先级2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能外部中断通道
NVIC_Init(&NVIC_InitStructure);//配置
}
//外部中断4服务程序
void EXTI4_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line4) != RESET)//判断是否置位
{}
EXTI_ClearITPendingBit(EXTI_Line4);//清除LINE4上的中断标志位
}
//外部中断3服务程序
void EXTI3_IRQHandler(void)
{
delay_ms(15);
EXTI_ClearITPendingBit(EXTI_Line3);//清除LINE4上的中断标志位
}
//外部中断2服务程序
void EXTI2_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line2);//清除LINE4上的中断标志位
}
//外部中断0服务程序
void EXTI0_IRQHandler(void)
{
EXTI_ClearITPendingBit(EXTI_Line1);//清除LINE4上的中断标志位
}
上一篇:STM32CUBEIDE打印浮点数问题
下一篇:STM32的RTC的原理与使用(附代码)
推荐帖子
- CKCWS-A90SA 谁有MDK注册机帮我产生一下
- CKCWS-A90SA谁有MDK注册机帮我产生一下CKCWS-A90SA谁有MDK注册机帮我产生一下CKCWS-A90SA是什么?CKCWS-A90SA是本机电脑的CID,因为限制下载不了注册机,所以求助!回复沙发youki12345的帖子就是用Keil注册机来弄的回复沙发youki12345的帖子NQQ63-AMGVZ-QBEEE-59TLR-GA9ND-2WDKT谢谢回复5楼kumocw的帖子
- suguoliu 微控制器 MCU
- “POS机套件”中的器件,你将怎样发挥它的作用?
- “POS机套件”中的器件,都很有特点,一部分是TI刚刚推出的新器件,性能及功能很好。TI这次活动将了放100套这样的套件,比例相当大。这些套件如果到了你手里,你将怎样发挥它的作用?有更具体的想法吗? “POS机套件”中的器件,你将怎样发挥它的作用?楼主的问题呢很好,还真不知道怎么怎样发挥它的作用,因为估计很多朋友还根本不知道它是个啥,,,谁了解的多,不妨来说一下放到DIY小组么~方案最重要,出了方案啥都好说~直接看看说明,手头搞的东西能用就直接上了原帖由shuigui于
- dontium 模拟与混合信号
- 关于AMS1117 AD 输出电压求助
- 有一个这样的1117应用。不知道输出电压的计算公式是怎么样的?找了很多资料发现接法都不同。求助谢谢关于AMS1117AD输出电压求助看起来是个恒流源的应用,猜测而已测试了一下,貌似是恒流,哪么该怎么计算呢?是算电流还是电压的?看来是恒流的,只是不知道该怎么算电压电流这个的话,我记得datasheet中有对这些计算有解释的。您去下载它的datasheet,看看里面的内容就知道怎么计算了。R1是这个IC的负载电阻,在它上面的电压,等于其稳压值。它是变相的恒流电路。
- xxhei PCB设计
- 【资料共享】33个毕业设计——单片机类
- 即将毕业的同学可以参考借鉴,33个毕业设计——单片机类!【资料共享】33个毕业设计——单片机类33个毕业设计——单片机类33个毕业设计——单片机类顶一下!谢谢楼主分享谢谢楼主分享顶一下好东西,看看能干嘛源码??谢谢楼主!很有用,学习学习谢谢楼主收下了,谢谢分享下载了为什么是0B呢,没有任何内容~最经在学习单片机,这下有材料可以做了太感谢了谢谢分享,下载看看先好东西,感谢分享哇塞碉堡了先谢谢,看一下希望有点意思东西不错,下来看看啊!多谢
- zgzzlt 51单片机
- 关于消费电子产品的功能测试问题
- 本帖最后由jameswangsynnex于2015-3-320:00编辑楼上的可以多帖一些资料上来啊Re:关于消费电子产品的功能测试问题本帖最后由jameswangsynnex于2015-3-320:00编辑没有人顶了,打击积极性嘛!回复:关于消费电子产品的功能测试问题
- cloudy313 移动便携
- 【行空板 Python编程学习主控板】使用陀螺仪和语音识别的星球大战BB-8机器人控制器
- 目录:零、前言一、设计规划二、六轴传感器三、麦克风与语音识别四、按键处理五、BB-8机器人的控制方式六、行空板控制BB-8机器人七、BB-8机器人控制器系统八、实际操作效果演示九、总结零、前言在申请行空板的时候,我提交的测评计划是:准备基于此开发板,使用Python语言,基于板载的加速度传感器和麦克风,构建一个星球大战之BB-8机器人控制系统,其具体功能如下: 将星空开发板变身手持控制器,通过保持平衡
- HonestQiao 嵌入式系统
设计资源 培训 开发板 精华推荐
- 使用 Analog Devices 的 LTC4302-2CMS 的参考设计
- LTC4064EMSE 演示板,4.0V 锂离子电池充电器,Vin = 4.25V 至 6.3V,Bat = 4.0V @ 0.5A/1A
- 适用于 EV/HEV 电池管理系统的高性能 MCU 参考设计
- RSL10-SENSE-DB-GEVK:带调试器的 RSL10 传感器开发套件
- LM358EDR2G 双四路滤波器运算放大器的典型应用
- 汽车音响用音频功率放大器
- AD8337-EVAL-INV,双电源反相评估套件,为 AD8337 VGA 的测试和评估提供平台
- 4G数字农业
- LTC1261LCMS8-4.5 5V 输入、-4V 输出 GaAs FET 偏置发生器的典型应用电路
- NUCLEO-L4R5ZI,STM32 Nucleo-144开发板,带STM32L4R5ZIT6 MCU,支持Arduino、ST Zio和Morpho