GD 32中断系统实现

1.0 中断的概念

 中断:简单来说就是打断的意思,在计算机系统中CPU在执行一个操作的时候,有一个比当前任务更为紧急的任务需要执行,cpu暂停当前任务转而去执行更为紧急任务的操作,执行完更为紧急任务之后再返回来执行原来未执行完的任务:这里还涉及到任务切换的概念【以上是对于中断的理解】


2.0 中断的硬件结构


以上的结构大概是GD32单片机有7个端口,每一个端口大概有8个引脚,【同一时间只能有一个引脚接入到中断引脚选择】,中断引脚选择中可以选择触发中断的模式,有上升沿触发,下降沿触发选择完成后设置中断标志位,今个NVIC嵌入式中断向量控制器,然后进入对应的片上外设。


3.0 中断优先级

中断的优先级分为4组,每一组设置有不同的抢占式优先级和响应式优先级,可以参考以下的例子作为了解。

CPU 正在执行任务A,这个时候任务B来了 ,假设目前任务A的抢占式优先级是2 响应式优先级是3,任务B的抢占式优先级是1,响应式优先级是3 , 这是时候,GPU或展停任务A的执行转而去执行任务B的任务B任务执行完毕之后再去执行A任务。

第一种场景


抢占式优先级:如下图所示,任务a的抢占式优先级是3,响应式优先级是1,任务B的抢占式优先级是2,响应式优先级是2,然后任务B会打断抢占任务A的先执行

 以下可以类比得出结果


4.0 代码实现

相关库函数参考

项目架构

中断配置步骤

初始化GPIO时钟

以上初始化GPIO的时钟使用定义结构体的方式进行初始化,使用结构体更方便后续程序的移植与使用,也可以选择不使用结构体初始化的方式。

中断EXTI初始化

使用结构体的方式初始化中断,在使用NVIC嵌套中断向量控制器使能中断的时候,首先要清除指定的中断线路,否则可能会出现程序频繁的进入中断与中断卡死的情况。

中断函数编写

以上主要使用到3个中断线,第一个是EXTI_0的中断,第二个是EXTI_13的中断,第三个是EXTI_14的中断。


KEY.C程序源码

#include "gd32f30x.h"                   // Device header
#include <stdint.h>
#include "LED.h"// 创建结构体数组
typedef struct{rcu_periph_enum rcu;uint32_t gpio;uint32_t mode;uint32_t speed;uint32_t pin;
}Exti_Gpio_t;static Exti_Gpio_t Exti_List[] = {{RCU_GPIOA,GPIOA,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_10MHZ,GPIO_PIN_0},{RCU_GPIOG,GPIOA,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_10MHZ,GPIO_PIN_13},{RCU_GPIOG,GPIOA,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_10MHZ,GPIO_PIN_14},
};#define  Max_List_Exti sizeof(Exti_List)/sizeof(Exti_List[0])static void GPIO_Init(void){uint16_t i = 0;for(i = 0; i < Max_List_Exti; i++){rcu_periph_clock_enable(Exti_List[i].rcu);gpio_init(Exti_List[i].gpio,Exti_List[i].mode,Exti_List[i].speed,Exti_List[i].pin);}	
}static void EXTI_Init(void){// 开启中断时钟rcu_periph_clock_enable(RCU_AF);// 开启中断引脚选择gpio_exti_source_select(GPIO_PORT_SOURCE_GPIOA,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,1);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);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_4);nvic_irq_enable(EXTI10_15_IRQn, 0, 1);}void KeyDrvInit(void){GPIO_Init();EXTI_Init();
}void EXTI0_IRQHandler(void){// 获取中断标志位if(exti_interrupt_flag_get(EXTI_0) != RESET){Toggle_Led_Turn(LED1);// 清除中断线路,防止该中断被反复的处理exti_interrupt_flag_clear(EXTI_0);while(1);}
}void EXTI10_15_IRQHandler(void){if(exti_interrupt_flag_get(EXTI_13) != RESET){Toggle_Led_Turn(LED2);exti_interrupt_flag_clear(EXTI_13);}if(exti_interrupt_flag_get(EXTI_14) != RESET){Toggle_Led_Turn(LED3);exti_interrupt_flag_clear(EXTI_14);}
}

KEY.H程序源码

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

LED.C 程序源码

#include "gd32f30x.h"                   // Device header
#include "Delay.h"
#include <stdint.h>// 初始化结构体结构体数据类型
typedef struct Led_gpio_t{rcu_periph_enum rcu;uint32_t gpio;uint32_t pin;
}LED_GPIO_T;// 定义一个静态全局变量保存GPIO口的资源信息
static LED_GPIO_T Gpio_List[] = {{RCU_GPIOA,GPIOA,GPIO_PIN_8},{RCU_GPIOE,GPIOE,GPIO_PIN_6},{RCU_GPIOF,GPIOF,GPIO_PIN_6}
};// 宏定义确定数组的大小
#define LED_NUM_MAX (sizeof(Gpio_List) / sizeof(Gpio_List[0]))void LED_Init_Drive(void){for(uint8_t i = 0; i < LED_NUM_MAX; i++){// 开启GPIO时钟rcu_periph_clock_enable(Gpio_List[i].rcu);// 初始化GPIOgpio_init(Gpio_List[i].gpio,GPIO_MODE_OUT_PP,GPIO_OSPEED_10MHZ,Gpio_List[i].pin);// GPIO 初始化调用的方式gpio_bit_reset(Gpio_List[i].gpio,Gpio_List[i].pin);}
}void Turn_LedOn(uint8_t LedNo){if(LedNo >= LED_NUM_MAX){return;}else{gpio_bit_set(Gpio_List[LedNo].gpio,Gpio_List[LedNo].pin);}}void Turn_OffLed(uint8_t LedOff){if(LedOff >= LED_NUM_MAX){return;}else{gpio_bit_reset(Gpio_List[LedOff].gpio,Gpio_List[LedOff].pin);}
}// 进入中断函数之后实现LED翻转功能
void Toggle_Led_Turn(uint8_t LedToggle){// 设置中断标志位FlagStatus bit_state;// 获取输出数据寄存器的值bit_state = gpio_input_bit_get(Gpio_List[LedToggle].gpio,Gpio_List[LedToggle].pin);// 取反功能bit_state = (FlagStatus)(1 - bit_state);// 写入数据寄存器的值gpio_bit_write(Gpio_List[LedToggle].gpio,Gpio_List[LedToggle].pin,bit_state);}/*注:下面的这段代码可以忽略
*/// 初始化LED灯
void LED_Init(void){// 使能RCU时钟rcu_periph_clock_enable(RCU_GPIOA);// 配置引脚输出频率gpio_init( GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_8);// 初始化GPIOE的引脚rcu_periph_clock_enable(RCU_GPIOE);// 配置引脚输出频率gpio_init( GPIOE, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_6);// 初始化GPIOE的引脚rcu_periph_clock_enable(RCU_GPIOF);// 配置引脚输出频率gpio_init( GPIOF, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_6);
}// 实现循环流水灯的功能
void LED_Cycle(void){DelayInit();while(1){gpio_bit_set(GPIOA, GPIO_PIN_8); DelayNms(1000);gpio_bit_reset(GPIOA, GPIO_PIN_8);DelayNms(1000);gpio_bit_set(GPIOE, GPIO_PIN_6); DelayNms(1000);gpio_bit_reset(GPIOE, GPIO_PIN_6);DelayNms(1000);gpio_bit_set(GPIOF, GPIO_PIN_6); DelayNms(1000);gpio_bit_reset(GPIOF, GPIO_PIN_6);DelayNms(1000);}}

LED.H程序源码

#ifndef _LED_H_
#define _LED_H_
#include <stdint.h>//宏定义LED灯的引脚
#define LED1   0
#define LED2   1
#define LED3   2void LED_Init(void);void LED_Cycle(void);void LED_Init_Drive(void);void Turn_LedOn(uint8_t LedNo);void Turn_OffLed(uint8_t LedOff);void Toggle_Led_Turn(uint8_t LedToggle);#endif

MAIN.C程序源码

#include <stdio.h>
#include "gd32f30x.h"
#include "Delay.h"
#include "LED.h"
#include "Key.h"int main(void)
{    // 初始化LEDLED_Init();KeyDrvInit();while(1){} }

注:以上程序实现的效果是由KEY1,KEY2,KEY3,控制三个LED灯分别为LED1,LED2,LED3当第一个按键按下时LED1点亮,同时控制LED1的按键优先级低于控制KEY2,KEY3按键的优先级这个时候LED1灯会被抢占,也就是点亮LED1后可能无法再次被熄灭。【抢占式优先级】。


5.0 STM32类比学习

.....

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

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

相关文章

高铁站客运枢纽IPTV电视系统-盐城高铁站西广场IP电视系统应用浅析

高铁站客运枢纽IPTV电视系统-盐城高铁站西广场IP电视系统应用浅析 由北京海特伟业科技有限公司任洪卓于2024年7月9日发布 随着科技的飞速发展&#xff0c;特别是“互联网”战略的深入推进&#xff0c;高铁站客运枢纽的信息化建设成为提升服务质量、增强乘客体验的重要手段。盐…

【1.3】动态规划-解码方法

一、题目 一条包含字母A-Z的消息通过以下映射进行了编码&#xff1a; A -> 1 B -> 2 ... Z -> 26 要解码已编码的消息&#xff0c;所有数字必须基于上述映射的方法&#xff0c;反向映射回字母&…

新能源汽车充电站远程监控系统S275钡铼技术无线RTU

新能源汽车充电站的远程监控系统在现代城市基础设施中扮演着至关重要的角色&#xff0c;而钡铼技术的S275无线RTU作为一款先进的物联网数据监测采集控制短信报警终端&#xff0c;为充电站的安全运行和高效管理提供了强大的技术支持。 技术特点和功能 钡铼S275采用了基于UCOSI…

Android11 窗口动画

窗口进入动画 应用端窗口绘制完成之后&#xff0c;调用finshDraw告知WMS&#xff0c;WMS这边最后就会调用WindowSurfacePlacer的performSurfacePlacement方法&#xff0c;最终调用到 WindowStateAnimator的commitFinishDrawingLocked方法 //frameworks/base/services/core/jav…

OJhelper一款帮助你获取各大oj信息的软件

项目地址 应用功能 目前应用支持&#xff1a;查询、自定义、收藏各大oj比赛信息&#xff0c;跳转比赛界面。查询各大oj的Rating分以及题量&#xff0c;查看题量饼状图。 应用环境 windows和安卓端 应用预览&#xff1a; 维护概况 后期会提供持续更新&#xff0c;具体可以…

7.9数据结构

思维导图 作业 doubleloop.h #ifndef __DOUBLELOOP_H__ #define __DOUBLELOOP_H__#include <stdio.h> #include <stdlib.h>typedef int datatype; typedef struct node {union{int len;datatype data;};struct node *pri;//前驱指针struct node *next;//后继指针…

全终端自动化测试框架wyTest

突然有一些觉悟&#xff0c;程序猿不能只会吭哧吭哧的低头做事&#xff0c;应该学会怎么去展示自己&#xff0c;怎么去宣传自己&#xff0c;怎么把自己想做的事表述清楚。 于是&#xff0c;这两天一直在整理自己的作品&#xff0c;也为接下来的找工作多做点准备。接下来…

Linux | 安装lb-toolkits 1.2.4库

Linux | 安装 lb-toolkits 最近又需要下载葵花的数据&#xff0c;之前分享过一次代码。今天发现之前的环境不小心被我删了&#xff0c;而运行相关的代码需要安装lb-toolkits这个库&#xff0c;今天正好记录了一下安装lb-toolkits的过程。 这里安装的版本是1.2.4&#xff0c;别…

53-4 内网代理6 - frp搭建三层代理

前提:53-3 内网代理5 - frp搭建二级代理-CSDN博客 三级网络代理 在办公区入侵后,发现需要进一步渗透核心区网络(192.168.60.0/24),并登录域控制器的远程桌面。使用FRP在EDMZ区、办公区与核心区之间建立三级网络的SOCKS5代理,以便访问核心区的域控制器。 VPS上的FRP服…

压缩感知3——重构算法正交匹配追踪算法

算法流程 问题的实质是&#xff1a;AX Y 求解&#xff08;A是M维&#xff0c;Y是N维且N>>M并且稀疏度K<M&#xff09;明显X有无穷多解&#xff0c;重构过程是M次采样得到的采样值升维的过程。OMP算法的具体步骤&#xff1a;(1)用X表示信号&#xff0c;初始化残差e0 …

计算给定数字的阶乘

1 问题 计算给定数字的阶乘. 2 方法 使用while循环。使用for循环。使用函数。 通过实验、实践等证明提出的方法是有效的&#xff0c;是能够解决开头提出的问题。 代码清单 1 使用while循环numberint(input(请输入一个数字:))factorial1i1while i<number: factorialfactor…

【论文速读】| JADE:用于大语言模型的基于语言学的安全评估平台

本次分享论文&#xff1a;JADE : A Linguistics-based Safety Evaluation Platform for Large Language Models 基本信息 原文作者&#xff1a;Mi Zhang, Xudong Pan, Min Yang 作者单位&#xff1a;Whitzard-AI, System Software and Security Lab Fudan University 关键…

『大模型笔记』GraphRAG:用于复杂数据发现的新工具现已在GitHub上发布

GraphRAG:用于复杂数据发现的新工具现已在GitHub上发布 文章目录 一. GraphRAG:用于复杂数据发现的新工具现已在GitHub上发布1. 评估和结果2. 研究见解和未来方向二. 参考文献一. GraphRAG:用于复杂数据发现的新工具现已在GitHub上发布 下载 GraphRAG今年早些时候,我们介绍…

倒计时 2 周!CommunityOverCode Asia 2024 IoT Community 专题部分

CommunityOverCode 是 Apache 软件基金会&#xff08;ASF&#xff09;的官方全球系列大会&#xff0c;其前身为 ApacheCon。自 1998 年以来&#xff0c;在 ASF 成立之前&#xff0c;ApacheCon 已经吸引了各个层次的参与者&#xff0c;在 300 多个 Apache 项目及其不同的社区中探…

百度文心4.0 Turbo开放,领跑国内AI大模型赛道!

百度文心4.0 Turbo开放&#xff0c;领跑国内AI大模型赛道&#xff01; 前言 文心一言大模型 就在7月5日&#xff0c;在2024世界人工智能大会 (WAIC) 上&#xff0c;百度副总裁谢广军宣布文心大模型4.0 Turbo正式向企业客户全面开放&#xff01;这一举动直接引发了业界的关注。那…

springboot中@bean注解的创建和使用

bean的创建顺序 在Spring Boot中&#xff0c;当一个配置类&#xff08;使用Configuration注解的类&#xff09;中定义了多个bean时&#xff0c;这些bean的创建顺序并不完全由它们在类中的声明顺序决定。Spring框架在创建和管理bean时&#xff0c;遵循了复杂的依赖注入和生命周…

在Windows中使用开源高性能编辑器Zed(持续更新)

简介 “Zed is a high-performance, multiplayer code editor from the creators of Atom and Tree-sitter. It’s also open source.” “Zed是一款高性能的支持多人协作的代码编辑器&#xff0c;由Atom和Tree-sitter的创建者开发。它也是开源的。” Zed主打“高性能”&…

为什么选择开放式耳机?悠律凝声环开放式耳机体验

开放式耳机相对于其他传统耳机优势有以下几点&#xff1a; 配戴舒适性更好&#xff1a;由于开放式耳机的背面是开放的&#xff0c;空气可以自由流动&#xff0c;减少了耳朵的闷热感。长时间佩戴时更加舒适。&#xff0c;而传统入耳式耳机一般都是塞入耳道&#xff0c;久戴会胀…

Java中的 this 关键字是什么意思? this() 又是什么?

目录 问题问题一&#xff1a;什么是this关键字?问题二&#xff1a;什么是this()&#xff1f; 问题 问题一&#xff1a;什么是this关键字? 定义&#xff1a;this 代表当前对象。这个定义比较抽象&#xff0c;举例来回答。 思考一个问题&#xff1a;如果没有 this 会怎样&…

鸿蒙开发学习笔记2

一、class 类 类是用于 创建对象模版。同时类声明也会引入一个 新类型&#xff0c;可定义其 实例属性、方法 和 构造函数。 // 类名 首字母大写&#xff08;规范&#xff09; class 类名 {// 1、实例属性&#xff08;字段&#xff09;// 2、构造函数// 3、方法 }1、属性&…