- 前言
- 一、STM32F4 外部中断简介
- 二、编程要点
- 相关宏定义如下
- 1、使能 IO 口时钟,初始化 IO 口为输入
- 2.开启 SYSCFG 时钟,设置 IO 口与中断线的映射关系。
- 3、 初始化线上中断,设置触发条件等。
- 4、配置中断分组(NVIC),并使能中断。
- 5、编写中断服务函数。
- 6、在main函数中初始化按键的配置
- 总结
本文教大家使用外部中断,通过连接按键到IO口,利用中断控制单片机内部程序。
使用器材:STM32F407
STM32F4 的每个 IO 都可以作为外部中断的中断输入口,STM32设计GPIO 的管脚GPIOx.0~GPIOx.15(x=A,B,C,D,E,F,G,H,I)分别对应中断线 0~15。这样每个中断线对应了最多 9 个 IO 口,以线 0 为例:它对应了 GPIOA.0、GPIOB.0、GPIOC.0、GPIOD.0、GPIOE.0、GPIOF.0、GPIOG.0,GPIOH.0,GPIOI.0。而中断线每次只能连接到 1 个 IO口上,这样就需要通过配置来决定对应的中断线配置到哪个 GPIO 上了。
GPIO跟中断线的映射关系图:
- 使能 IO 口时钟,初始化 IO 口为输入;
- 配置 NVIC;
- 配置按键 GPIO 为输入模式;
- 将按键 GPIO 连接到 EXTI 源输入;
- 配置按键 EXTI 中断/事件线;
- 编写 EXTI 中断服务函数。
#define KEY1_INT_GPIO_PORT GPIOC #define KEY1_INT_GPIO_CLK RCC_AHB1Periph_GPIOC #define KEY1_INT_GPIO_PIN GPIO_Pin_9 #define KEY1_INT_EXTI_PORTSOURCE EXTI_PortSourceGPIOC #define KEY1_INT_EXTI_PINSOURCE EXTI_PinSource9 #define KEY1_INT_EXTI_LINE EXTI_Line9 #define KEY_INT_EXTI_IRQ EXTI9_5_IRQn //5~9的IO口共用 #define KEY_IRQHandler EXTI9_5_IRQHandler1、使能 IO 口时钟,初始化 IO 口为输入
首先,我们要使用 IO 口作为中断输入,所以我们要使能相应的 IO 口时钟,以及初始化相
应的 IO 口为输入模式
GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE); //开启对应GPIO时钟 GPIO_InitStructure.GPIO_Pin = KEY1_INT_GPIO_PIN; //选择管脚 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; //配置为输入模式 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //配置为上拉模式 GPIO_Init(KEY1_INT_GPIO_PORT,&GPIO_InitStructure); //初始化结构体2.开启 SYSCFG 时钟,设置 IO 口与中断线的映射关系。
1、我们要配置 GPIO 与中断线的映射关系,那么我们首先需要打开 SYSCFG 时钟。这里大家一定要注意,只要我们使用到外部中断,就必须打开 SYSCFG 时钟。(注明一下,在F103上不需要开启此时钟)
2、我们配置 GPIO 与中断线的映射关系。在库函数中,配置 GPIO 与中断线的映射关系的函数 SYSCFG_EXTILineConfig ()来实现的:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); SYSCFG_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE,KEY1_INT_EXTI_PINSOURCE);3、 初始化线上中断,设置触发条件等。
SYSCFG_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE,KEY1_INT_EXTI_PINSOURCE); EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure);4、配置中断分组(NVIC),并使能中断。
static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = KEY_INT_EXTI_IRQ; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }5、编写中断服务函数。
我们配置完中断优先级之后,接着要做的就是编写中断服务函数。中断服务函数的名字是
在 MDK 中事先有定义的。这里需要说明一下,STM32F4 的 IO 口外部中断函数只有 7 个,分
别为:
EXPORT EXTI0_IRQHandler EXPORT EXTI1_IRQHandler EXPORT EXTI2_IRQHandler EXPORT EXTI3_IRQHandler EXPORT EXTI4_IRQHandler EXPORT EXTI9_5_IRQHandler EXPORT EXTI15_10_IRQHandler
中断线 0-4 每个中断线对应一个中断函数,中断线 5-9 共用中断函数 EXTI9_5_IRQHandler,中
断线 10-15 共用中断函数 EXTI15_10_IRQHandler。在编写中断服务函数的时候会经常使用到两
个函数。
第一个函数是判断某个中断线上的中断是否发生(标志位是否置位):
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
这个函数一般使用在中断服务函数的开头判断中断是否发生。另一个函数是清除某个中断线上
的中断标志位:
void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
这个函数一般应用在中断服务函数结束之前,清除中断标志位。
常用的中断服务函数格式为
void EXTI3_IRQHandler(void) { if(EXTI_GetITStatus(EXTI_Line3)!=RESET)//判断某个线上的中断是否发生 { …中断逻辑… EXTI_ClearITPendingBit(EXTI_Line3); //清除 LINE 上的中断标志位 } }
在这里需要说明一下,固件库还提供了两个函数用来判断外部中断状态以及清除外部状态:
标志位的函数 EXTI_GetFlagStatus 和 EXTI_ClearFlag,他们的作用和前面两个函数的作用类似。
只是在 EXTI_GetITStatus 函数中会先判断这种中断是否使能,使能了才去判断中断标志位,而
EXTI_GetFlagStatus 直接用来判断状态标志位。
一定要记得在main函数中调用这些初始化函数,很多新手小白就是一老忘记这件事(我),烧录程序之后按键没反应,对着代码看了半天也想不明白哪里配置错了。
总结1)使能 IO 口时钟,初始化 IO 口为输入。
2)使能 SYSCFG 时钟,设置 IO 口与中断线的映射关系。
3)初始化线上中断,设置触发条件等。
4)配置中断分组(NVIC),并使能中断。
5)编写中断服务函数。
6)在main函数中初始化按键的配置
通过以上几个步骤的设置,我们就可以正常使用外部中断了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)