2-1 EXTI外部中断(gd32)

2024-05-12 19:20
文章标签 中断 外部 gd32 exti

本文主要是介绍2-1 EXTI外部中断(gd32),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

中断的概念

中断硬件结构/软件结构

EXTI中断

EXTI硬件结构

注:EXTI线在同一时刻只能连接一个GPIO口,如果我们先连接了PA0,然后又连接了PB0那么此时PA0这个IO口就失去作用。

中断触发函数

中断优先级

中断优先级

数值越小优先级越高,抢占优先级可以实现中断嵌套的效果,不同的分组有不同的抢占优先级

EXTI外部中断配置

配置步骤

根据学习库函数原理配置步骤一般为如下所示(类比学习hal库函数原理)

1:配置AFIO,中断引脚寻找

2:配资EXTI,边沿检测以及控制

3:配置NVIC,嵌套中断向量控制器(用于统一分配和管理优先级)

注:按照步骤将下图打通即可

配置EXTI外部中断

static void KeyExtiInit(void)
{/*使能EXTI时钟*/rcu_periph_clock_enable(RCU_AF);/*I/O连接到EXTI线*/gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_0);
//	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_0);//gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_0);/*配置上升/下降沿*/exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING);/*清除标志*/exti_interrupt_flag_clear(EXTI_0);/*使能中断*/nvic_irq_enable(EXTI0_IRQn, 1, 0);/*key2*/gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOG, GPIO_PIN_SOURCE_13);/*配置上升/下降沿*/exti_init(EXTI_13, EXTI_INTERRUPT, EXTI_TRIG_FALLING);/*清除标志*/exti_interrupt_flag_clear(EXTI_13);/*KEY3*/gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOG, GPIO_PIN_SOURCE_14);/*配置上升/下降沿*/exti_init(EXTI_14, EXTI_INTERRUPT, EXTI_TRIG_FALLING);/*清除标志*/exti_interrupt_flag_clear(EXTI_14);// 使能中断nvic_irq_enable(EXTI10_15_IRQn, 1, 0);}

中断服务函数代码

 

// EXTI0中断服务函数,对应PA0口
void EXTI0_IRQHandler(void){// 判断中断标志位,产生中断时标志位会设置为1if( exti_interrupt_flag_get(EXTI_0) == SET){// 此时说明进入中断ToggleLed(LED1);		// 清除标志位,如果标志位没有清除为0,//会不断地进入中断服务函数当中,所以要清除中断标志位exti_interrupt_flag_clear(EXTI_0);}
}uint8_t flag = 0;// EXTI_10_15中断服务函数,对应PA0口
void EXTI10_15_IRQHandler(void){// 判断中断标志位,产生中断时标志位会设置为1if( exti_interrupt_flag_get(EXTI_13) == SET){// 此时说明进入中断ToggleLed(LED2);		// 清除标志位,如果标志位没有清除为0,会不断地进入中断服务函数当中,// 所以要清除中断标志位exti_interrupt_flag_clear(EXTI_13);			}// 判断中断标志位,产生中断时标志位会设置为1if( exti_interrupt_flag_get(EXTI_14) == SET){// 此时说明进入中断ToggleLed(LED3);		// 清除标志位,如果标志位没有清除为0,会不断地进入中断服务函数当中,// 所以要清除中断标志位exti_interrupt_flag_clear(EXTI_14);flag = 1;			}
}

 整个程序的完整结构

KEY_DRV.c代码

#include <stdint.h>
#include "gd32f30x.h"
#include "KEY_DRV.h"
#include <stdint.h>
#include "LED.h"static void KeyGpioInit(void)
{rcu_periph_clock_enable(RCU_GPIOA);gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_2MHZ, GPIO_PIN_0);// 初始化剩下的两个按键rcu_periph_clock_enable(RCU_GPIOG);gpio_init(GPIOG, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_2MHZ, GPIO_PIN_13);gpio_init(GPIOG, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_2MHZ, GPIO_PIN_14);
}static void KeyExtiInit(void)
{/*使能EXTI时钟*/rcu_periph_clock_enable(RCU_AF);/*I/O连接到EXTI线*/gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA, GPIO_PIN_SOURCE_0);
//	gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_0);//gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOC, GPIO_PIN_SOURCE_0);/*配置上升/下降沿*/exti_init(EXTI_0, EXTI_INTERRUPT, EXTI_TRIG_FALLING);/*清除标志*/exti_interrupt_flag_clear(EXTI_0);/*使能中断*/nvic_irq_enable(EXTI0_IRQn, 1, 0);/*key2*/gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOG, GPIO_PIN_SOURCE_13);/*配置上升/下降沿*/exti_init(EXTI_13, EXTI_INTERRUPT, EXTI_TRIG_FALLING);/*清除标志*/exti_interrupt_flag_clear(EXTI_13);/*KEY3*/gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOG, GPIO_PIN_SOURCE_14);/*配置上升/下降沿*/exti_init(EXTI_14, EXTI_INTERRUPT, EXTI_TRIG_FALLING);/*清除标志*/exti_interrupt_flag_clear(EXTI_14);// 使能中断nvic_irq_enable(EXTI10_15_IRQn, 1, 0);}/**
***********************************************************
* @brief 按键硬件初始化
* @param
* @return 
***********************************************************
*/
void KeyDrvInit(void)
{KeyGpioInit();KeyExtiInit();
}// EXTI0中断服务函数,对应PA0口
void EXTI0_IRQHandler(void){// 判断中断标志位,产生中断时标志位会设置为1if( exti_interrupt_flag_get(EXTI_0) == SET){// 此时说明进入中断ToggleLed(LED1);		// 清除标志位,如果标志位没有清除为0,//会不断地进入中断服务函数当中,所以要清除中断标志位exti_interrupt_flag_clear(EXTI_0);}
}uint8_t flag = 0;// EXTI_10_15中断服务函数,对应PA0口
void EXTI10_15_IRQHandler(void){// 判断中断标志位,产生中断时标志位会设置为1if( exti_interrupt_flag_get(EXTI_13) == SET){// 此时说明进入中断ToggleLed(LED2);		// 清除标志位,如果标志位没有清除为0,会不断地进入中断服务函数当中,// 所以要清除中断标志位exti_interrupt_flag_clear(EXTI_13);			}// 判断中断标志位,产生中断时标志位会设置为1if( exti_interrupt_flag_get(EXTI_14) == SET){// 此时说明进入中断ToggleLed(LED3);		// 清除标志位,如果标志位没有清除为0,会不断地进入中断服务函数当中,// 所以要清除中断标志位exti_interrupt_flag_clear(EXTI_14);flag = 1;			}
}

KEY_DRV.h代码

#ifndef _KEY_DRIVE_H_
#define _KEY_DRIVE_H_
#include <stdint.h>void KeyDrvInit(void);#endif

LED.C

#include "gd32f30x.h"                   // Device header
#include "Delay.h"// 结构体初始化
typedef struct{rcu_periph_enum rcu;uint32_t gpio;uint32_t pin;}Led_GPIO_t;// 保存GPIO口的资源信息
static Led_GPIO_t g_gpioList[] = {{RCU_GPIOA,GPIOA,GPIO_PIN_8},{RCU_GPIOE,GPIOE,GPIO_PIN_6},{RCU_GPIOF,GPIOF,GPIO_PIN_6},
};
// 获取内存空间的大小
#define LED_NUM_MAX (sizeof(g_gpioList)/sizeof(g_gpioList[0]))void LedDrv_Init(void){uint8_t i = 0;for(i = 0; i < LED_NUM_MAX;i++){rcu_periph_clock_enable(g_gpioList[i].rcu);gpio_init(g_gpioList[i].gpio,GPIO_MODE_OUT_PP,GPIO_OSPEED_2MHZ,g_gpioList[i].pin);// 熄灭LED灯	gpio_bit_reset(g_gpioList[i].gpio,g_gpioList[i].pin);	}
}void TurnOnLed(uint8_t ledNO){if(ledNO >= LED_NUM_MAX){return;}gpio_bit_set(g_gpioList[ledNO].gpio,g_gpioList[ledNO].pin);
};void TrunOffLed(uint8_t LedOff){if(LedOff >= LED_NUM_MAX){return;}gpio_bit_reset(g_gpioList[LedOff].gpio,g_gpioList[LedOff].pin);
};// led状态取反
void ToggleLed(uint8_t ledNO){FlagStatus bit_state;bit_state = gpio_input_bit_get(g_gpioList[ledNO].gpio,g_gpioList[ledNO].pin);// 当获取到的数据为0的时候 1 -0 等于 0 ,当获取到的数据为1的时候 1 - 1 = 0;bit_state = (FlagStatus)(1 - bit_state); gpio_bit_write(g_gpioList[ledNO].gpio,g_gpioList[ledNO].pin,bit_state);};

LED.H

 

#ifndef _LED_H_
#define _LED_H_#include <stdint.h>#define LED1 0
#define LED2 1
#define LED3 2void LedDrv_Init(void);
// 点亮LED ledNO 标号0-2
void TurnOnLed(uint8_t ledNO);
void TrunOffLed(uint8_t LedOff);
void ToggleLed(uint8_t ledNO);#endif

main.c

#include <stdint.h>
#include "gd32f30x.h"
#include "Delay.h"
#include "LED.h"
#include "KEY_DRV.h"extern uint8_t flag;
int main(void)
{    LedDrv_Init();KeyDrvInit();while(1){if(flag == 1){/*执行led是否被按下*/flag = 0;}	} }

仿真调试

 

按键运算补充

抢占优先级的作用

注:高优先级的任务会抢占低优先级的任务,数值越小表示优先级别越高,当抢占式优先级相同时

如果有一个任务响应式优先级更高,但是实际上抢占还是不会发生,仍然是执行前面优先级部分。

这篇关于2-1 EXTI外部中断(gd32)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/983510

相关文章

vue-cil项目中使用外部js的3种方法

vue-cil项目中 1. 导入属性的方法 新建 ./api/api.js import Vue from 'vue';Vue.prototype.test=function () {alert(111)} 在main.js 中导入; import * as API from './api/api.js' 在任何一个.vue文件中都可以使用此属性.例如 在a.vue中 this.t

按顺序加载外部资源js css

cmmon.js /*** 公共js文件* 内置参数说明:* locationUrl:硬盘路径(开发模式使用)* ytRootUrl:系统根目录,引入该js文件后可直接使用* initJq:自定义jq文件的目录,如果需要引用不同的jq文件,请修改目录。* initCssUrl:初始化css文件容器,如果需要新增或修改引入的c

SpringBoot-注解@PropertiySource读取外部属性文件

@ConfigurationProperties和@Value两个注解能从配置文件中获取数据,但是前面讲了他们是从全局配置文件中获取,且只能从全局配置文件中获取,那么如果是一些数值类的数据放在全局配置文件里,是不怎么合适的,我们往往会把他们分离出来,比如前面的课程中Spring的xml配置文件里,与数据库链接的信息,我们是分离出来放在jdbc.properties里,然后在spring.xml里用

如何实现外部编码器轴和虚轴电子齿轮比例随动(汇川AM400PLC)

1、如何添加虚轴可以参考下面文章链接: 如何添加虚轴(AM400PLC)-CSDN博客文章浏览阅读2次。EtherCAT运动控制总线启用的时候,选择EtherCAT总线任务周期。选择好后,选择点击添加。https://blog.csdn.net/m0_46143730/article/details/139898985?csdn_share_tail=%7B%22type%22%3A%22blo

【GD32】从零开始学兆易创新32位微处理器——RTC实时时钟+日历例程

1 简介 RTC实时时钟顾名思义作用和墙上挂的时钟差不多,都是用于记录时间和日历,同时也有闹钟的功能。从硬件实现上来说,其实它就是一个特殊的计时器,它内部有一个32位的寄存器用于计时。RTC在低功耗应用中可以说相当重要,因为在使用外部低速晶振的条件下,它在所有的低功耗模式下都可以工作,这使得RTC很适合实现芯片的低功耗唤醒。下面是RTC的框图。 咋一看RTC的内部还挺复杂的。 2 硬件时

51单片机STC89C52RC——6.1 中断系统

一,文字层面理解          反正我看下面的几段文字时脑壳没有正常运转。一个头几个大         中断系统是为使CPU具有对外界紧急事件的实时处理能力而设置的。         当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作,这样的过程称为中断。实现这种功能的部件

STM32 EXTI(外部中断)和NVIC(嵌套向量中断控制器)学习

STM32 EXTI(外部中断)和NVIC(嵌套向量中断控制器)学习 在STM32中EXTI有0~18个事件/中断,0~4各自都是单独的一个通道,5~9是共一个通道,10~15共享一个通道,16/17/18各自独立用到一个通道 在STM32中NVIC是嵌套向量中断控制器,分为0~4五个组,称之为(Group) NVIC_PriorityGroup_0 ~ NVIC_Priorit

外部存储器

外部存储器是主存的后援设备,也叫做辅助存储器,简称外存或辅存。 它的特点是容量大、速度慢、价格低,可以脱机保存信息,属于非易失性存储器。 外存主要有:光盘、磁带、磁盘;磁盘和磁带都属于磁表面存储器。 目前广泛运用的固态硬盘(SSD)主要由闪存芯片构成,属于半导体存储器。 1.磁盘存储器 磁盘分为硬磁盘和软磁盘,现在大多用硬磁盘。 优点:容量大、位价低;记录介质可重复使用(可以多次读写)

红队内网攻防渗透:内网渗透之内网对抗:信息收集篇自动项目本机导出外部打点域内通讯PillagerBloodHound

红队内网攻防渗透 1. 内网自动化信息收集1.1 本机凭据收集类1.1.1、HackBrowserData 快速获取浏览器的账户密码1.1.2、Searchall 快速搜索服务器中的有关敏感信息还有浏览器的账户密码1.1.3、Pillager 适用于后渗透期间的信息收集工具,可以收集目标机器上敏感信息 1.2 对外打点扫描类1.2.1、FScan内网综合扫描工具,方便一键自动化、全方位漏扫扫

GD32 MCU的选项字节是什么?

GD32 MCU的选项字节是什么,有什么功能呢?选项字节被误篡改如何回复? 读者朋友们是否会有以上的疑问,首先我们先为大家介绍选项字节是什么以及选项字节的功能。 以GD32F30X系列MCU为例,其选项字节说明如下表所示,该选项字节共16个字节,用于芯片内部配置。具体说明如下:SPC为读保护控制位,可以设置芯片读保护;SPCN为SPC补字节,不需要配置;USER为用户配置字节,可以配置芯片从B