易智联LM401模块学习(五)——外部中断

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

扩展中断和事件控制器(EXTI)通过可配置和直接的事件输入来管理各个CPU和系统的唤醒。它向电源控制提供唤醒请求,并向CPU NVIC产生中断请求,向CPU事件输入产生事件。


提示:以下是本篇文章正文内容,下面案例可供参考

一、外部中断特点

EXTI的主要特点如下:

  • 支持47个输入事件。
  • 大多数事件输入允许系统被唤醒。
  • 有些事件只能用于产生CPU唤醒事件。
  • 在外设中没有相关唤醒标志的事件,在EXTI中有一个标志,并从EXTI产生一个中断给CPU。
    异步事件输入被分为以下两组:
  • 可配置的事件(来自I/O或外设的信号能够产生一个脉冲),其特点如下:
  • 可选择的主动触发边缘
  • 中断等待状态寄存器位
  • 单独的中断和事件生成掩码,用于调节CPU的唤醒、中断和事件生成
  • SW触发的可能性
  • 直接事件(来自外设的中断和唤醒源,有一个相关的标志在外设中被清除),具有以下特点:
  • 固定上升沿主动触发
  • EXTI中没有中断等待状态寄存器位(中断等待状态标志由产生事件的外设提供)。
  • 单独的中断和事件生成掩码,用于调节CPU的唤醒和事件生成
  • 没有软件触发的可能性

二、外围设备和CPU之间的EXTI连接

当系统处于停止模式时,能够产生唤醒或中断事件的外设被连接到EXTI。
产生脉冲的外设唤醒信号或外设中没有中断状态位的外设,被连接到EXTI可配置的事件输入。对于这些事件,EXTI提供了一个需要被清除的状态等待位。正是与该状态位相关的EXTI中断对CPU进行了中断。
外设中断和唤醒信号在外设中具有一个状态位,需要在外设中被清除,被连接到EXTI直接事件输入。EXTI内没有状态等待位。中断或唤醒是由外设中的CPU清除的。是外设的中断直接中断了CPU。
EXTI可配置的事件中断与CPU的NVIC相连。
专用的EXTI/EVG CPU事件被连接到CPU的rxev输入。
EXTI CPU唤醒信号连接到PWR块,用于唤醒系统和CPU子系统总线时钟

三、功能和相关寄存器

	 要产生中断,必须先配置好并使能中断线。根据需要的边沿检测设置 2 个触发寄存器,同时在 中断屏蔽寄存器的相应位写“1”使能中断请求。当外部中断线上出现选定信号沿时,便会产生中断请求,对应的挂起位也会置 1。在挂起寄存器的对应位写“1”,将清除该中断请求。
	要产生事件,必须先配置好并使能事件线。根据需要的边沿检测设置 2 个触发寄存器,同时 在事件屏蔽寄存器的相应位写“1”允许事件请求。当事件线上出现选定信号沿时,便会产生事件脉冲,对应的挂起位不会置 1。
	通过在软件中对软件中断/事件寄存器写“1”,也可以产生中断/事件请求。

在这里插入图片描述
在这里插入图片描述

具体细节参考
在这里插入图片描述

四、STM32CubeMX工程创建

1、芯片选择,根据需求选择响应芯片
2、引脚设置
在这里插入图片描述
这里将PA0配置位外部中断模式,通过按键控制电平变化,触发外部中断
3、GPIO配置
在这里插入图片描述
在这里插入图片描述
外部中断模式 上升沿触发检测的(这里我们选择上升沿触发)
外部中断模式,下降沿触发检测、
外部中断模式,上升/下降沿触发检测
外部事件模式,上升沿触发检测
外部事件模式,下降沿触发检测
外部事件模式,上升/下降沿触发检测!

开启外部中断
在这里插入图片描述
4、时钟配置

这里我用的msi作为时钟源
5、配置路径,选择IDE,创建工程
在这里插入图片描述

五、keil代码部分

在这里插入图片描述
在编写外部中端服务函数是发现,嵌套调用了下
在这里插入图片描述
在这里插入图片描述

这是个弱定义,我们重新编写
在这里插入图片描述
在main中加入

uint8_t flag=0;
GPIO_PinState PinState;


void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
	
 if(GPIO_Pin==BUT_Pin){
	 //HAL_Delay(20);中断函数为了高效,不能加入延时函数
	   GPIO_PinState PinState=HAL_GPIO_ReadPin(GPIOA,BUT_Pin);
		 if(PinState==GPIO_PIN_SET){//按键按下一次
			/* if(flag==0){flag=1;HAL_GPIO_TogglePin(GPIOB,LED1_Pin);}
			 else if(flag==1){flag=2;HAL_GPIO_TogglePin(GPIOB,LED2_Pin);}
			 else if(flag==2){flag=3;HAL_GPIO_TogglePin(GPIOB,LED3_Pin);}
			 else if(flag==3){
				        flag=0;
			          HAL_GPIO_WritePin(GPIOB,LED1_Pin, GPIO_PIN_RESET);
							  HAL_GPIO_WritePin(GPIOB,LED2_Pin, GPIO_PIN_RESET);
							  HAL_GPIO_WritePin(GPIOB,LED3_Pin, GPIO_PIN_RESET);
			          		       
			 }*/
			  switch(flag){
							 case 0:
								// HAL_GPIO_WritePin(GPIOB,LED1_Pin, GPIO_PIN_SET);
                flag=1;
							 HAL_GPIO_TogglePin(GPIOB,LED1_Pin);	//点亮LED1				 
									break;
							 case 1:
								// HAL_GPIO_WritePin(GPIOB,LED2_Pin, GPIO_PIN_SET);
                flag=2;
							 HAL_GPIO_TogglePin(GPIOB,LED2_Pin);//点亮LED2
							 break;
							 case 2:
								 //HAL_GPIO_WritePin(GPIOB,LED3_Pin, GPIO_PIN_SET);
                 flag=3;
							   HAL_GPIO_TogglePin(GPIOB,LED3_Pin);//点亮LED3
							 break;
							 case 3://熄灭所有灯
								flag=0;
								HAL_GPIO_WritePin(GPIOB,LED1_Pin, GPIO_PIN_RESET);
							  HAL_GPIO_WritePin(GPIOB,LED2_Pin, GPIO_PIN_RESET);
							  HAL_GPIO_WritePin(GPIOB,LED3_Pin, GPIO_PIN_RESET);							  
							 break;
							 default:break;	
         							 
						 }  
				}

	 }
 }

 //发现按下去触发中断时可能会产生两次任务(预期是按下去就触发一次任务)。因为按键时会有抖动的,导致进入了两次中断

这里有个小BUG,正在解决,未完待续。。。。

总结

一个外部中断通道可以被多个pin使用,但同一时间只能有一个进行使用,通过多路复用器可以完成此操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值