STM32外部中断
中断和事件
什么是中断
中断是指计算机运行过程中,出现某些意外情况需要主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原来被暂停的程序继续运行。
什么是EXTI
外部中断控制器(EXTI)管理了控制器的20个中断线,每个中断线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿检测。EXTI可以实现对每个中断线的单独配置,可以单独配置为中断或者事件,以及触发事件的属性。
外部中断线有20个,每个GPIO都可以被设置为输入线。占用EXTI0至EXTI15,还有另外四根用于特定的外设事件。那么中断线怎么和IO口对应那

外部中断通用IO镜像

从上图可以轻易地看出来:每个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个中断服务函数。

从上图中可以看出,外部中断线59分配一个中断向量,共用一个服务函数;外部中断线1015分配一个中断向量,共用一个中断服务函数;而中断向量线0-4则单独使用一个中断服务函数。也就是说,IO口的外部中断最多只能使用7个。
优先级
- 抢占优先级
高优先级的中断会打断原来的中断
举个例子:一开始你在摸鱼,这时候你的朋友找你打游戏,你暂停摸鱼,去和你朋友打游戏,打游戏的时候,你妈叫你吃饭,你会暂停打游戏去吃饭,回来继续打游戏,然后打完游戏接着摸鱼。
- 响应优先级
响应优先级应用在抢占优先级相同的情况下,当两个中断的抢占优先级相同时,如果两个中断同时到达,则先处理响应优先级高的中断
- 抢占优先级和响应优先级的区别
高优先级的抢占优先级可以打断正在进行的低抢占优先级中断
抢占优先级相同的两个中断,响应优先级高的中断不可以打断低响应优先级的中断
抢占优先级相同的两个中断,如果两个中断同时发生,会先执行响应中断级高的那个
如果两个中断的抢占优先级和响应优先级都一样,谁先发生就执行谁。
EXIT和NVIC
 
EXIT可以分为两个部分,一个是产生中断,另一个是产生事件,这两个功能从硬件上就有所不同
产生中断线路目的是把输入信号输入到NVIC,进一步会运行中断服务函数,实现功能,这样是软件级别的。而产生事件线路目的就是传输一个脉冲信号给其他外设使用,并且是电路级别的信号,属于硬件级别的。
什么是NVIC
NVIC是中断控制器,进行中断管理,重要是配置抢占优先级和响应优先级。
使用中断的方法点亮LED
步骤
1.配置时钟
 
 
2.配置GPIO
 
将GPIO口 PA0配置为外部中断时,会选择其中断触发方式

3.使能中断(设置NVIC)
将外部中断开关打开,并设置其优先级
 
4.配置工程
找到中断执行函数
首先进入 stm32f1xx_it.c文件,找到EXTI0_IRQHandler函数

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

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

_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的参数是哪个引脚触发的事件,根据触发中断的引脚不同,实现不同的效果
 
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号