STM32外部中断

中断和事件

什么是中断

中断是指计算机运行过程中,出现某些意外情况需要主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原来被暂停的程序继续运行。

什么是EXTI

外部中断控制器(EXTI)管理了控制器的20个中断线,每个中断线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿检测。EXTI可以实现对每个中断线的单独配置,可以单独配置为中断或者事件,以及触发事件的属性。

外部中断线有20个,每个GPIO都可以被设置为输入线。占用EXTI0至EXTI15,还有另外四根用于特定的外设事件。那么中断线怎么和IO口对应那

image-20230123165807691

外部中断通用IO镜像

image-20230123165843282

从上图可以轻易地看出来:每个GPIOx的同一编号的引脚(共7个)与一条中断线对应。比如PA0、PB0、PC0、PD0、PE0、PF0、PG0一条中断线。EXTI0至 EXTI15用于 GPIO,通过编程控制可以实现任意一个 GPIO作为外部中断的输入源。

注意一下同一个时间,只能有一个IO口映射到同一个中断线。也就是说,PA0和PB0不能同一时间映射到同一个中断线,而PA0、PA1则可以同时映射,因为它们不是在同一个中断线上。

由上图可以PA0和PB0公用一个中断线,如果发生中断,在HAL_GPIO_EXTI_Callback()中如何判断时PA0触发的还是PB0触发的那

解决办法 : 我们可以在中断执行函数中,读取引脚状态来判断是哪个引脚触发的

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	//因为一根中断线上有多个中断源,判断是哪个中断源触发的,当引脚发生中断的时候,可肯定会发生电平的由高到低(下降沿触发)的变化,所以进入中断函数之后,判断一下引脚是否为低电平,如果是低电平说明是该引脚触发的
	if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_14) == GPIO_PIN_RESET)
	{
		Server = 1;
	}
}

中断服务函数

那么是不是16个中断线就可以分配16和中断服务函数那

答案也不是。在中断向量表中,IO口外部中断在中断向量表中只分配了7个中断向量,也就是只能使用7个中断服务函数

image-20230123170321228

从上图中可以看出,外部中断线59分配一个中断向量,共用一个服务函数;外部中断线1015分配一个中断向量,共用一个中断服务函数;而中断向量线0-4则单独使用一个中断服务函数。也就是说,IO口的外部中断最多只能使用7个。

优先级

  • 抢占优先级

高优先级的中断会打断原来的中断

举个例子:一开始你在摸鱼,这时候你的朋友找你打游戏,你暂停摸鱼,去和你朋友打游戏,打游戏的时候,你妈叫你吃饭,你会暂停打游戏去吃饭,回来继续打游戏,然后打完游戏接着摸鱼。

  • 响应优先级

响应优先级应用在抢占优先级相同的情况下,当两个中断的抢占优先级相同时,如果两个中断同时到达,则先处理响应优先级高的中断

  • 抢占优先级和响应优先级的区别

高优先级的抢占优先级可以打断正在进行的低抢占优先级中断

抢占优先级相同的两个中断,响应优先级高的中断不可以打断低响应优先级的中断

抢占优先级相同的两个中断,如果两个中断同时发生,会先执行响应中断级高的那个

如果两个中断的抢占优先级和响应优先级都一样,谁先发生就执行谁。

EXIT和NVIC

image-20230122154945499

EXIT可以分为两个部分,一个是产生中断,另一个是产生事件,这两个功能从硬件上就有所不同

产生中断线路目的是把输入信号输入到NVIC,进一步会运行中断服务函数,实现功能,这样是软件级别的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用,并且是电路级别的信号,属于硬件级别的。

什么是NVIC

NVIC是中断控制器,进行中断管理,重要是配置抢占优先级和响应优先级。

使用中断的方法点亮LED

步骤

1.配置时钟

image-20230122160220343 image-20230122160349985

2.配置GPIO

image-20230122160516088

将GPIO口 PA0配置为外部中断时,会选择其中断触发方式

image-20230122160714926

3.使能中断(设置NVIC)

将外部中断开关打开,并设置其优先级

image-20230122160827384

4.配置工程

找到中断执行函数

首先进入 stm32f1xx_it.c文件,找到EXTI0_IRQHandler函数

image-20230122161414837

点进HAL_GPIO_EXTI_IRQHandler函数,并按F12去寻找该函数的原函数

image-20230122161511657

然后找到HAL_GPIO_EXTI_Callback函数,这个函数就是中断事件触发时所执行的函数

image-20230122161553513

_weak表示为虚函数,将此函数复制到main中可以进行编辑

中断法实现按键点灯操作

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	//消抖处理
	switch(GPIO_Pin)
	{
		HAL_Delay(50);
		case GPIO_PIN_0:
			if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == RESET)
			{
				HAL_GPIO_TogglePin (GPIOB,GPIO_PIN_8);
			}
			break;
		case GPIO_PIN_1:
			if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_1) == RESET)
			{
				HAL_GPIO_TogglePin (GPIOB,GPIO_PIN_9);
			}
			break;
	}
}
//其中HAL_GPIO_EXTI_Callback的参数是哪个引脚触发的事件,根据触发中断的引脚不同,实现不同的效果
posted @ 2023-09-01 14:08  徐博正  阅读(746)  评论(0)    收藏  举报