目录
总结:经过分析框图,可以产生软件中断和事件中断,软件中断的目的是进中断服务函数。事件中断是产生一个脉冲信号给片内外设,属于硬件级别的。
EXTI1_IRQHandler EXTI9_5_IRQHandler EXTI15_10_IRQHandler
1.外部中断描述
作用于GPIO口,引用芯片外部中断作为中断源。
一般产品有19个外部中断,互联型产品有20个外部中断。真正意义上的外部中断只有16个(0-15)。
其余四个:
EXTI线16连接到PVD输出
EXTI线17连接到RTC闹钟事件
EXTI线18连接到USB唤醒事件
EXTI线19连接到以太网唤醒事件(只适用于互联型产品)
注意:EXIT0-EXIT4每个中断源对应一个中断入口地址。EXIT5-EXIT9公用一个中断入口地址。。EXIT10-EXIT15公用一个中断入口地址
2.外部中断框图
工作流程:
1.外部GPio引脚输入信号以后经过边沿检测电路,当检测到特定的边沿后输出信号1.。
2.线路经过或门时软件设置是否产生事件中断(硬件中断)。
软件中断事件寄存器 (EXTI_SWIER)作用:每1位控制1个外部中断线,这个寄存器是写“1”有效,写“0”无效。手动产生一个外部中断/事件请求
注意:该寄存器不能直接清零(不能直接对寄存器相应位清零),只能通过“挂起寄存器挂起寄存器 (EXTI_PR)”的对应位进行清零,从而使该寄存器的相应位清零。
3.如果需要产生事件中断,需要向事件屏蔽寄存器 (EXTI_EMR)往对应位写入“1”,此时就会输出一个脉冲信号。
4.向中断屏蔽寄存器(EXTI_IMR)应位写入“1”,则使能对应中断线的中断使能,写入“0”,则关闭中断。
5.当边沿检测电路检测到期待的边沿信号时,挂起寄存器的对应位会被硬件自动置1,产生一个用于申请中断的标志。
注:这个寄存器只能通过往对应位写入“1”来对相应的标志位进行清零(写1清零),或者通过改变中断线的边沿检测条件来对标志位进行清零。
总结:经过分析框图,可以产生软件中断和事件中断,软件中断的目的是进中断服务函数。事件中断是产生一个脉冲信号给片内外设,属于硬件级别的。
3.端口对应
外部中断0~15映射到任何一组同名的GPIO端口(外部中断0,映射到端口编号为0的GPIO端口),并且一个外部中断入口只能映射到一个GPIO端口
4.编程思路
- 定义结构体NVIC和EXIT
- 开启复用时钟 ----RCC_APB2PeriphClockCmd
EXIT
- 配置 GPIO口对应的外部中断线。GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0)
- 选择GPIO对应的外部中断线。0-15
- 选则外部中断或者事件中断
- 选择上升沿还是下降沿触发
- 使能中断线
- 初始化外部中断结构体
NVIC
- 配置NVIC中断源
- 设置抢占优先级和响应优先级
- 中断通道使能
- 初始化中断结构体
EXTI1_IRQHandler EXTI9_5_IRQHandler EXTI15_10_IRQHandler
- 编写中断服务函数
5.代码
void KEY_Exit_Init(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
EXTI_InitStructure.EXTI_Line = EXTI_Line3;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //软件中断
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发---key默认高电平
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
EXTI_InitStructure.EXTI_Line = EXTI_Line4;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //软件中断
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn; //key2
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;//key1
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
void EXTI3_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line3) == SET) //挂起寄存器
{
EXTI_ClearITPendingBit(EXTI_Line3);//
//
}
}