STM32如何关闭,开启进入中断服务函数

前言中断的配置举例说明对主函数的影响开启关闭中断关闭NVIC中断通道关闭EXTI

前言

当我们使用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();

在电机转动过程中无论怎么按都不会触发中断影响执行。 至此,问题解决。

本帖记录自己学习开发中所遇到的问题以及解决方法,内容比较浅显。欢迎各位不吝赐教,前来指正批评