外部中断映射
![](https://i-blog.csdnimg.cn/blog_migrate/d69f000fa465604501eff7d7965de4ad.png)
也就是说,每个不同GPIO组的相同pin不能接到同一个外部中断线上;而且,通过AFIO_EXTICRx配置GPIO线上的外部中断/事件,必须先使能AFIO时钟。
![](https://i-blog.csdnimg.cn/blog_migrate/2685e6ac21965f7d91d5368e4e597dfc.png)
![](https://i-blog.csdnimg.cn/blog_migrate/3f8ac2b64daa96d8e8555ddd3345a28c.png)
![](https://i-blog.csdnimg.cn/blog_migrate/cc1fdc14b1883dfc51654743c80416d5.png)
手册里没有双边沿触发的寄存器,看一下库函数如下:0x10对应的寄存器是软件促发的寄存器,具体实现不管,知道下降沿和上升沿都能触发中断即可
typedef enum
{
EXTI_Trigger_Rising = 0x08,
EXTI_Trigger_Falling = 0x0C,
EXTI_Trigger_Rising_Falling = 0x10
}EXTITrigger_TypeDef;
![](https://i-blog.csdnimg.cn/blog_migrate/6b585de014710811165c880e2371501a.png)
AFIO:用于中断引脚选择,所以在使用外部中断时应该先将它的时钟打开,它用于让外部中断线连上gpio的pin上,让它工作使能它的时钟即可
![](https://i-blog.csdnimg.cn/blog_migrate/b8e0feb9da30b99bd5c95c54b2e042d3.png)
其中,EXTI5到EXTI9共用一个中断函数,EXTI10到EXTI15共用一个中断函数,具体要使用哪个外部中断得在中断内部根据中断标志再次判断
![](https://i-blog.csdnimg.cn/blog_migrate/21db6af41f554116336e578372d9031e.png)
中断引脚实验
中断组
/**
* @brief Configures the priority grouping: pre-emption priority and subpriority.
* @param NVIC_PriorityGroup: specifies the priority grouping bits length.
* This parameter can be one of the following values:
* @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority
* 4 bits for subpriority
* @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority
* 3 bits for subpriority
* @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority
* 2 bits for subpriority
* @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority
* 1 bits for subpriority
* @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority
* 0 bits for subpriority
* @retval None
*/
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{
/* Check the parameters */
assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));
/* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */
SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}
我们以外部·中断12来写一个例程
void it_key_init(void)
{
//开启GPIO和AFIO的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//初始化GPIOB
GPIO_InitTypeDef GPIOB_STRU;
GPIOB_STRU.GPIO_Pin=GPIO_Pin_12;
GPIOB_STRU.GPIO_Mode=GPIO_Mode_IPU;
GPIOB_STRU.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIOB_STRU);
//接入外部中断线
GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);
//外部中断初始化
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_InitStruct.EXTI_Line=EXTI_Line12;
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;//下降沿
EXTI_InitStruct.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStruct);
//NVIC管理外部中断
//中断分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel=EXTI15_10_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=4;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
//外部中断服务函数
void EXTI15_10_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line12)==SET)
{
USART_SendString(USART1,"ok");//串口发送字符串
EXTI_ClearITPendingBit(EXTI_Line12);//清除挂起寄存器的置位
}
}
结果成功
![](https://i-blog.csdnimg.cn/blog_migrate/b111a622158ff3d74b4f52da192c3aba.png)