STM32--外部中断——EXIT
目录
NVIC
NVIC 是嵌套向量中断控制器,控制着 整个芯片中断相关的功能,它跟内核紧密耦合,是内核里面的一个外设。
要想使用中断,就需要配置这个内部中断,而外部只是一个触发信号;
配置NVIC
下面是常用的配置:
为了方便,使用固件库函数
//关于NVIC中断的结构体
typedef struct
{
uint8_t NVIC_IRQChannel; /*!< Specifies the IRQ channel to be enabled or disabled.
This parameter can be a value of @ref IRQn_Type
(For the complete STM32 Devices IRQ Channels list, please
refer to stm32f10x.h file) */
uint8_t NVIC_IRQChannelPreemptionPriority; /*!< Specifies the pre-emption priority for the IRQ channel
specified in NVIC_IRQChannel. This parameter can be a value
between 0 and 15 as described in the table @ref NVIC_Priority_Table */
uint8_t NVIC_IRQChannelSubPriority; /*!< Specifies the subpriority level for the IRQ channel specified
in NVIC_IRQChannel. This parameter can be a value
between 0 and 15 as described in the table @ref NVIC_Priority_Table */
FunctionalState NVIC_IRQChannelCmd; /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel
will be enabled or disabled.
This parameter can be set either to ENABLE or DISABLE */
} NVIC_InitTypeDef;
uint8_t NVIC_IRQChannel; | 中断源的选择 |
uint8_t NVIC_IRQChannelPreemptionPriority | 抢占优先级 |
uint8_t NVIC_IRQChannelSubPriority; | 抢占子优先级 |
FunctionalState NVIC_IRQChannelCmd; | 中断使能 |
//NVIC简单配置
static void EXTI_NVIC_Config()
{
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
NVIC_InitStruct.NVIC_IRQChannelSubPriority=1;
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStruct);
NVIC_InitStruct.NVIC_IRQChannel=EXTI15_10_IRQn;
NVIC_Init(&NVIC_InitStruct);//这里的初始化,只是改变上面修改过的参数,其余的不变
}
这是中断的内部条件,内部条件配置好了之后,中断就完成了50%,剩下的就是外设启动中断;
EXIT
EXTI(External interrupt/event controller)—外部中断/事件控制器,管理了控制器的 20 个中断/事 件线。每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的 检测。EXTI 可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触 发事件的属性。
EXIT说白了就是外部中断配置管理,它设置着外部哪种信号可以出发中断,比如它可以设置上升沿触发中断,也可以下降沿触发中断,同时,为了安全性更加稳定,EXIT可以设置多个条件才能启动中断;
功能框图
这里我们以按键操作中断为例:配置两个按键
void EXTI_Key_Config()
{
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
EXTI_NVIC_Config();
RCC_APB2PeriphClockCmd(KEY1_INT_GPIO_CLK,ENABLE);
GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStruct.GPIO_Pin=KEY1_INT_GPIO_PIN;
GPIO_Init(KEY1_INT_GPIO_PORT, &GPIO_InitStruct);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(KEY1_INT_EXTI_PORTSOURCE,KEY1_INT_EXTI_PINSOURCE);
EXTI_InitStruct.EXTI_Line=KEY1_INT_EXTI_LINE;
EXTI_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;
EXTI_InitStruct.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStruct);
RCC_APB2PeriphClockCmd(KEY2_INT_GPIO_CLK,ENABLE);
GPIO_InitStruct.GPIO_Pin=KEY2_INT_GPIO_PIN;
GPIO_Init(KEY2_INT_GPIO_PORT, &GPIO_InitStruct);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
GPIO_EXTILineConfig(KEY2_INT_EXTI_PORTSOURCE, KEY2_INT_EXTI_PINSOURCE);
EXTI_InitStruct.EXTI_Line=KEY2_INT_EXTI_LINE;
EXTI_InitStruct.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_Init(&EXTI_InitStruct);
}
//该函数放置在中断函数里面,函数名必须正确,这里是经过了宏定义
void KEY1_IRQHandler()
{
if(EXTI_GetITStatus(EXTI_Line0)!=RESET)
{
LED_G_TOGGLE;
}
EXTI_ClearITPendingBit(EXTI_Line0);
}
void KEY2_IRQHandler()
{
if(EXTI_GetITStatus(EXTI_Line13)!=RESET)
{
LED_R_TOGGLE;
}
EXTI_ClearITPendingBit(EXTI_Line13);
}
总结
EXIT它的作用是配置触发信号;
NVIC是真正的中断函数;
中断启动的过程是先经过EXIT再经过NVIC;
——参考资料野火开发指南