stm32之外部中断EXTI和NVIC
中断如何配置步骤如下
一、初始化用来中断的GPIO口
二、初始化EXTI(外部中断)
三、配置NVIC(中断优先级)中断控制器
四、编写中断函数
一、初始化用来中断的GPIO口
以GPIOA1为例:
void Exti_Init(void)
{
GPIO_InitTypeDef shank_init;
//1、定义GPIOA1的结构体
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// 2、使能GPIOA时钟
shank_init.GPIO_Mode = GPIO_Mode_IPU;
shank_init.GPIO_Pin = GPIO_Pin_1;
shank_init.GPIO_Speed = GPIO_Speed_10MHz;
//3、配置GPIOA的结构体
GPIO_Init(GPIOA,&shank_init);
//4、初始化GPIOA1时钟
}
二、初始化EXTI(外部中断)
边缘检测电路----》上升沿/下降沿触发中断
2.1、EXTI中断原理图
2.2、EXTI外部中断源
有20个中断/事件线
2.3、EXT外部中断的结构体,及参数讲解
typedef struct
{
uint32_t EXTI_Line; /*!< Specifies the EXTI lines to be enabled or disabled.
This parameter can be any combination of @ref EXTI_Lines */
EXTIMode_TypeDef EXTI_Mode; /*!< Specifies the mode for the EXTI lines.
This parameter can be a value of @ref EXTIMode_TypeDef */
EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
This parameter can be a value of @ref EXTIMode_TypeDef */
FunctionalState EXTI_LineCmd; /*!< Specifies the new state of the selected EXTI lines.
This parameter can be set either to ENABLE or DISABLE */
}EXTI_InitTypeDef;
参数:
1、EXTI_Line :EXTI中断/事件线选择;可选EXTI0至EXTI19(stm32f10x_exti.h)
2、EXTI_Mode: EXTI模式选择;选择中断/事件模式
3、EXTI_Trigger : EXTI边沿触发事件,上升/下降沿/上升下降沿触发;
4、EXTI_LineCmd : 控制是否使能EXTI线;或禁用。
2.4、配置EXTI外部中断
void Exti_Init(void)
{ //1、定义GPIOA1的结构体
GPIO_InitTypeDef shank_init;
//1.1、定义GPIOA1中断结构体
EXTI_InitTypeDef exti_init;
//1.2、
// 2、使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//2.1、使能GPIOA时钟为外部中断
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//3.1、设置为外部中断源输入
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);
//3.2、配置GPIOA的结构体
shank_init.GPIO_Mode = GPIO_Mode_IPU;
shank_init.GPIO_Pin = GPIO_Pin_1;
shank_init.GPIO_Speed = GPIO_Speed_10MHz;
//4、初始化GPIOA1时钟
GPIO_Init(GPIOA,&shank_init);
//5、配置EXTI中断
exti_init.EXTI_Line = EXTI_Line1;
exti_init.EXTI_Mode = EXTI_Mode_Interrupt;
exti_init.EXTI_Trigger = EXTI_Trigger_Falling;
exti_init.EXTI_LineCmd = ENABLE;
//6、初始化中断结构体
EXTI_Init(&exti_init);
}
三、配置NVIC(中断优先级)中断控制器
NVIC结构体:
typedef struct
{
uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled.
This parameter can be a value of @ref IRQn_Type
(For the complete STM32 Devices IRQ Channels list, please
refer to stm32f10x.h file) */
uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel
specified in NVIC_IRQChannel. This parameter can be a value
between 0 and 15 as described in the table @ref NVIC_Priority_Table */
uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified
in NVIC_IRQChannel. This parameter can be a value
between 0 and 15 as described in the table @ref NVIC_Priority_Table */
FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
will be enabled or disabled.
This parameter can be set either to ENABLE or DISABLE */
} NVIC_InitTypeDef;
参数:
1、NVIC_IRQChannel : 设置中断的通道(misc.h)
2、NVIC_IRQChannelPreemptionPriority : 设置抢占优先级
3、NVIC_IRQChannelSubPriority : 设置子优先级
4、NVIC_IRQChannelCmd : 设置是否使能中断控制器,使能/禁用
void Exti_Init(void)
{ //1、定义GPIOA1的结构体
GPIO_InitTypeDef shank_init;
//1.1、定义GPIOA1中断结构体
EXTI_InitTypeDef exti_init;
//1.2、定义NVIC中断结构体
NVIC_InitTypeDef nvic_init;
// 2、使能GPIOA时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//2.1、使能GPIOA时钟为外部中断
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
//7.3、配置中断优先级组结构体
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//3.1、设置为外部中断源输入
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource1);
//3.2、配置GPIOA的结构体
shank_init.GPIO_Mode = GPIO_Mode_IPU;
shank_init.GPIO_Pin = GPIO_Pin_1;
shank_init.GPIO_Speed = GPIO_Speed_10MHz;
//4、初始化GPIOA1时钟
GPIO_Init(GPIOA,&shank_init);
//5、配置EXTI中断
exti_init.EXTI_Line = EXTI_Line1;
exti_init.EXTI_Mode = EXTI_Mode_Interrupt;
exti_init.EXTI_Trigger = EXTI_Trigger_Falling;
exti_init.EXTI_LineCmd = ENABLE;
//6、初始化中断结构体
EXTI_Init(&exti_init);
// 7、配置NVIC结构体
nvic_init.NVIC_IRQChannel = EXTI1_IRQn;
nvic_init.NVIC_IRQChannelCmd = ENABLE;
nvic_init.NVIC_IRQChannelPreemptionPriority = 1;
nvic_init.NVIC_IRQChannelSubPriority = 1;
//7.1、初始化NVIC结构体
NVIC_Init(&nvic_init);
}
四、编写中断处理函数
在启动文件中startup_stm32f10x_hds;找到定义中断处理函数
void EXTI_ClearFlag(uint32_t EXTI_Line);
//1、清除中断标志位
ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
//2、触发中断函数
中断处理函数编写:
void EXTI1_IRQHandler(void)
{
if ( EXTI_GetITStatus(EXTI_Line1) != RESET ) //
{
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
delay(3000);
GPIO_SetBits(GPIOC, GPIO_Pin_13);
}
EXTI_ClearFlag(EXTI_Line1);
}