这篇文章主要学习外部中断的使用,中断的基础知识需要先了解一下
https://zhuanlan.zhihu.com/p/357655706
那么先查看中文参考手册,搜索并了解EXTI外部中断,先看一下EXTI外部中断的框图
配合着功能说明看框图,要产生中断要先配置再等待中断请求。先看配置部分,设置两个触发器寄存器也就是框图上的上升沿触发选择寄存器和下降沿触发选择寄存器,同时在中断屏蔽寄存器的相应位写1允许中断请求。那我们来先参考手册搜索这三个寄存器,也就是框图中从左往右数第一、第四、第五的寄存器,这三个寄存器如何配置先不谈,先流程
什么是挂起?挂起就是中断来了之后不会立马执行、等待cpu执行,这个过程叫挂起。发生一个期待的边沿后挂起寄存器的相应位被硬件自动置1,然后等待进入中断服务函数。进入之后由软件编程写入该位1将它清空,最后中断传到NVIC中断控制器。
NVIC又是什么?NVIC叫嵌套向量中断控制器,他是用来对中断分组的,怎么分组?是通过抢占优先级和子优先级来分组的,中断之间谁先执行先比较抢占优先级一样的话比较子优先级,都一样的话比较在中断顺序表位置先后。这个顺序表在启动文件startup_stm32f10x_hd.s中,那么就需要配置NVIC的抢占优先级和子优先级等属性了
那么产生中断在框图中的路线应该是这样的
通过IO口PA0按钮来触发中断,中断函数内反转LED1亮灭状态,这个过程相当于选择哪个外设触发外部中断。
先使能AFIO时钟,AFIO挂在APB2总线上,然后通过AFIO_GPIOCRx寄存器配置GPIO线上的外部中断,看AFIO_GPIOCRx寄存器这个寄存器的低16位是配置EXTI0 到EXTI3的抢占优先级和子优先级的,这样的寄存器还有三个AFIO_GPIOCR2、AFIO_GPIOCR3、AFIO_GPIOCR4,这四个寄存器配置了EXTI0~EXTI15的优先级。
那么整个流程按照框图应该是,
1、开启AFIO时钟、GPIO时钟
2、配置EXTI0、配置NVIC
3、写中断函数,中断函数中记得清楚挂起寄存器标志位之后再进行编程操作
EXTI配置属性:
NVIC属性:
通道在STM32f10x.h文件中
抢占优先级和子优先级根据需要填写,使能ENABLE
‘
以下最终代码:
#include "exti.h"
#include "led.h"
//外部中断线0的配置
void Exti0_Config(void)
{
//库函数
//开启AFIO时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
//1,选择PA0作为 EXTI0 的输入管脚
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);
//2,配置EXTI
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line0;//中断线0
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;//中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;//下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;//使能中断线
EXTI_Init(&EXTI_InitStructure);//初始化
//3,NVIC配置
NVIC_InitTypeDef NVIC_InitStruct={0};
NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;//中断通道
NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;//通道使能
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;//抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;//响应优先级
NVIC_Init(&NVIC_InitStruct);
}
//EXTI0中断服务函数
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0) == SET)
{
EXTI_ClearITPendingBit(EXTI_Line0);
LED1_F();
}
}