【GD32】03 - EXTI外部中断

EXTI

EXTI,全称External Interrupt/Event Controller,即外部中断/事件控制器,是微控制器中的一个重要组成部分。它主要用于管理来自外部设备的中断和事件请求。以下是关于EXTI的详细介绍:

  1. 功能概述:
  • EXTI管理了控制器的多个中断/事件线,通常这些线路数量在STM32等微控制器中可以达到20个或更多。
  • 每个中断/事件线都对应有一个边沿检测器,可以实现输入信号的上升沿检测和下降沿检测。这意味着当外部信号的状态从低电平变为高电平(上升沿)或从高电平变为低电平(下降沿)时,EXTI可以检测到这种变化并产生相应的中断或事件。
  • EXTI可以实现对每个中断/事件线进行单独配置,可以单独配置为中断或者事件,以及触发事件的属性(如上升沿触发、下降沿触发或双边沿触发)。
  1. 两大功能:
  • 产生中断:当外部设备触发中断条件时,它会向EXTI发送中断请求。EXTI会接收并处理这些中断请求,并将信号传递给NVIC(Nested Vectored Interrupt Controller,嵌套向量中断控制器)进行处理。NVIC会根据中断的优先级来决定是否响应中断,并调用相应的中断服务程序。
  • 产生事件:除了产生中断外,EXTI还可以产生事件。这些事件可以用于触发某些特定的操作或行为,而无需进入中断服务程序。例如,可以使用EXTI来检测按钮的按下事件,并在检测到该事件时执行某个特定的任务或操作。
  1. 典型应用:
  • 在物联网应用中,NVIC和EXTI是常用的中断处理器和中断控制器。外部设备可以是各种传感器、开关、按钮等。当这些设备触发中断条件时,它们会向EXTI发送中断请求,EXTI会接收并处理这些请求,并触发相应的中断服务程序或事件处理程序。
  • 在嵌入式系统中,EXTI也常用于处理各种外设的中断请求,例如传感器数据的到达、网络通信的中断等。
  1. 结构特点:
  • EXTI的结构通常包括多个中断/事件线、边沿检测器、配置寄存器等部分。每个中断/事件线都可以单独进行配置,以选择请求类型和相应的触发事件。此外,EXTI还提供了丰富的库函数和API,方便开发人员进行编程和配置。

总的来说,EXTI是微控制器中一个重要的外部中断/事件控制器,它可以实现对外部设备的中断和事件请求的管理和处理。在物联网和嵌入式系统等领域中,EXTI具有广泛的应用前景和重要的价值。

以上介绍来自文心一言。

GD32中的EXTI

很常规的EXTI,与STM32不一样的是,GD32这边的优先级是只有2位配置中断优先级的。

再看看中断的流程。

那根据上面的框图,我们要实现外部中断,要配置的东西就是边沿检测,极性控制,中断屏蔽控制(NVIC)。

然后和STM32一样的是,我们是GPIO几,那么中断线就是几号。并且同一时间同一个引脚号只能使用一种端口(A,B,C)

固件库函数

首先我们除了需要打开拿来外部中断的GPIO的外设时钟之外。由于我们还需要将GPIO口映射到中断线上,因此还需要配置系统时钟。

rcu_periph_clock_enable(RCU_CFGCMP);

exti_init

初始化EXTI。

如果我们用的是GPIO的0号引脚,那么选择0号中断线(EXTI_0),一号引脚就选择1号中断线,以此类推。

模式一般选择中断模式EXTI_INTERRUPT

exti_interrupt_enable

中断使能,输入的参数指定中断线。

exti_interrupt_flag_get

获取指定中断线的标志位,当我们有多条中断线共用一个中断处理函数的时候可以帮助我们判断具体是哪一个中断线触发的中断。

exti_interrupt_flag_clear

清除指定中断线的中断标志位。

关于EXTI的函数就上面几个就够了。但是根据框图,我们还需要将GPIO映射到中断线上,以及配置NVIC的优先级。

syscfg_exti_line_config

根据上面表格的参数来填写,将我们使用的端口以及对应的中断线选上。因为中断线的序号和GPIO的引脚号是一致的,所以只需要说是EXTI的哪个引脚(中断线)即可。

nvic_irq_enable

使能NVIC中断并且配置优先级。

可以自行去官方提供的固件库使用指南去寻找可以使用的枚举类型。

比如说我使用GPIO的0号引脚,那么我就使用红框框中的参数。

一切准备就绪,我们就可以开始中断了,最后一个问题就是中断处理函数,和STM32一样,我们去启动文件中的汇编文件里寻找。

示例代码

#include "gd32e23x.h"
#include "systick.h"
#include <stdio.h>
#include "OLED.h"

int count=0;

void EXTI0_1_IRQHandler(void){
    if(exti_interrupt_flag_get(EXTI_0) == SET){        //获取中断线0的标志位
        if(!gpio_input_bit_get(GPIOA,GPIO_PIN_0)){     //消抖处理
            delay_ms(15);
            gpio_bit_toggle(GPIOA, GPIO_PIN_5);
            count++;
        }
        exti_interrupt_flag_clear(EXTI_0);              //清除标志位
    }
}

int main(void){
    systick_config();       //延时函数初始化
    OLED_Init();
    
    rcu_periph_clock_enable(RCU_GPIOA);         //打开GPIOA的外设时钟
    rcu_periph_clock_enable(RCU_CFGCMP);        //配置系统时钟
    
    gpio_mode_set(GPIOA,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_PIN_5);            //GPIOA5输出模式
    gpio_output_options_set(GPIOA,GPIO_OTYPE_PP,GPIO_OSPEED_2MHZ,GPIO_PIN_5);   
    
    gpio_mode_set(GPIOA,GPIO_MODE_INPUT,GPIO_PUPD_PULLDOWN,GPIO_PIN_0);         //GPIOA0下拉输入模式
    nvic_irq_enable(EXTI0_1_IRQn, 1);                                           //NVIC分配优先级
    
    syscfg_exti_line_config(EXTI_SOURCE_GPIOA,EXTI_SOURCE_PIN0);                //将GPIO口映射到中断线上
    
    exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING);                       //EXTI初始化
    
    exti_interrupt_enable(EXTI_0);                                              //中断使能
    
    while(1){
        OLED_ShowNum(1,1,count,2);
        delay_ms(1000);
    }
}


  • 17
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
w5500是一款高性能的以太网控制器,它支持外部中断(exti)功能,可以用于接收数据。下面是一段gd32代码的示例,用于实现w5500外部中断(exti)接收数据的功能: ```c // 包含所需的头文件 #include "gd32f30x_exti.h" #include "gd32f30x_gpio.h" #include "gd32f30x_rcu.h" #include "gd32f30x_usart.h" // 定义w5500的中断引脚和SPI接口的引脚 #define W5500_INT_PIN GPIO_PIN_0 #define W5500_INT_GPIO_PORT GPIOB #define W5500_INT_GPIO_CLK RCU_GPIOB #define W5500_SCK_PIN GPIO_PIN_5 #define W5500_SCK_GPIO_PORT GPIOB #define W5500_SCK_GPIO_CLK RCU_GPIOB #define W5500_MISO_PIN GPIO_PIN_4 #define W5500_MISO_GPIO_PORT GPIOB #define W5500_MISO_GPIO_CLK RCU_GPIOB #define W5500_MOSI_PIN GPIO_PIN_3 #define W5500_MOSI_GPIO_PORT GPIOB #define W5500_MOSI_GPIO_CLK RCU_GPIOB // w5500初始化函数 void w5500_init() { // 初始化SPI接口 spi_parameter_struct spi_init_struct; spi_i2s_deinit(SPI0); spi_struct_para_init(&spi_init_struct); spi_init_struct.trans_mode = SPI_TRANSMODE_FULLDUPLEX; spi_init_struct.device_mode = SPI_MASTER; spi_init_struct.frame_size = SPI_FRAMESIZE_8BIT; spi_init_struct.clock_polarity_phase = SPI_CK_PL_LOW_PH_1EDGE; spi_init_struct.nss = SPI_NSS_SOFT; spi_init_struct.prescale = SPI_PSC_256; spi_init(SPI0, &spi_init_struct); spi_enable(SPI0); // 初始化外部中断引脚 rcu_periph_clock_enable(W5500_INT_GPIO_CLK); gpio_init(W5500_INT_GPIO_PORT, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, W5500_INT_PIN); // 配置外部中断触发方式为上升沿 exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_RISING); exti_interrupt_flag_clear(EXTI_0); exti_interrupt_enable(EXTI_0); } // 外部中断0中断处理函数 void EXTI0_IRQHandler(void) { if (exti_interrupt_flag_get(EXTI_0) == SET) { // 处理接收到的数据 uint8_t data = spi_i2s_data_receive(SPI0); // ... // 在此处添加具体的数据处理逻辑 // ... exti_interrupt_flag_clear(EXTI_0); } } int main(void) { // 初始化w5500 w5500_init(); while (1) { // 主程序中的其他代码逻辑 // ... } } ``` 以上是一段gd32代码的示例,用于实现w5500外部中断(exti)接收数据的功能。在代码中,首先定义了w5500的中断引脚和SPI接口的引脚,然后在w5500_init函数中对SPI接口和外部中断引脚进行了初始化配置。在EXTI0_IRQHandler中断处理函数中,可以处理接收到的数据,具体的数据处理逻辑可以根据实际需求进行编写。在主程序中,可以添加其他的代码逻辑。 希望以上的回答能够帮助到您!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值