EXTI(External interrupt/event controller) —外部中断/事件控制器
NVIC 是嵌套向量中断控制器
编程思路
1)初始化用来产生中断的GPIO 口。
2)开启 AFIO 时钟
3)初始化EXTI。
4)NVIC配置。
5)编写中断服务函数。
1)初始化IO及EXTI配置
-
注意开启AFIO时钟
-
EXTI配置时要选择输入线(把相应的要发生中断的GPIO连接到EXTILine)GPIO_EXTILineConfig(KEY1_EXTI_PortSource,KEY1_EXTI_PinSource);
void EXIT_KEY_Config(void)
{
//NVIC_config();!!!!此句要放在函数声明下面
/* 第一步.初始化要连接到EXTI的GPIO*/
GPIO_InitTypeDef GPIO_InitStruct; //变量定义必须放在函数可执行语句前
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_config();
/*1.打开外设的时钟*/
RCC_APB2PeriphClockCmd(KEY1_EXTI_CLK|KEY2_EXTI_CLK,ENABLE);
/*2.设置相应结构体 */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin = KEY1_EXTI_PIN;
//设置为输入模式就不用设置GPIO_Speed参数了
/* 3.调用外设初始化函数,把配置好的结构体成员写到寄存器里边 */
GPIO_Init(KEY1_EXTI_PORT,&GPIO_InitStruct);
//KEY2初始化
GPIO_InitStruct.GPIO_Pin = KEY2_EXTI_PIN;
GPIO_Init(KEY2_EXTI_PORT,&GPIO_InitStruct);
/* 第二步.初始化EXTI外设*/
/*需要用到AFIO,先打开AFIO时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //AFIO
/*1.选择输入线(PA0,PC13)*/
GPIO_EXTILineConfig(KEY1_EXTI_PortSource,KEY1_EXTI_PinSource);
GPIO_EXTILineConfig(KEY2_EXTI_PortSource,KEY2_EXTI_PinSource);
/*2.配置EXTI的初始化结构体*/
EXTI_InitStruct.EXTI_Line = KEY1_EXTI_Line;
EXTI_InitStruct.EXTI_LineCmd = ENABLE;
EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
/*3.调用EXTI初始化函数,把配置好的结构体成员写到寄存器里边*/
EXTI_Init(&EXTI_InitStruct);
EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStruct.EXTI_Line = KEY2_EXTI_Line;
EXTI_Init(&EXTI_InitStruct);
}
2)NVIC配置
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//配置为组1
------这个函数的作用是对中断的优先级进行分组,这个函数在系统中只能被调用一次
-
抢占优先级的级别高于响应优先级。而数值越小所代表的优先级就越高。
-
如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;
-
高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。而抢占优先级相同的中断,高优先级的响应优先级不可以打断低响应优先级的中断。
static void NVIC_config(void)
{
NVIC_InitTypeDef NVIC_InitStruct;
/*第一步.配置中断优先级分组*/
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//配置为组1
/*第二步.配置NVIC的初始化结构体*/
NVIC_InitStruct.NVIC_IRQChannel = KEY1_EXTI_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;//子优先级
/*第三步.调用NVIC初始化函数,把配置好的结构体成员写到寄存器里边*/
NVIC_Init(&NVIC_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel = KEY2_EXTI_IRQn; //中断源
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 1;//子优先级
NVIC_Init(&NVIC_InitStruct);
}
3)中断服务函数
-
中断服务函数可以写在stm32f10x_it.c文件中
-
中断服务函数的
函数名
需要引用库函数中固定的匹配名称 如PC13 IO口的的中断服务函数名为EXTI15_10_IRQHandler 下边demo中函数名用了宏定义
- EXTI_GetITStatus( ) 中断检测函数
- EXTI_ClearITPendingBit( )标志位清除
void KEY1_EXTI_Handler(void)
{
if(EXTI_GetITStatus(KEY1_EXTI_Line) != RESET)
{
LEDG_Toggle;
}
EXTI_ClearITPendingBit(KEY1_EXTI_Line);
}
void KEY2_EXTI_Handler(void)
{
if(EXTI_GetITStatus(KEY2_EXTI_Line) != RESET)
{
LEDR_Toggle;
}
EXTI_ClearITPendingBit(KEY2_EXTI_Line);
}