STM32之中断(二)

1. EXTI

1.1 EXTI的简介

• EXTI 是 External Interrupt 的缩写,表示外部中断事件控制器 。EXTI 可以监测指定 GPIO 的电平信号变化,并在检测到指定条件时,向内核的中断控制器NVIC 发出中断申请。NVIC 在裁决后,如果满足条件,会中断CPU的主程序,使CPU转而执行EXTI对应的中断服务程序。

• EXTI 支持的触发方式:上升沿、下降沿、双边沿或软件触发。并且上升沿、下降沿、双边沿这三种方式是常用触发方式,都可以在配置GPIO口的mode中配置,上升沿(GPIO_MODE_IT_RISING),下降沿(GPIO_MODE_IT_FALLING),双边沿(GPIO_MODE_IT_RISING_FALLING)。

• EXTI 支持所有的GPIO口,但需要注意的是,相同的 Pin 不能同时触发中断。例如,PA0 和 PB0 不能同时被 配置为中断源。

• EXTI 提供了16 GPIO_Pin 的中断线 ,以及额外的中断线如 PVD 输出、RTC 闹钟 、USB 唤醒和以太网唤醒。(注意只有互联网芯片才有以太网)。

1.2 中断和事件区别:

• 中断会打断CPU当前正在执行的程序,转而去执行中断服务程序,待中断服务程序执行完毕后,CPU会返回到原来的程序执行点继续执行。

• 事件只是简单地表示某个动作或状态的变化 ,而不会打断CPU当前正在执行的程序。当事件发生时,它会根据配置 来决定是否触发相应的中断。如果开放了对应的**中断屏蔽位,**事件就可以触发相应的中断,如果没有开放相应的中断屏蔽位,事件只会作为一个信号存在,不会被CPU处理。

1.3 EXTI基本结构,如图:

2. AFIO

• AFIO 是 Alternate Function Input/Output 的缩写,表示复用功能IO ,主要用于实现 IO 端口的复用功能 以及外部中断的控制

• STM32上有很多 IO口以及内置外设(如I2C、ADC、SPI、USART等)。为了节省引出引脚的数量,这些内置外设通常与 IO 口共用管脚,即 IO 管脚具有复用功能。例如,一个 GPIO 管脚除了可以作为普通的 IO端口外,还可以被复用为某个内置外设的功能引脚。

• 然而,为了优化64脚或100脚封装的外设数量,有时需要将一些复用功能重新映射到其他引脚上。这时,就可以使用AFIO的复用重映射功能。通过设置复用重映射和调试IO配置寄存器(AFIO_MAPR),可以实现引脚的重新映射,使得复用功能不再映射到它们的原始分配上。

• 此外,AFIO 还用于控制外部中断用来配置 EXTI 中断线 0~15 对应哪个具体 IO

• 当需要使能外部中断线进行外部中断线的映射 时,通常需要开启AFIO 的时钟

• AFIO与IO对应关系,如图:

3. EXIT的配置流程

• 使能GPIO时钟__HAL_RCC_GPIOx_CLK_Enable();

• 设置GPIO输入模式

• 设置AFIO(开启时钟,IO映射)

• 设置EXTI(屏蔽,上下沿)

• 以上三步均在HAL_GPIO_init()函数进行配置,HAL库函数已经对相应寄存器进行封装了

• 设置NVIC(优先级分组,设置优先级,使能中断)

• 设置中断服务函数(EXTIx_IRQHandler())

4. 实操,按键电灯(中断法),按下 KEY1 翻转 LED1 状态,而 LED2 一直保持 500ms 的频率闪烁。

4.1 main.c

cpp 复制代码
#include "sys.h"
#include "exti.h"
#include "delay.h"
#include "led.h"


int main(void)
{
    HAL_Init();                         /* 初始化HAL库 */
    stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
    led_init();                         /* LED初始化 */
    exti_init();

    while(1)//流水灯实验
    { 
        led2_on();
        delay_ms(500);
        led2_off();
        delay_ms(500);
    }
}

4.2 led.c

cpp 复制代码
#include "led.h"

void led_init(){
    GPIO_InitTypeDef gpio_init = {0};
    __HAL_RCC_GPIOB_CLK_ENABLE();//使能GPIO时钟
    gpio_init.Mode = GPIO_MODE_OUTPUT_PP;
    gpio_init.Pin = GPIO_PIN_8 | GPIO_PIN_9;//推挽输出
    gpio_init.Pull = GPIO_PULLUP;//默认上拉
    gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB,&gpio_init);//初始化gpio
    led1_off();//关灯
    led2_off();

}


void led1_on(){
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
}

void led1_off(){
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
}


void led1_toggle(){
    HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_8);
}

void led2_on(){
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
}

void led2_off(){
    HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);
}


void led2_toggle(){
    HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_9);
}

4.3 exti.c

cpp 复制代码
#include "exti.h"
#include "delay.h"
#include "led.h"

void exti_init(){
    GPIO_InitTypeDef gpio_init = {0};
    __HAL_RCC_GPIOA_CLK_ENABLE();//使能GPIO时钟
    gpio_init.Mode = GPIO_MODE_IT_FALLING;//下降沿触发中断
    gpio_init.Pin = GPIO_PIN_0;//推挽输出
    gpio_init.Pull = GPIO_PULLUP;//默认上拉
    gpio_init.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA,&gpio_init);//初始化gpio
    HAL_NVIC_SetPriority(EXTI0_IRQn,2,0);//设置优先级
    HAL_NVIC_EnableIRQ(EXTI0_IRQn);//使能中断
}

void EXTI0_IRQHandler(){//中断服务函数没参数和返回值
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);//中断服务公共函数

}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){
    delay_ms(20);//消抖
    if(GPIO_Pin == GPIO_PIN_0){
        if(HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0) == GPIO_PIN_RESET)
             led1_toggle();
    }
}
相关推荐
单片机杂货铺3 小时前
基于单片机的智能粮仓控制系统设计与实现
stm32·单片机·嵌入式硬件·物联网·计算机外设·51单片机·课程设计
指尖的爷3 小时前
RKNN转化环境搭建(rknn_toolkit2新版本)
嵌入式硬件·深度学习·物联网·目标检测
梁朝辉3 小时前
滴泪的曲线(Curved)还是直线(Line)什么区别,都应用于什么场景!
嵌入式硬件·硬件工程
clear sky .5 小时前
stm32H7进入HardFault_Handler机制
stm32·单片机·嵌入式硬件
小僧景贤5 小时前
STM32 GPIO 详解(含寄存器、HAL 库、电气特性、低功耗深度剖析)
stm32·单片机·嵌入式硬件
远翔调光芯片^138287988727 小时前
从参数到应用:FP7208如何以0.2V精密反馈提升LED驱动性能
科技·单片机·嵌入式硬件·智能家居·能源
碧海银沙音频科技研究院8 小时前
4 BES2710编译环境搭建方法
嵌入式硬件·算法
别催小唐敲代码9 小时前
STM32 定时器学习笔记:TIM 架构、输入捕获与 PWM 一篇讲透
笔记·stm32·学习
csdn杰哥9 小时前
瑞萨单片机AI教程【六】导入外部电机状态数据训练模型
人工智能·单片机·嵌入式硬件·瑞萨·ra6m5
深念Y10 小时前
ZTE_UZ901_NVRAM经验总结
linux·服务器·网络·嵌入式硬件·嵌入式·随身wifi