[STM32F1官方例程讲解3] 外部中断EXTI

第一章 中断是什么

在这里插入图片描述
中断概念的解释可以通过一个简单的接电话过程来解释。假设一个人坐在在一个随时可能有人拨入的电话前,要求他能接到对方的电话,有两种方法:1. 隔个几分钟就拿起电话一次,听听有没有人说话;2. 等电话响起再拿起电话。
前一种方式被称为轮循(polling)。虽然轮询是检查状态变化的一种简单方法,但这样做是有代价的。如果检查间隔太长,则从发生到发现之间可能会有很长的时间间隔。如果在检查之前状态又变回原样,则可能会完全错过相关的事件。虽然较短的间隔将获得更快,更可靠的检测,但也意味着更多无用的检测,还会消耗更多的处理时间与算力。
后一种方式被称为中断(interrupt)。显然,后一种方法所需的精力更少,空余出来的时间允许用户去做其他事情。在嵌入式系统中也是如此:使用这种方法,状态更改会生成一个中断信号,该信号导致CPU暂停其当前操作(并保存其当前状态),然后执行与该中断相关的处理,然后恢复其先前状态并从中断处恢复。

第二章 STM32F1的中断结构

2.1 Cortex-M3 内核中断

在这里插入图片描述
在Cortex M3中,中断(Interrupt)是直接连接到位于内核的核心嵌套向量中断控制器(NVIC),提供了可嵌套中断支持(允许设置中断的优先级),向量中断支持(根据中断号从中断表中直接找出ISR入口地址,大大缩短中断延迟时间),动态优先级调整支持(可在程序运行时修改中断优先级)等中断特性,允许工程师配置快速的、对正常程序极少干扰的中断过程。
Cortex M3内核提供了能够支持11种系统异常,外加240个外部中断的嵌套向量中断控制器(NVIC),同时提供了可嵌套的使用方案,从而大大增强了M3内核处理中断的种类效率
当系统响应中断时,首先保存现场,调用中断服务函数清除中断标志,而后再恢复现场,执行刚刚执行一半的程序。

2.2 EXTI中断简介

在这里插入图片描述
在STM32F1中,外部中断EXTI管理了控制器的中断/事件线,如上图所示。例如,EXTI0中断线管理了由PA0~PE0的上的中断。此外,每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿的检测。EXTI允许对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性。

第三章 中断配置过程

3.1 电路原理图

在这里插入图片描述

本次实验平台选择mcudev生产的STM32F103C8T6平台,为了更好的显示中断的效果,对例程程序作了一点修改,将中断服务函数改成按一下按键就通过串口输出累计按下次数的值。原理图如上图所示,其按键连接到PA0。当按键按下时,PA0上会出现一个由高至低的电平变化,即下降沿,故中断线选为EXTI0,并且配置成下降沿检测

3.2 嵌套向量中断控制器(NVIC)配置

void NVIC_Config(void)
{
	NVIC_InitTypeDef   NVIC_InitStructure;
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
}

3.3 EXTI与GPIO配置

oid GPIO_Config(void)
{
	GPIO_InitTypeDef   GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void EXTI_Config(void)
{
	EXTI_InitTypeDef   EXTI_InitStructure;
	
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0); //使能PA0的中断源

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

	EXTI_InitStructure.EXTI_Line = EXTI_Line0;
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;
	EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt; //选择中断事件
	EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
	
	EXTI_Init(&EXTI_InitStructure);
}

3.4 EXTI中断服务函数

位于stm32f103_it.c内,其中count为全局变量。

int count=0;
void EXTI0_IRQHandler(void)
{
	if(EXTI_GetITStatus(EXTI_Line0) != RESET)
	{
		count=count+1;
		if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)==0) printf("%d\r\n",count);
		EXTI_ClearITPendingBit(EXTI_Line0);
	}
}

注意,不建议在中断函数内书写需要较长时间的printf等函数,有可能会造成程序卡死

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页