
外部中断
stm32所有的引脚都可以用来作为外部中断
stm32有16个引脚对应着16个中断线(EXTI_Line0~EXTI_Line15),要注意的是在配置中断向量表的时候,要注意16个中断线只对应了7个终端通道
EXTI_Line0~EXTI_Line4这5条分别对应着EXTI0_IRQn~EXTI4_IRQn
EXTI_Line5~EXTI_Line9 共用一条中断通道 EXTI9_5_IRQn
EXTI_Line10~EXTI_Line15 共用一条中断通道 EXTI15_10_IRQn
外部中断检测电平和利用程序检测引脚电平的区别
简单的功能:例如按键被按下就开启什么,且不在乎执行次数的
如果是单纯的检测电平的高低变化,使用GPIO_ReadInputDataBits这个库函数就可以了,简单方便,但是需要程序不断地去检测对应引脚的电平是否发生了改变
如果是单纯的检测电平的高低变化,且你不在意cpu的资源的时候,使用外部中断来达到检测目的,过程是比较“繁琐”的,需要开启对应的中断,对应的时钟、还要将中断源和中断线联系起来。
比较复杂的功能:按下按键执行功能,但是只能执行一次,且这个按键还处于一直被按下的状态,意味着一旦检测,仍是高(低)电平,又会被重复执行
这样的话,如果也是用程序进行检测的电平变化的话,需要在按键消抖之后,做一个标志,进行判断,如果是很多个按键的,就会照造成cpu开销变大,且响应不及时
采用外部中断的话则会很方便,设置好对应的边沿触发,就没问题了,
外部中断实现过程
开启对应时钟
初始化引脚
初始化外部中断,连接中断源和中断线
设置NVIC
代码
外部中断检测
#include "Exti.h" ///这是一个用来练手的知识点 //板载的led1 pb0 //led2 pb1 //k1 pa11 //k2 pa12 ///引脚初始化 void Test_GPIO_Config(){ GPIO_InitTypeDef GPIO_InitStructure; //定义一个GPIO_InitTypDef类型的结构体 RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //开启GPIB的外设时钟 RCC_APB2PeriphClockCmd( RCC_APB2Periph_AFIO,ENABLE ); //开启复用 ///按键初始化 GPIO_InitStructure.GPIO_Pin = K1_GPIO|K2_GPIO; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(K_Port,&GPIO_InitStructure); ///led灯初始化 GPIO_InitStructure.GPIO_Pin = Led1_GPIO|Led2_GPIO; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(Led_Port,&GPIO_InitStructure); } ///中断初始化 void Test_EXTI_Init(){ EXTI_InitTypeDef EXTI_InitStructure; //外部中断结构体 NVIC_InitTypeDef NVIC_InitStructure; //中断向量控制结构体 //配置外部中断 GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource11|GPIO_PinSource12); //连接中断源和中断线 EXTI_InitStructure.EXTI_Line = EXTI_Line11|EXTI_Line12; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_Init(&EXTI_InitStructure); //配置中断向量 //NVIC_PriorityGroupConfig( NVIC_PriorityGroup_0 ); //设置中断组别为0组 NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //配置中断通道 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x00; //抢占式优先级0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //响应优先级1 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能 NVIC_Init(&NVIC_InitStructure); } ///硬件初始化 void Hard_Init(){ Test_GPIO_Config(); //引脚初始化 Test_EXTI_Init(); //中断初始化 }
#好好学习!