stm32外部中断(EXTI)
0x01 中断和异常向量表
- 中断和异常向量名称在startup_stm32f10x.md里可以查看。
- 中断函数例程在stm32f10x_it.c里可以查看,没有例程的可通过中断和异常向量名称定义。
0x02 中断标志位
1.为什么要清除中断标志位?
响应中断条件是:中断使能和中断标志同时成立。
一般来讲,响应中断后,有硬件清标志和软件清标志两种。
因为你不止是要中断一次啊,你下一次中断咋办呢?
单片机要靠查询中断标志来判断是否要进入中断,如果你不清除中断标志,本次中断退出,单片机又会检测到中断标志,因此重复进入中断。
2.为什么在中断函数还要判断中断标志位?
还有不少中断,一个中断函数对应多个中断通道,就不得不加判断了。
0x03 EXTI配置流程
- 配置嵌套向量中断控制器NVIC(任何中断和异常处理都需要配置NVIC)
- 配置外部中断I/O口(外部中断通用I/O映像,不同的I/O口对应的EXIT不一样)
- 配置外部中断 EXTI 寄存器
- 定义中断函数(注意有些EXTI都对应一个中断函数 )
0x04 EXTI0配置代码
#include "bsp_exti.h"
void PA0_EXTI0_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line = EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
}
void EXTI0_IRQHandler(void)
{
if (EXTI_GetITStatus(EXTI_Line0) != RESET) {
GPIOA->ODR ^= GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4;
EXTI_ClearITPendingBit(EXTI_Line0);
}
}