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.pswp.cn/diannao/44058.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/44058.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/44058.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

SRS流媒體源碼解析--service

本文主要解析一下SRS3.0 service部分源碼&#xff0c;主要和srs_service_st模塊。 srs_service_st 模塊包含了網絡服務的基礎實現&#xff0c;特別是與套接字&#xff08;sockets&#xff09;和網絡通信相關的功能。主要功能和特點包括&#xff1a; &#xff08;1&#xff0…

高鐵站客運樞紐IPTV電視系統-鹽城高鐵站西廣場IP電視系統應用淺析

高鐵站客運樞紐IPTV電視系統-鹽城高鐵站西廣場IP電視系統應用淺析 由北京海特偉業科技有限公司任洪卓于2024年7月9日發布 隨著科技的飛速發展&#xff0c;特別是“互聯網”戰略的深入推進&#xff0c;高鐵站客運樞紐的信息化建設成為提升服務質量、增強乘客體驗的重要手段。鹽…

代碼隨想錄算法訓練營:29/60

非科班學習算法day29 | LeetCode134:加油站 &#xff0c;Leetcode135:分發糖果 &#xff0c;Leetcode860:檸檬水找零 介紹 包含LC的兩道題目&#xff0c;還有相應概念的補充。 相關圖解和更多版本&#xff1a; 代碼隨想錄 (programmercarl.com)https://programmercarl.com/…

IT專業高考假期入門指南

IT領域預習指南&#xff1a;開啟未來科技之旅 一、確定興趣方向 IT領域廣闊&#xff0c;涵蓋軟件開發、網絡安全、數據分析、人工智能等多個方向。首先&#xff0c;明確自己的興趣所在&#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…

JS進階-深入對象

學習目標&#xff1a; 掌握深入對象 學習內容&#xff1a; 創建對象三種方式構造函數實例成員&靜態成員 創建對象三種方式&#xff1a; 利用對象字面量創建對象 const o {name: 佩奇}利用new Object創建對象 const obj new Object({ uname: 雪碧寶寶 })console.log(obj…

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;別…

windows USB 設備驅動開發-發送MDL和錯誤恢復

USB 驅動程序可以在堆棧中使用鏈接式 MDL 功能發送數據&#xff0c;并且USB驅動的客戶端可以將傳輸緩沖區作為 MDL 結構鏈發送。 大多數 USB 主機控制器要求傳輸緩沖區幾乎是連續的。 幾乎連續意味著緩沖區可以開始和結束頁中的任意位置&#xff0c;但緩沖區的其余部分必須在頁…

53-4 內網代理6 - frp搭建三層代理

前提:53-3 內網代理5 - frp搭建二級代理-CSDN博客 三級網絡代理 在辦公區入侵后,發現需要進一步滲透核心區網絡(192.168.60.0/24),并登錄域控制器的遠程桌面。使用FRP在EDMZ區、辦公區與核心區之間建立三級網絡的SOCKS5代理,以便訪問核心區的域控制器。 VPS上的FRP服…

海豚調度器(DolphinScheduler)修改時區為東八區

海豚調度器設置了定時&#xff0c;執行的時間和設置時間不同&#xff0c;后來排查發現是時區問題。可以用下面方法和步驟來修改&#xff1a; 修改DolphinScheduler服務器時區 登錄服務器&#xff1a;首先&#xff0c;通過SSH或其他方式登錄到運行DolphinScheduler服務的服務器…

壓縮感知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 關鍵…

AWS Glue 與 Amazon Redshift 的安全通信配置

1. 引言 在 AWS 環境中,確保服務間的安全通信至關重要。本文將探討 AWS Glue 與 Amazon Redshift 之間的安全通信配置,特別是為什么需要特定的安全組設置,以及如何正確實施這些配置。 2. 背景 AWS Glue:全托管的 ETL(提取、轉換、加載)服務Amazon Redshift:快速、完全…

嵌入式底層開發 入門學習路線

入門嵌入式底層開發的學習路線可以分為幾個關鍵階段&#xff0c;下面是一個較為系統的學習路徑&#xff0c;它涵蓋了從基礎知識到實際項目應用的全過程。 1. 基礎知識 計算機科學基礎&#xff1a;理解數據結構、算法、操作系統等基本概念。電子和電路理論&#xff1a;學習數字…