这个EXTI可以理解为就是外部中断/事件触发了,进入了中断线,然后就是做一下我们设置这个中断线时候要做的事情了。一般来说外部中断/事件都是由映射到IO口上的,一共有20个中断线,IO口占了前16个,剩下的这样表示
来此之前先简单说一下中断和事件的区别:中断我们通过以往的学习也知道我们系统中会有一个中断服务函数,但是从来没有听说过事件服务函数。其实我认识,中断是软件上的设置,需要CPU干预,而事件属于硬件上的内容,无需CPU干预。但是事件可以触发一下其他外事的事件,比如DMA传输,ADC采样,并且无需CPU干预。
这个我们还是看下寄存器来解释吧。
中断屏蔽寄存器(EXTI_IMR) :占了前20位用来开放/屏蔽中断请求。
事件屏蔽寄存器(EXTI_EMR) :占了前20位用来开放/屏蔽事件请求。
上升沿触发选择寄存器(EXTI_RTSR)
下降沿触发选择寄存器(EXTI_FTSR) 这两个看字面理解就好了
软件中断事件寄存器(EXTI_SWIER) :软件中断的意思,就是软件自己设置的中断,如果IMR和EMR设置了话也可以产生中断。
挂起寄存器(EXTI_PR) :这个寄存器就是相当于判断,你产生了触发条件就会被置为1,不过要在中断服务函数里面写1清除(或者产生其他沿触发),不然就导致会一直进入中断。
库函数版本:
#include "exti.h"
void EXTIX_Init(void)
{
EXTI_InitTypeDef EXTI_xxx;
NVIC_InitTypeDef NVIC_xxx;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
KEY_GPIO_Init();
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
EXTI_xxx.EXTI_Line = EXTI_Line3;
EXTI_xxx.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_xxx.EXTI_LineCmd = ENABLE;
EXTI_xxx.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_Init(&EXTI_xxx);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource4);
EXTI_xxx.EXTI_Line = EXTI_Line4;
EXTI_Init(&EXTI_xxx);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
EXTI_xxx.EXTI_Line = EXTI_Line0;
EXTI_xxx.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&EXTI_xxx);
NVIC_xxx.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_xxx.NVIC_IRQChannelCmd = ENABLE;
NVIC_xxx.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_xxx.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_xxx);
NVIC_xxx.NVIC_IRQChannel = EXTI3_IRQn;
NVIC_xxx.NVIC_IRQChannelCmd = ENABLE;
NVIC_xxx.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_xxx.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_xxx);
NVIC_xxx.NVIC_IRQChannel = EXTI4_IRQn;
NVIC_xxx.NVIC_IRQChannelCmd = ENABLE;
NVIC_xxx.NVIC_IRQChannelPreemptionPriority = 3;
NVIC_xxx.NVIC_IRQChannelSubPriority = 2;
NVIC_Init(&NVIC_xxx);
}
void EXTI0_IRQHandler(void)
{
delay_ms(10);
if(WK_UP)
{
printf("\r\n我按下了WK_UP");
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
void EXTI3_IRQHandler(void)
{
delay_ms(10);
if(!KEY1)
{
printf("\r\n我按下了KEY1");
}
EXTI_ClearITPendingBit(EXTI_Line3);
}
void EXTI4_IRQHandler(void)
{
delay_ms(10);
if(!KEY0)
{
printf("\r\n我按下了KEY0");
}
EXTI_ClearITPendingBit(EXTI_Line4);
}
寄存器数版本:
void EXTIX_Init(void)
{
KEY_GPIO_Init();
Ex_NVIC_Config(GPIO_A,0,RTIR); //上升沿触发
Ex_NVIC_Config(GPIO_E,3,FTIR); //下降沿触发
Ex_NVIC_Config(GPIO_E,4,FTIR); //下降沿触发
MY_NVIC_Init(2,3,EXTI0_IRQn,2); //抢占2,子优先级3,组2
MY_NVIC_Init(2,1,EXTI3_IRQn,2); //抢占2,子优先级1,组2
MY_NVIC_Init(2,0,EXTI4_IRQn,2); //抢占2,子优先级0,组2
}
void EXTI0_IRQHandler(void)
{
delay_ms(10);
if(WK_UP)
{
printf("\r\n寄存器版本:我按下了WK_UP");
}
EXTI->PR|=1<<0;
}
void EXTI3_IRQHandler(void)
{
delay_ms(10);
if(!KEY1)
{
printf("\r\n寄存器版本:我按下了KEY1");
}
EXTI->PR|=1<<3;
}
void EXTI4_IRQHandler(void)
{
delay_ms(10);
if(!KEY0)
{
printf("\r\n寄存器版本:我按下了KEY0");
}
EXTI->PR|=1<<4;
}
如果对您的问题有帮助的话可以帮忙点个赞,谢谢~QQ群:540093471 有问题大家可以一起交流沟通!