2-1 EXTI外部中断(gd32)

news2024/11/30 12:48:38

中断的概念

中断硬件结构/软件结构

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){
		// 判断中断标志位,产生中断时标志位会设置为1
	    if( 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){
		// 判断中断标志位,产生中断时标志位会设置为1
	    if( exti_interrupt_flag_get(EXTI_13) == SET){
		      // 此时说明进入中断
              ToggleLed(LED2);		
        	  // 清除标志位,如果标志位没有清除为0,会不断地进入中断服务函数当中,
			  // 所以要清除中断标志位
              exti_interrupt_flag_clear(EXTI_13);			
		}
				// 判断中断标志位,产生中断时标志位会设置为1
	    if( 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){
		// 判断中断标志位,产生中断时标志位会设置为1
	    if( 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){
		// 判断中断标志位,产生中断时标志位会设置为1
	    if( exti_interrupt_flag_get(EXTI_13) == SET){
		      // 此时说明进入中断
              ToggleLed(LED2);		
        	  // 清除标志位,如果标志位没有清除为0,会不断地进入中断服务函数当中,
			  // 所以要清除中断标志位
              exti_interrupt_flag_clear(EXTI_13);			
		}
				// 判断中断标志位,产生中断时标志位会设置为1
	    if( 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 2
 
void 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;
			
		}	
	} 
	
}

仿真调试

 

按键运算补充

抢占优先级的作用

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1667764.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

17 M-LAG 配置思路

16 华三数据中心最流行的技术 M-LAG-CSDN博客 M-LAG 配置思路 什么是M-LAG&#xff1f;为什么需要M-LAG&#xff1f; - 华为 (huawei.com) 1 配置 M-LAG 的固定的MAC地址 [SW-MLAG]m-lag system-mac 2-2-2 2 配置M-LAG 的系统标识符系统范围1到2 [SW-MLAG]m-lag system-nu…

程序员工作中常见问题,你遇到过几个?

在赛博朋克2077玩后感中&#xff0c;我提到&#xff0c;即便是在严谨的机制下&#xff0c;依然可能出现让人匪夷所思或是贻笑大方的问题。 那么今天&#xff0c;就以后端程序员的视角&#xff0c;盘点下从设计开发到上线的常见问题&#xff0c;看看大家中过几个。 01 设计与开…

解决ubuntu无法上网问题

发现是网络配置成了Manual手动模式&#xff0c;现在都改成自动分配DHCP模式 打开后&#xff0c;尝试上网还是不行&#xff0c;ifconfig查看ip地址还是老地址&#xff0c;怀疑更改没生效&#xff0c;于是重启试试。 重启后&#xff0c;ip地址变了&#xff0c;可以打开网页了 …

中间件的使用

中间件是全局使用 工厂函数定义中间件 middleware.py # 工厂函数的中间件 def simple_middleware(get_response):def middleware(request):print("在视图函数处理之前执行、、、、、")response get_response(request)print("在视图函数处理之后执行。。。。…

宝塔面板Java项目部署,五步轻松搞定

当涉及到正规的开发项目时&#xff0c;最终的上线部署是至关重要的一个环节。本文旨在以最简单便捷的方法来教你如何完成项目的部署工作。 1. SSH下载地址 项目完成后需要使用SSH终端进行项目部署&#xff0c;以确保安全的远程访问、和操作远程服务器。 Xshell (支持Windows系…

【数据结构】排序(一)—— 希尔排序(思路演进版)

目录 一、常见的排序算法分类 二、常见排序算法的实现 2.1插入排序 2.1.1基本思想 2.1.2直接插入排序 思路 step1.单趟控制 step2.总体控制 代码实现 测试 特性总结 2.1.3 希尔排序( 缩小增量排序 ) 基本思想 思路演进 &#x1f308;1.代码实现单组排序&#…

【recast-navigation-js】通过websocket获取navmesh数据并初始化

目录 说在前面目录结构websocket服务器前端结果 说在前面 操作系统&#xff1a;windows 11浏览器&#xff1a;edge版本 124.0.2478.97recast-navigation-js版本&#xff1a;0.29.0golang版本&#xff1a;1.21.5 目录结构 D:. │ go.mod │ go.sum │ main.go // websocket …

Ant-design实现a-table无数据的时候展示中文

Ant-design实现国际化 1.基本需求 当a-table中没有数据的时候展示的是No Data现在我们需要将这个英文变成中文的形式 就要实现“国际化”2.实现国际化 参考&#xff1a;我用的是Vue3Ant-Design4.x 导入&#xff1a; import zhCN from "ant-design-vue/es/locale/zh_CN&qu…

Hadoop大数据应用技术复习题分析

文章目录 复习一一. 单选题二. 多选题三. 填空题 复习三一. 单选题 复习一 一. 单选题 (单选题)压缩速度由大到小snappy、LZO、gzip、bzip2&#xff0c;压缩比最大的是 A. snappy B. LZO C. gzip D. zip2 正确答案: D:zip2; 答案解析&#xff1a; 压缩率&#xff1a;zip2>…

深度学习--DCGAN

代码之后的注释和GAN的一样&#xff0c;大家如果已经掌握GAN&#xff0c;可以忽略掉哦&#xff01;&#xff01;&#xff01; 在学习DCGAN之前&#xff0c;我们要先掌握GAN&#xff0c;深度学习--生成对抗网络GAN-CSDN博客 这篇博客讲的就是GAN的相关知识&#xff0c;还是很详…

8个免费无版权视频素材网站,高清无水印视频任性下载

在数字化时代&#xff0c;优质的视频素材成为各种项目不可缺少的元素&#xff0c;从短片制作到商业广告&#xff0c;高品质的视频能显著提高作品的吸引力和传播效果。然而&#xff0c;寻找既免费又无版权问题的高清视频素材并非易事。以下介绍几个优秀的免费视频素材网站&#…

ORA-609频繁出现在alert.log,如何解决?

ORA-609就alertlog中比较常见的一个报错&#xff0c;虽然并没有太大的影响&#xff0c;但是频繁的出现在alert log也是很让人厌烦的事情&#xff0c;本文介绍如何排查解决ORA-609问题。 1.ORA-609官方定义 could not attach to incoming connection Cause Oracle process cou…

通过linux花里胡哨的控制台,学习linux基础命令

今天这个B我装定了&#xff01; 前言命令集 开始1、cowsay &#xff08;让牛说话&#xff0c;够无聊的&#xff0c;但牛说的话是你输入的&#xff0c;细思极恐&#xff01;&#xff09;Debian/Ubuntu 安装命令&#xff1a;RHEL/CentOS/Fedora 安装&#xff1a;运行解释 2、fort…

libssh C++封装之七(File)

1 概述 libssh是一个在客户端和服务器端实现SSHv2协议的多平台C库。使用libssh,您可以远程执行程序、传输文件、使用安全透明的隧道、管理公钥等等。本文描述的对libssh客户端功能的C++封装。 libssh下载地址 3 实现 3.6 File File类型可以读写远程文件。 3.6.1 File定义 …

李宏毅-注意力机制详解

原视频链接&#xff1a;attention 一. 基本问题分析 1. 模型的input 无论是预测视频观看人数还是图像处理&#xff0c;输入都可以看作是一个向量&#xff0c;输出是一个数值或类别。然而&#xff0c;若输入是一系列向量&#xff0c;长度可能会不同&#xff0c;例如把句子里的…

Attention Sink

论文发现自回归LLM存在的一个有趣现象&#xff1a;对于输入文本最靠前的少量几个token&#xff0c;无论它们在语义上与语言建模任务的相关性如何&#xff0c;大量的注意力分数都会分配给他们&#xff0c;如下图所示&#xff1a; 模型的前两层还能保持attention score更多分配给…

第四步->手撕spring源码之bena注入实现和依赖

本步骤目标 上述几个步骤 定义和注册Bean (opens new window)、实例化Bean (opens new window)&#xff0c;按照是否包含构造函数实现不同的实例化策略 (opens new window)&#xff0c;那么在创建对象实例化这我们还缺少什么&#xff1f;其实还缺少一个关于类中是否有属性的问题…

【应用浅谈】Odoo的库存计价与产品成本(二)

序言:时间是我们最宝贵的财富,珍惜手上的每个时分 Odoo的库存&#xff08;Stock&#xff09;模块拥有众多功能&#xff0c;其中库存计价是一项非常重要的功能&#xff0c;原生的成本方法分三种&#xff1a;【标准成本】&#xff0c;【平均成本】&#xff0c;【先进先出】&#…

【算法】竞赛常用知识之字符串1

前言&#xff1a; 本系列是学习了董晓老师所讲的知识点做的笔记 董晓算法的个人空间-董晓算法个人主页-哔哩哔哩视频 (bilibili.com) 动态规划系列&#xff08;还没学完&#xff09; 【算法】动态规划之线性DP问题-CSDN博客 【算法】动态规划之背包DP问题&#xff08;2024…

Mybatis-Plus大批量插入数据到MySQL

MyBatis-Plus的saveBatch方法 GetMapping("/save1") public void save1() {// 数据准备List<MallOrder> orderList getMallOrderList();// mybatis-pluslong start System.currentTimeMillis();mallOrderService.saveBatch(orderList);System.out.println(&…