1 原理
1.1 EXTI
外部中断用到的外设-----------EXTI(External interrupt/event controller),中断控制器,产生中断
EXTI的功能框图
输入线: 对应的是GPIO,共有20根(EXTI_Line1..EXTI_Line19)
上升沿/下降沿触发选择寄存器: 配置触发条件
软件中断寄存器: 是否产生中断
中断屏蔽寄存器: 中断请求是否相应
1.2 NVIC
NVIC----------------配置中断优先级,将中断信号发送到内核,内核根据中断服务程序做出反应
2 代码
给出一个外部中断的样例,实现了按键中断实现灯开关
关于按键的一些宏定义:
#define KEY_GPIO_PIN GPIO_Pin_1
#define KEY_GPIO_PORT GPIOA
#define KEY_GPIO_CLK RCC_AHBPeriph_GPIOA
#define KEY_ON 1
#define KEY_OFF 0
步骤一:配置产生中断的GPIO
(1)定义GPIO初始化结构体
GPIO_InitTypeDef GPIO_InitStruct;
(2)初始化GPIO
//****************1-初始化GPIO**********************
RCC_AHBPeriphClockCmd(KEY_INT_CLK, ENABLE); //开时钟
GPIO_InitStruct.GPIO_Pin = KEY_INT_PIN;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; //浮空
GPIO_Init(KEY_INT_PORT, &GPIO_InitStruct); //初始化
步骤二:初始化EXTI
(1)定义EXTI初始化结构体
EXTI_InitTypeDef EXTI_InitStruct;
(2)初始化EXTI
//****************2-初始化EXTI**********************
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); //开时钟
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource1); //选择输入线
EXTI_InitStruct.EXTI_Line = EXTI_Line0; //选择EXTI线
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; //选择模式
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising; //选择上升沿触发
EXTI_InitStruct.EXTI_LineCmd = ENABLE; //使能选择的EXTI_Line
EXTI_Init(&EXTI_InitStruct) //初始化结构体
步骤三:配置中断优先级
(1)定义NVIC初始化结构体
NVIC_InitTypeDef NVIC_InitStruct;
(2)配置中断优先级
//****************3-配置中断优先级**********************
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); //配置组优先级
NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; //选择中断源
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1; //子优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; //开总中断
NVIC_Init(&NVIC_InitStruct); //初始化结构体
步骤四:编写中断服务函数
(1)在启动文件中声明中断服务函数
(我用的是EXTI0这条线,启动文件中已经默认编写了中断服务函数,并且为弱定义)
(2)在stm32l1xx_it.c(根据你的型号)中实现中断服务函数,并在头文件中声明
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
LED_TOGGLE;
}
EXTI_ClearITPendingBit(EXTI_Line0);
}