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();
    }
}
相关推荐
于小猿Sup10 小时前
VMware在Ubuntu22.04驱动Livox Mid360s
linux·c++·嵌入式硬件·自动驾驶
chao18984411 小时前
STM32 HAL库驱动AT24C02 EEPROM例程
stm32·单片机·嵌入式硬件
不会武功的火柴12 小时前
SystemVerilog语法(8)-有限状态机(FSM)
嵌入式硬件·fpga开发·自动化·ic验证·rtl·uvm方法学
猫猫的小茶馆14 小时前
【Python】函数与模块化编程
linux·开发语言·arm开发·驱动开发·python·stm32
feifeigo12314 小时前
STM32矩阵键盘驱动(库函数版)实现
stm32·矩阵·计算机外设
嵌入式小站15 小时前
STM32 零基础可移植教程 05:按键消抖,为什么按一次会触发好几次
chrome·stm32·嵌入式硬件
czhaii15 小时前
跟我动手学FX系列PLC GX2环境
嵌入式硬件
拾知_H16 小时前
STM32/Delay延时函数编程思路
stm32·单片机·时钟·延时
2zcode17 小时前
基于STM32的智能扫地机器人设计与实现
stm32·嵌入式硬件·机器人
jllllyuz18 小时前
单相并网逆变器控制代码实现(STM32版)
stm32·单片机·嵌入式硬件