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

相关文章

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

FreeRTOS学习笔记(四)Freertos的中断管理及临界保护

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Cortex-M 中断管理1.1 中断优先级分组1.2 相关寄存器1.3 相关宏定义1.4 FreeRTOS 开关中断 二、临界段及其保护2.1 taskENTER_CRITICAL( ) 和 taskEXIT_CRITICAL( )2.2 taskENTER_CRITICAL_FROM_ISR( )

C8T6超绝模块--EXTI

C8T6超绝模块–EXTI 大纲 控制流程结构体分析EXTI实现按键 具体案例 控制流程 这里是流程框图,具体可以去看我STM32专栏的EXTI的具体分析 结构体分析 typedef struct {uint32_t EXTI_Line; // 中断/事件线EXTIMode_TypeDef EXTI_Mode; // EXTI 模式EXTITrigger_TypeDef EXTI_

Cortex-A7:ARM官方推荐的嵌套中断实现机制

0 参考资料 ARM Cortex-A(armV7)编程手册V4.0.pdf ARM体系结构与编程第2版 1 前言 Cortex-M系列内核MCU中断硬件原生支持嵌套中断,开发者不需要为了实现嵌套中断而进行额外的工作。但在Cortex-A7中,硬件原生是不支持嵌套中断的,这从Cortex-A7中断向量表中仅为外部中断设置了一个中断向量可以看出。本文介绍ARM官方推荐使用的嵌套中断实现机

【AI大模型应用开发】2.1 Function Calling连接外部世界 - 入门与实战(1)

Function Calling是大模型连接外部世界的通道,目前出现的插件(Plugins )、OpenAI的Actions、各个大模型平台中出现的tools工具集,其实都是Function Calling的范畴。时下大火的OpenAI的GPTs,原理就是使用了Function Calling,例如联网检索、code interpreter。 本文带大家了解下Function calling,看

外部中断的边缘触发和电平触发

MCS-51单片机中的边缘触发是指当输入引脚电平由高到低发生跳变时,才引起中断。而电平触发是指只要外部引脚为低电平就引起中断。         在电平触发方式下,当外部引脚的低电平在中断服务返回前没有被拉高时(即撤除中断请求状态),会引起反复的不需要的中断,造成程序执行的错误。这类中断方式下,需要在中断服务程序中设置指令,清除外部中断的低电平状态,使之变为高电平。

【Java编程思想】线程的基本协作机制 与 线程的中断

wait/notify Java在Object类中定义了一些线程协作的基本方法,wait和notify public final void wait() throws InterruptedException;public final native void wait(long timeout) throws InterruptedException; 一个带时间参数,单位是毫秒,表示最

基于IMX6ULL的Cortex-A中断原理讲解,以及编写其中断向量表

首先借助STM32我们需要了解中断系统是如何构成的         会有一个中断源,也就是能够向CPU发出中断请求的设备或事件。中断源不分硬件和软件,也就是产生中断信号,就会执行中断服务函数         但是CPU是如何知道中断源产生后就找到对应的中断服务函数呢,这个时候就要引入中断向量表,它的主要功能是描述中断对应的中断服务函数,每个中断源都有一个唯一的中断号(也称向量号),

【银河麒麟高级服务器操作系统实例】虚拟化平台系统服务中断现象分析及处理建议

服务器环境以及配置 【机型】虚机 处理器: Kunpeng-920 内存: 40G 【内核版本】 4.19.90-23.8.v2101.ky10.aarch64 【OS镜像版本】 银河麒麟操作系统 Kylin-Server-10-SP1-Release-Build20-20210518-arm64 【第三方软件】 智能运维系统、mysql数据集群 现象描述 环境描

从应用内跳转至外部浏览器 - 鸿蒙 HarmonyOS Next

从应用内跳转至外部浏览器,基于 Want 来实现,同时也可以通过其方式尝试跳转至其它系统模块,具体可参考如下 code : 方法调用 // 调用pushOutsideWeb(controller, url) 方法实现 import { common, contextConstant, Want } from '@kit.AbilityKit';import { HintMessage