STM32如何关闭,开启进入中断服务函数
前言
当我们使用STM32的中断时,为了不影响主函数里函数执行(进入中断服务函数导致一些问题),有时候我们需要关闭中断然后再打开。本贴记录一下如何关闭中断(进入中断服务函数)。再重新开启中断
中断的配置
我们需要先设置好中断线和 GPIO 映射关系,以一个按键为例
先看宏定义
#define KEY1_GPIO_CLK (RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO)
#define KEY1_GPIO_PORT GPIOA
#define KEY1_GPIO_PIN GPIO_Pin_12
#define KEY1_INT_EXTI_PORTSOURCE GPIO_PortSourceGPIOA
#define KEY1_INT_EXTI_PINSOURCE GPIO_PinSource12
#define KEY1_INT_EXTI_LINE EXTI_Line12
#define KEY1_INT_EXTI_IRQ EXTI15_10_IRQn
GPIO_PIN0-15 对应的中断线为EXTI_Linex(x为0-15)
GPIO_PIN0-4 对应的中断通道为EXTIx_IRQn(x为0-4),GPIO_PIN5-9对应的中断通道为EXTI9_5IRQn,
GPIO_PIN15-10对应的中断通道为EXTI15_10IRQn
下面看引脚以及中断配置
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(KEY1_GPIO_CLK,ENABLE);
Key_Nvic_Config();
GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN|KEY2_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //上拉
GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);
/* 选择 EXTI 的信号源 */
GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, \
KEY1_INT_EXTI_PINSOURCE);
EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
/* EXTI 为中断模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
/* 上升沿中断 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
/* 使能中断 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
配置NVIC中断向量
NVIC_InitTypeDef NVIC_InitStructure;
/* 配置 NVIC 为优先级组 1 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* 配置中断源:按键 1 */
NVIC_InitStructure.NVIC_IRQChannel = KEY1_INT_EXTI_IRQ;
/* 配置抢占优先级: 1 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 配置子优先级: 1 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断通道 */
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
NVIC_Init(&NVIC_InitStructure);
接下来就可以编写中断服务函数,在此就不举例了。
举例说明对主函数的影响
先看代码
Motor_move(500);
Delay_ms(2000);
Motor_stop();
Delay_ms(1000);
Motor_back(500);
这段我放在while(1)里的程序是需要控制电机的转动时长。Delay_ms的延时是通过Systick实现的。
于是当这段程序执行时,你按按键进入中断服务函数,电机可能会一直转动下去。程序跑飞。
开启关闭中断
关闭NVIC中断通道
我在NVIC配置中将下面这句修改
NVIC_InitStructure.NVIC_IRQChannelCmd =DISABLE;
虽然这样关闭之后,不会执行中断服务函数,但是依旧会产生中断。还是会导致电机不停转。
关闭EXTI
修改这句代码
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
不产生中断信号,问题解决。
我们在按键的文件中添加这么两个函数
void Key_Exti_Open()
{
EXTI_InitTypeDef EXTI_InitStructure;
/* 选择 EXTI 的信号源 */
GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, \
KEY1_INT_EXTI_PINSOURCE);
EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
/* EXTI 为中断模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
/* 上升沿中断 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
/* 使能中断 */
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
void Key_Exti_Close()
{
EXTI_InitTypeDef EXTI_InitStructure;
/* 选择 EXTI 的信号源 */
GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE, \
KEY1_INT_EXTI_PINSOURCE);
EXTI_InitStructure.EXTI_Line = KEY1_INT_EXTI_LINE;
/* EXTI 为中断模式 */
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
/* 上升沿中断 */
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
/* 使能中断 */
EXTI_InitStructure.EXTI_LineCmd = DISABLE;
EXTI_Init(&EXTI_InitStructure);
}
然后添加到主函数中去
Key_Exti_Close();
Motor_move(500);
Delay_ms(2000);
Motor_stop();
Delay_ms(1000);
Motor_back(500);
Key_Exti_Open();
在电机转动过程中无论怎么按都不会触发中断影响执行。
至此,问题解决。
本帖记录自己学习开发中所遇到的问题以及解决方法,内容比较浅显。欢迎各位不吝赐教,前来指正批评