易智联LM401模块学习(五)——外部中断
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 前言
- 一、外部中断特点
- 二、外围设备和CPU之间的EXTI连接
- 三、功能和相关寄存器
- 四、STM32CubeMX工程创建
- 五、keil代码部分
- 总结
前言
扩展中断和事件控制器(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);//点亮LED2break;case 2://HAL_GPIO_WritePin(GPIOB,LED3_Pin, GPIO_PIN_SET);flag=3;HAL_GPIO_TogglePin(GPIOB,LED3_Pin);//点亮LED3break;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使用,但同一时间只能有一个进行使用,通过多路复用器可以完成此操作
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
