EXTI(External Interrupt)
用一张图来讲述配置外部中断的流程
AFIO
AFIO在这里的作用是数据选择器直接用一个列子说明它的作用,它会在GPIOX(x=A~G)_Pin_1 中选择一个,而这样的数据选择器有16个,刚好对应16个引脚,所以不能同时选用GPIOA_PIN_1和GPIOB_PIN_1,两个序号相同的引脚
//AFIO
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);//开启时钟
GPIO_AFIODeInit();//恢复缺省配置
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource14);//选择GPIOB_Pin_14作为14号中断信号
EXTI
EXTI有20个中断通道,前16个对应IO口,后面四个分别是PWR电压检测,RTC闹钟,USB,以太网,USB和以太网还没接触过,配置时直接用一个初始化就好了
//EXTI
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line=EXTI_Line14;//中断通道选择(可以选择多个)
EXTI_InitStruct.EXTI_LineCmd=ENABLE;//开启该中断通道
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;//申请中断还是申请事件
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿触发(上升下降都可以选)
EXTI_Init(&EXTI_InitStruct);
EXTI_Line一共有20个,0~19
NVIC
NVIC是一个中断处理端口吧,负责管辖STM32所有的中断申请,提到NVIC就不得不提到中断优先级,NVIC为每个通道提供了0~15,16个优先级,也就是4bit,数字越小优先级越高,优先级一般由抢占优先级和响应优先级共同决定,抢占优先级高可以把别人踢下台(中断嵌套),响应优先级高可以强行插队(但要等前一个中断执行完),而这两个优先级通过分组方式确定各分配多少
prioritygroupconfig就是优先级分组函数,上面的注释就是具体的解释即抢占和响应各占几位Bit
//NVIC
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置优先级分组
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel=EXTI15_10_IRQn;//选择中断通道
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//开启中断通道
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;//响应优先级
NVIC_Init(&NVIC_InitStruct);
NCIC_IRQChannel就如第一张图所示,第一张图展示的只是EXTI的中断通道,不代表全部
那么这样子也就算中断配置完了,那么中断函数去哪找呢——Start_startup_stm32F10x_md.s
DCD EXTI0_IRQHandler ; EXTI Line 0
DCD EXTI1_IRQHandler ; EXTI Line 1
DCD EXTI2_IRQHandler ; EXTI Line 2
DCD EXTI3_IRQHandler ; EXTI Line 3
DCD EXTI4_IRQHandler ; EXTI Line 4
DCD EXTI9_5_IRQHandler ; EXTI Line 9..5
DCD EXTI15_10_IRQHandler ; EXTI Line 15..10
DCD RTCAlarm_IRQHandler ; RTC Alarm through EXTI Line
DCD USBWakeUp_IRQHandler ; USB Wakeup from suspend
DCD PVD_IRQHandler ; PVD through EXTI Line detect
//以太网的就不介绍了
中断函数主体
void EXTI15_10_IRQHandler(void)//中断主体函数
{
if(EXTI_GetITStatus(EXTI_Line14)==SET)
{
执行内容:
EXTI_ClearITPendingBit(EXTI_Line14);
}
}
有些时候需要清除多个标志
void RTCAlarm_IRQHandler(void)
{
if(RTC_GetFlagStatus(RTC_FLAG_ALR)==SET)
{
执行内容:
RTC_ClearITPendingBit(RTC_IT_ALR);
EXTI_ClearITPendingBit(EXTI_Line17);
}
}
以上就是我对EXTI中断的总结,至于事件和软件触发暂不涉及,另外附加一个EXTI流程框图