STM32中斷編程入門

文章目錄

  • 一、 理論部分
    • 1.中斷系統
    • 2.中斷執行流程
    • 3.NVIC的基本結構
    • 4.EXTI介紹
    • 5.AFIO復用IO口
  • 二、實驗目的:學習stm32中斷原理和開發編程方法。使用標準完成以下任務:
    • (一)實驗一 開關控制LED的亮滅
      • 1.代碼部分
      • 2.運行結果
    • (二)實驗二 接收單個字符控制發送數據
      • 1.代碼部分
      • 2.運行結果
    • (三)實驗三 接收字符串控制發送數據
      • 1.代碼部分
      • 2.運行結果
  • 三、總結

一、 理論部分

1.中斷系統

在這里插入圖片描述

2.中斷執行流程

在這里插入圖片描述

3.NVIC的基本結構

在這里插入圖片描述

在這里插入圖片描述

4.EXTI介紹

在這里插入圖片描述在這里插入圖片描述

5.AFIO復用IO口

在這里插入圖片描述

二、實驗目的:學習stm32中斷原理和開發編程方法。使用標準完成以下任務:

用stm32F103核心板的GPIOA端一管腳接一個LED,GPIOB端口一引腳接一個開關(用杜邦線模擬代替)。采用中斷模式編程,當開關接高電平時,LED亮燈;接低電平時,LED滅燈。
可參考教材課件上的6.4.3示例
采用串口中斷方式重做上周的串口通信作業,分別實現:1)當stm32接收到字符“s”時,停止持續發送“hello windows!”; 當接收到字符“t”時,持續發送“hello windows!”(提示:采用一個全局標量做信號燈);2)當stm32接收到字符“stop stm32!”時,停止持續發送“hello windows!”; 當接收到字符“go stm32!”時,持續發送“hello windows!”(提示:要將接收到的連續字符保存到一個字符數組里,進行判別匹配。寫一個接收字符串的函數。

(一)實驗一 開關控制LED的亮滅

1.代碼部分

//exti_key.c文件
#include "exti_key.h"
#include "misc.h"void EXTI_Key_Init()
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE);  //打開GPIOA和復用輸入輸出口的時鐘//配置GPIO口GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Pin_3;     GPIO_InitStructure.GPIO_Pin = GPIO_Mode_IN_FLOATING;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//配置NVIC(Nested Vectored Interrupt Controller:嵌套向量中斷控制器)NVIC_InitTypeDef NVIC_InitStructure;NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;NVIC_Init(&NVIC_InitStructure);//配置EXTI(External Interrupt/Event Controller:外部中斷/事件控制器)EXTI_InitTypeDef EXTI_InitStructure;EXTI_ClearITPendingBit(EXTI_Line3);GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource3);EXTI_InitStructure.EXTI_Line = EXTI_Line3;EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;EXTI_Init(&EXTI_InitStructure);}
#include "stm32f10x.h"  
#include "exti_key.h"
#include "LED.h"uint8_t led = 1;
int main()
{GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET); //默認為熄滅EXTI_Key_Init();while(1){}
}void EXTI3_IRQHandler()
{if(EXTI_GetITStatus(EXTI_Line3) != RESET ){led = ~led;if(led == 1){GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET);}else{GPIO_WriteBit(GPIOB,GPIO_Pin_5,Bit_SET);}		EXTI_ClearITPendingBit(EXTI_Line3);}}

2.運行結果

20240519_002

(二)實驗二 接收單個字符控制發送數據

采用串口中斷方式,當stm32接收到1個字符“s”時,停止持續發送“hello windows!”; 當接收到1個字符“t”時,持續發送“hello windows!”(提示:采用一個全局標量做信號燈);

1.代碼部分

#include "stm32f10x.h"                  // Device header
#include "Delay.h"int status = 0;//設置是否發送數據的標志位
int main()
{	//開啟GPIOA和USART1的時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);//實例化控制器的對象GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;//先配置GPIO控制器//1.設置PA9為復用推挽輸出模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //設置為復用推挽輸出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init(GPIOA,&GPIO_InitStructure);   //老子草了沒寫這一句,以為只GPIO_Init()一次就可以了,結果忘了這些參數會覆蓋的。//2.設置PA10為浮空輸入模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //設置為浮空輸入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//再配置USART控制器USART_InitStructure.USART_BaudRate = 9600;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //硬件流控制:選擇無流控制USART_InitStructure.USART_Mode = USART_Mode_Tx |USART_Mode_Rx; //模式選擇發送和接收USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_ClearFlag(USART1, USART_FLAG_TC);USART_Init(USART1,&USART_InitStructure);  //初始化串口1//配置中斷源USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//當USART串口接收到數據的時候,就觸發USART中斷// 4.給這個中斷源配置相應的搶占優先級和執行優先級NVIC_InitTypeDef  NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; //設置搶占(主)優先級    NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;      // 設置子優先級   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             NVIC_Init(&NVIC_InitStructure);    USART_Cmd(USART1,ENABLE);			//使能串口1char transmitArray[18]={"hello windows! \r\n "};   //windows系統串口發送時,用回車換行組合 (\r\n) 來實現換行while(1){	if(status == 1) //標志位status = 1 發送{for(int i=0;i<=17;i++){USART_SendData(USART1,transmitArray[i]);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)== RESET);  //RESET就是0,表示不符合,TXE的E是empty,表示發送寄存器不符合為空,即里面有東西,還在發送。	}Delay_s(1);}}}void USART1_IRQHandler(void)
{while(USART_GetITStatus(USART1,USART_IT_RXNE) == RESET ) //這里不再是USART_GetFlagStatus、USART_FLAG_RXNE,而是USART_GetITStatus、SART_IT_RXNE,要換成中斷{};  uint8_t RData=USART_ReceiveData(USART1);if(RData == 's'){status = 0;}else if (RData == 't'){status = 1;}}

2.運行結果

在這里插入圖片描述

(三)實驗三 接收字符串控制發送數據

1.代碼部分

#include "stm32f10x.h"                  // Device header
#include "Delay.h"void InitRDataArray();int status = 0;//設置是否發送數據的標志位char RDataArray[20];//接收指令的字符數組int main()
{	//開啟GPIOA和USART1的時鐘RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);//實例化控制器的對象GPIO_InitTypeDef GPIO_InitStructure;USART_InitTypeDef USART_InitStructure;//先配置GPIO控制器//1.設置PA9為復用推挽輸出模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //設置為復用推挽輸出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz ;GPIO_Init(GPIOA,&GPIO_InitStructure);   //老子草了沒寫這一句,以為只GPIO_Init()一次就可以了,結果忘了這些參數會覆蓋的。//2.設置PA10為浮空輸入模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //設置為浮空輸入GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA,&GPIO_InitStructure);//再配置USART控制器USART_InitStructure.USART_BaudRate = 9600;USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //硬件流控制:選擇無流控制USART_InitStructure.USART_Mode = USART_Mode_Tx |USART_Mode_Rx; //模式選擇發送和接收USART_InitStructure.USART_Parity = USART_Parity_No;USART_InitStructure.USART_StopBits = USART_StopBits_1;USART_InitStructure.USART_WordLength = USART_WordLength_8b;USART_ClearFlag(USART1, USART_FLAG_TC);USART_Init(USART1,&USART_InitStructure);  //初始化串口1//配置中斷源USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//當USART串口接收到數據的時候,就觸發USART中斷// 4.給這個中斷源配置相應的搶占優先級和執行優先級NVIC_InitTypeDef  NVIC_InitStructure;NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3; //設置搶占(主)優先級    NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;      // 設置子優先級   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;             NVIC_Init(&NVIC_InitStructure);    USART_Cmd(USART1,ENABLE);			//使能串口1char transmitArray[18]={"hello windows! \r\n "};   //windows系統串口發送時,用回車換行組合 (\r\n) 來實現換行InitRDataArray();  //初始化用來接收指令的字符數組while(1){	if(status == 1) //標志位status = 1 發送{for(int i=0;i<=17;i++){USART_SendData(USART1,transmitArray[i]);while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)== RESET);  //RESET就是0,表示不符合,TXE的E是empty,表示發送寄存器不符合為空,即里面有東西,還在發送。	}Delay_s(1);}}}//初始化字符數組
void InitRDataArray()
{for(int i=0;i<20;i++){RDataArray[i]=0;}
}void USART1_IRQHandler(void)
{int i=0;if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//判斷中斷是接收數據中斷{RDataArray[i]= USART_ReceiveData(USART1); //接收字符i++;} if (strcmp(RDataArray,"stop stm32!")==0){status = 0;//結束發送InitRDataArray();  //初始化用來接收指令的字符數組}
else if (strcmp(RDataArray,"go stm32!")==0){status = 1;//發送數據InitRDataArray();  //初始化用來接收指令的字符數組}
}

2.運行結果

在這里插入圖片描述

三、總結

我剛把串口通信學得差不多,現在又來了這個中斷,中斷我感覺比之前學的東西都要難。我也說不出為什么,就是覺得它很抽象。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/15805.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/15805.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/15805.shtml

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

相關文章

Qt | QFormLayout 類(表單布局)

01、上節回顧 Qt | QGridLayout 類(網格布局)02、簡介 1、QFormLayout 布局以兩列的形式列出其子項目, 2、QFormLayout 被分成兩列,左列是標簽(label)部分,通常由標簽 QLabel 組成,右列是由 字段(field)部分,通常是 QLineEdit 行編輯器,QSpinBox 旋轉框等部件,注意:…

【簡單易用,新人友好】一個輕量級生物信息學流程框架,從此解決99%的生物信息學流程搭建問題...

生物信息學數據分析流程的搭建是一項繁重而復雜的工作。隨著行業的發展&#xff0c;各種生信流程框架層出不窮&#xff0c;比如有: NextflowSnakemakeCWLWDL 各種標準&#xff0c;各種規則&#xff0c;令人眼花繚亂。選擇太多&#xff0c;往往令人無所適從。特別是新進入行業的…

小程序的深層了解

一:wxss的全局樣式和局部樣式 寫在文件上,第一個路徑會執行全局和局部自帶的wxss給wxml,會執行wxml,會執行json和js. 無論那個文件都會執行文件夾內的和外部的app.wxss,但是如果有一樣的屬性,則看屬性的權重,權重一樣,則設置局部樣式. 二:全局配置 wx:key"寫的是data內…

17.7K星開源產品分析平臺:Posthog

Posthog&#xff1a;開源洞察&#xff0c;產品優化的得力助手 - 精選真開源&#xff0c;釋放新價值。 概覽 PostHog是一個全面開源的平臺&#xff0c;旨在幫助團隊構建更好的產品。它提供了從產品分析到會話回放、功能標志和A/B測試等一系列工具&#xff0c;支持自托管&#x…

如何通過Nginx配置將請求轉發到conf.d目錄下的各個配置文件

目錄 如何通過Nginx配置將請求轉發到conf.d目錄下的各個配置文件1. 修改主配置文件 nginx.conf2. 在 conf.d 目錄中創建站點配置3. 設置站點根目錄和權限4. 檢查配置并重新加載Nginx總結 如何通過Nginx配置將請求轉發到conf.d目錄下的各個配置文件 在使用Nginx進行網站管理時&…

讀人工智能時代與人類未來筆記14_管控人工智能

1. 管控人工智能 1.1. 歷史上的戰場進一步推進到與數字網絡相連的所有地方 1.2. 數字程序現在控制著一個由眾多實體系統構成的龐大且仍在不斷增長的領域&#xff0c;而且越來越多的此類系統已實現網絡化 1.2.1. 在某些情況下甚至連門鎖和冰箱都實現了網絡化 1.2.2. 這催生出…

拋出異常時仍然需要記錄錯誤日志

場景&#xff1a;當service的方法執行拋出異常時&#xff0c;事務會發生回滾&#xff0c;導致無法記錄錯誤日志 解決&#xff1a;切面 其他&#xff1a;1.日志需要記錄日志標題&#xff0c;保存入參 2.失敗時會拋出異常&#xff1b;日志需要判斷執行是否成功&#xff0c;記錄…

2024年漢字小達人活動4個多月開賽:18道歷年選擇題和答案、解析

根據近年的安排&#xff0c;2024年第11屆漢字小達人比賽還有4個多月就啟動&#xff0c;那么孩子們如何利用這段時間有條不紊地備考呢&#xff1f;我的建議是兩手準備&#xff1a;①把小學1-5年級的語文課本上的知識點熟悉&#xff0c;重點是字、詞、成語、古詩。②把歷年真題刷…

聯想端游聯運SDK接入指南

1. 接入流程 本文檔主要介紹了 聯想PC游戲SDK接入流程、聯想游戲提供的功能、接入注意事項等。 1.1. 接入方式 1. 聯想游戲SDK2.1版本支持“賬號防沉迷支付”接入方式&#xff1b; a. 聯想提供賬號注冊、登錄等能力 b. 聯想提供防沉迷服務 c. 聯想提供游戲內支付 1.2. 對…

【學習筆記】計算機組成原理(八)

CPU 的結構和功能 文章目錄 CPU 的結構和功能8.1 CPU的結構8.1.1 CPU的功能8.1.2 CPU結構框圖8.1.3 CPU的寄存器8.1.4 控制單元CU和中斷系統 8.2 指令周期8.2.1 指令周期的基本概念8.2.2 指令周期的數據流 8.3 指令流水8.3.1 指令流水原理8.3.2 影響流水線性能的因素8.3.3 流水…

meinheld-gunicorn-flask VS uvicorn-gunicorn-fastapi 性能對比測試

本文會使用如下兩個項目&#xff1a;meinheld-gunicorn-flask 與 uvicorn-gunicorn-fastapi 前文有測過 Flask vs FastApi 性能對比測試&#xff0c;可能不夠有說服力&#xff0c;這次使用了號稱最快的wsgi或asgi服務器gunicorn來運行flask或fastapi。 上面meinheld-gunicorn…

數據庫-SQL性能分析

SQL執行頻率 慢查詢日志 慢查詢日志記錄了所有執行時間超過指定參數&#xff08;long_query_time&#xff0c;單位&#xff1a;秒&#xff0c;默認10秒&#xff09;的所有 SQL語句的日志。 MySQL的慢查詢日志默認沒有開啟&#xff0c;我們可以查看一下系統變量 slow_query_l…

html5 筆記02

目錄 01 svg的基本使用 02 svg繪圖 03 進程和線程 01 svg的基本使用 svg和canvas的區別: canvas: 1.canvas作為一個容器只有一個dom元素 ,內部元素無法使用dom操作 (canvas不能展開然后選擇不到 svg查看元素能選中因為是通過標簽控制的) 2.canvas 是配合js完成各種繪制效果 …

vue-route的路由配置中父組件沒有component怎么處理

概述 為了方便開發和維護&#xff0c;所以web前端的路由配置路徑和前端代碼文件路徑一般是一致的。但在實際開發中&#xff0c;項目可能會分很多級的菜單&#xff0c;由于很多菜單只有葉子菜單是真正的頁面。而中間菜單項只是一個路由配置。 為了正確路由到底層的功能頁面&…

指紋識別概念解析

目錄 1. 指紋是物證之首 1.1 起源于中國 1.2 發展于歐洲 1.3 流行于全世界 2. 指紋圖像 3. 指紋特征 4. 指紋注冊 5. 指紋驗證 6. 指紋辨識 1. 指紋是物證之首 指紋識別技術起源于中國、發展于歐洲、流行于全世界。自20世紀以來&#xff0c;指紋在偵破刑事案件、解決訴…

水泥超低排平臺哪家好?

隨著環保政策的加強和綠色發展理念的深入人心&#xff0c;水泥行業的超低排放改造已成為行業發展的新趨勢。選擇一個合適的水泥超低排平臺對于確保改造效果和實現企業的可持續發展至關重要。朗觀視覺小編將從多個角度出發&#xff0c;為您提供一份綜合評估與選擇攻略&#xff0…

Spring Boot 3.x 與 Spring Boot 2.x 的對比

Spring Boot 是 Java 開發領域的一個重要框架&#xff0c;它簡化了基于 Spring 的應用開發。隨著版本的不斷更新&#xff0c;Spring Boot 提供了更多功能、更好的性能以及更簡潔的配置。本文將詳細對比 Spring Boot 3.x 和 Spring Boot 2.x&#xff0c;探討它們之間的主要區別和…

[C語言]自定義類型詳解:結構體、聯合體、枚舉

目錄 &#x1f680;結構體 &#x1f525;結構體類型的聲明 &#x1f525;結構的自引用 &#x1f525;結構體變量的定義和初始化 &#x1f525;結構體內存對齊 &#x1f525;結構體傳參 &#x1f525;結構體實現位段&#xff08;位段的填充&可移植性&#xff09; &a…

安裝 Ubuntu桌面版,詳細步驟(附引導 U盤制作工具)

下載鏡像 安裝Ubuntu首先要下載鏡像包&#xff0c;訪問下面網址下載鏡像包 https://releases.ubuntu.com/ 選擇你要安裝的Ubuntu版本 將 .iso 文件保存到所需位置&#xff0c;下面會使用此文件創建可引導 U盤。 制作 Ubuntu 引導 U 盤 首先要找到一個大于4G的U盤&#xff…

貓頭虎 解析:為什么AIGC在國內適合做TOB,在國外適合做TOC?

貓頭虎 解析&#xff1a;為什么AIGC在國內適合做TOB&#xff0c;在國外適合做TOC&#xff1f; 博主 貓頭虎 的技術世界 &#x1f31f; 歡迎來到貓頭虎的博客 — 探索技術的無限可能&#xff01; 專欄鏈接&#xff1a; &#x1f517; 精選專欄&#xff1a; 《面試題大全》 — 面…