STM32F103_LL庫+寄存器學習筆記05 - GPIO輸入模式,捕獲上升沿進入中斷回調

導言


GPIO設置輸入模式后,一般會用輪詢的方式去查看GPIO的電平狀態。比如,最常用的案例是用于檢測按鈕的當前狀態(是按下還是沒按下)。中斷的使用一般用于計算脈沖的頻率與計算脈沖的數量。

項目地址:https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_ll_library05_gpio_input_interrupt

一、代碼(LL庫)


1.1、main.c

在這里插入圖片描述
如上所示,函數EXTI_Configure()完成PB4的上升沿觸發中斷的設置。
在這里插入圖片描述
如上所示,一定要在GPIO設置完輸入模式后,才能設置中斷。

1.2、stm32f1xx_it.c

在這里插入圖片描述
如上所示,編寫EXTI4中斷回調函數EXTI4_IRQHandler()的內容,在函數EXTI4_IRQHandler()里一定要清除中斷標志,否則下一次中斷將不會被執行。
為什么EXTI4的中斷函數的名字是EXTI4_IRQHandler()? 在啟動文件startup_stm32f103xb.s的中斷向量表里有定義,當發現EXTI4中斷時,調用函數EXTI4_IRQHandler()。如下所示:
在這里插入圖片描述
回到EXTI4中斷回調函數EXTI4_IRQHandler(),既然EXTI4捕獲到中斷時,會調用函數EXTI4_IRQHandler()。但是,為什么EXTI4_IRQHandler()里需要用if (LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_4) != RESET)再一次確認是EXTI4的中斷標志位?
我認為主要有兩個原因:

  1. 規范中斷回調函數的一致性(都要再一次通過中斷標志位確認)
    • 在 STM32 中,并非所有 EXTI 線路都有獨立的中斷處理函數。例如,EXTI5 到 EXTI9 共享一個處理函數 EXTI9_5_IRQHandler(),在這種情況下,必須通過檢查標志位來判斷具體是哪條線路觸發了中斷。所以,不管是EXTI1(有獨立的中斷回調函數EXTI41_IRQHandler)還是EXTI9都要在中斷回調函數里再一次檢查中斷標志位。
  2. 確保中斷源的準確性
    • 盡管 EXTI4_IRQHandler() 通常只由 EXTI4 觸發,但在某些異常情況下(例如軟件配置錯誤、中斷控制器異常等),其他因素可能導致誤觸發。檢查 LL_EXTI_LINE_4 的標志位可以確認中斷確實是由 EXTI4 引發的,從而避免執行錯誤的處理邏輯。這種額外的驗證提高了代碼的健壯性。
      在這里插入圖片描述

二、寄存器的梳理


2.1、中斷向量表

《STM32F1參考手冊》的章節9.1.2-中斷與異常向量看到,EXTI中斷一共有如下:
在這里插入圖片描述
在這里插入圖片描述
如上所示,只有EXTI1~4有單獨的中斷地址,EXTI5~EXTI9共享一個中斷地址,EXTI10~EXTI15共享一個中斷地址。所以,弄明白中斷回調函數EXTI4_IRQHandler()里為什么再一次使用代碼if (LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_4) != RESET)去判斷中斷標志位了。從中斷向量表里看到,EXTI5~EXTI9確認共享一個中斷地址(函數指針)。

2.2、為什么PB4的中斷對應EXTI4?

在這里插入圖片描述
如上所示,根據《STM32F1參考手冊》的章節9.2.5看到GPIO跟EXTI中斷線的對應關系,PB4對應EXTI4。

2.3、外部中斷配置寄存器x (AFIO_EXTICRx)

在這里插入圖片描述
在這里插入圖片描述
如上所示,《STM32F1參考手冊》的章節8.4.4,寄存器AFIO_EXTICR2的段EXTI4 = 0001時,相當于將PB4映射到EXTI4。

MODIFY_REG(AFIO->EXTICR[1], 0xF << 0UL, 0x01 << 0UL); // 配置EXTI4線路映射到PB4引腳

2.4、上升沿觸發選擇寄存器(EXTI_RTSR)

在這里插入圖片描述
寄存器EXTI_PTSR的作用設置上升沿是否觸發EXTI線中斷。比如,位TR4 = 1相當于EXTI4啟動上升沿觸發中斷。

EXTI->RTSR |= 0x01UL << 4UL;  // EXTI4開啟上升沿觸發中斷
EXTI->RTSR |= 0x01UL << 10UL; // EXTI10開啟上升沿觸發中斷EXTI->RTSR &= ~(0x01UL << 4UL);  // EXTI4關閉上升沿觸發中斷
EXTI->RTSR &= ~(0x01UL << 10UL); // EXTI10關閉上升沿觸發中斷

2.5、下降沿觸發選擇寄存器(EXTI_FTSR)

在這里插入圖片描述
寄存器EXTI_FTSR的作用設置下降沿是否觸發EXTI線中斷。比如,為TR4 = 1相當于EXTI4啟動下降沿觸發中斷。

EXTI->FTSR |= 0x01UL << 4UL; // 開啟EXTI4下降沿中斷
EXTI->FTSR &= ~(0x01UL << 4UL); // 關閉EXTI4下降沿中斷

2.6、掛起寄存器(EXTI_PR)

在這里插入圖片描述
當寄存器EXTI_PR的位PR4置1時,代表觸發EXTI4中斷。 往里寫‘1’可以清除它。

if (EXTI->PR & (0x01UL << 4UL)) { // 判斷是不是EXTI4中斷EXTI->PR |= 0x01UL << 4UL; // 清除EXTI4的中斷標志
}if (EXTI->PR & (0x01UL << 10UL)) { 判斷是不是EXTI10中斷EXTI->PR |= 0x01 << 10UL; // 清除EXTI10的中斷標志
}

三、代碼(寄存器方式)


3.1、main.c

在這里插入圖片描述
如上所示,使用寄存器方式真的簡潔。

3.2、stm32f1xx_it.c

在這里插入圖片描述
如上所示,通過寄存器EXTI_PR的bit4判斷是否是EXTI4中斷。然后往bit4寫入‘1’就能清除中斷標志。
在這里插入圖片描述
如上所示,在debug模式看到,當PB4從低電平->高電平時,進入中斷回調函數EXTI4_IRQHandler(),且寄存器EXTI_PR的bit4被置1。

四、細節補充


4.1、EXTI4支持同時檢測PB4與PA4嗎??

在這里插入圖片描述
根據《STM32F1參考手冊》的章節9.2.5,根據PA0~PG0映射到EXTI0上,所以PA4~PG4是映射到EXTI4上。有一個疑問,STM32F1支持PA4、PB4一起映射到EXTI4上嗎??抱著這個疑問,我嘗試用CubeMX試試,看看ST官方工具允許不允許這樣做。
在這里插入圖片描述
如上圖所示,CubeMX不支持PA4與PB4一起映射到EXTI4。PA4映射到EXTI4后,如果將PAB4映射到EXTI4的話,PA4就會自動失效。所以,每一個EXTIx只能映射某一個PAx。

4.2、STM32F103一共支持多少路EXTI中斷?

在這里插入圖片描述
如上所示,參考《STM32F1參考手冊》的章節9.2.5,在STM32F103引腳資源足夠的情況下,最多支持16個GPIO口映射到EXTI外部中斷(EXTI0~EXTI15)。 另外EXTI16~EXTI19不能映射到普通GPIO,只能用于處理特定內部事件或外設的中斷/事件,比如EXTI18的USB喚醒事件。

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

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

相關文章

【C++進階二】string的模擬實現

【C進階二】string的模擬實現 1.構造函數和C_strC_str: 2.operator[]3.拷貝構造3.1淺拷貝3.2深拷貝 4.賦值5.迭代器6.比較ascll碼值的大小7.reverse擴容8.push_back尾插和append尾插9.10.insert10.1在pos位置前插入字符ch10.2在pos位置前插入字符串str 11.resize12.erase12.1從…

wokwi arduino mega 2560 - 點亮LED案例

截圖&#xff1a; 點亮LED案例仿真截圖 代碼&#xff1a; unsigned long t[20]; // 定義一個數組t&#xff0c;用于存儲20個LED的上次狀態切換時間&#xff08;單位&#xff1a;毫秒&#xff09;void setup() {pinMode(13, OUTPUT); // 將引腳13設置為輸出模式&#xff08;此…

vue3項目使用 python +flask 打包成桌面應用

server.py import os import sys from flask import Flask, send_from_directory# 獲取靜態文件路徑 if getattr(sys, "frozen", False):# 如果是打包后的可執行文件base_dir sys._MEIPASS else:# 如果是開發環境base_dir os.path.dirname(os.path.abspath(__file…

后端學習day1-Spring(八股)--還剩9個沒看

一、Spring 1.請你說說Spring的核心是什么 參考答案 Spring框架包含眾多模塊&#xff0c;如Core、Testing、Data Access、Web Servlet等&#xff0c;其中Core是整個Spring框架的核心模塊。Core模塊提供了IoC容器、AOP功能、數據綁定、類型轉換等一系列的基礎功能&#xff0c;…

LeetCode 第34、35題

LeetCode 第34題&#xff1a;在排序數組中查找元素的第一個和最后一個位置 題目描述 給你一個按照非遞減順序排列的整數數組nums&#xff0c;和一個目標值target。請你找出給定目標值在數組中的開始位置和結束位置。如果數組中不存在目標值target&#xff0c;返回[-1,1]。你必須…

告別分庫分表,時序數據庫 TDengine 解鎖燃氣監控新可能

達成效果&#xff1a; 從 MySQL 遷移至 TDengine 后&#xff0c;設備數據自動分片&#xff0c;運維更簡單。 列式存儲可減少 50% 的存儲占用&#xff0c;單服務器即可支撐全量業務。 毫秒級漏氣報警響應時間控制在 500ms 以內&#xff0c;提升應急管理效率。 新架構支持未來…

第十四屆藍橋杯真題

一.LED 先配置LED的八個引腳為GPIO_OutPut,鎖存器PD2也是,然后都設置為起始高電平,生成代碼時還要去解決引腳沖突問題 二.按鍵 按鍵配置,由原理圖按鍵所對引腳要GPIO_Input 生成代碼,在文件夾中添加code文件夾,code中添加fun.c、fun.h、headfile.h文件,去資源包中把lc…

《基于機器學習發電數據電量預測》開題報告

個人主頁&#xff1a;大數據蟒行探索者 目錄 一、選題背景、研究意義及文獻綜述 &#xff08;一&#xff09;選題背景 &#xff08;二&#xff09;選題意義 &#xff08;三&#xff09;文獻綜述 1. 國內外研究現狀 2. 未來方向展望 二、研究的基本內容&#xff0c;擬解…

UWP程序用多頁面實現應用實例多開

Windows 10 IoT ARM64平臺下&#xff0c;UWP應用和MFC程序不一樣&#xff0c;同時只能打開一個應用實例。以串口程序為例&#xff0c;如果用戶希望同時打開多個應用實例&#xff0c;一個應用實例打開串口1&#xff0c;一個應用實例打開串口2&#xff0c;那么我們可以加載多個頁…

Springboot整合Netty簡單實現1對1聊天(vx小程序服務端)

本文功能實現較為簡陋&#xff0c;demo內容僅供參考&#xff0c;有不足之處還請指正。 背景 一個小項目&#xff0c;用于微信小程序的服務端&#xff0c;需要實現小程序端可以和他人1對1聊天 實現功能 Websocket、心跳檢測、消息持久化、離線消息存儲 Netty配置類 /*** au…

GitLab 中文版17.10正式發布,27項重點功能解讀【二】

GitLab 是一個全球知名的一體化 DevOps 平臺&#xff0c;很多人都通過私有化部署 GitLab 來進行源代碼托管。極狐GitLab 是 GitLab 在中國的發行版&#xff0c;專門為中國程序員服務。可以一鍵式部署極狐GitLab。 學習極狐GitLab 的相關資料&#xff1a; 極狐GitLab 官網極狐…

好消息!軟航文檔控件(NTKO WebOffice)在Chrome 133版本上提示擴展已停用的解決方案

軟航文檔控件現有版本依賴Manifest V2擴展技術支持才能正常運行&#xff0c;然而這個擴展技術到2025年6月在Chrome高版本上就徹底不支持了&#xff0c;現在Chrome 133開始的版本已經開始彈出警告&#xff0c;必須手工開啟擴展支持才能正常運行。那么如何解決這個技術難題呢&…

字典樹與01trie

字典樹簡介 當我們通過字典查一個字或單詞的時候&#xff0c;我們會通過前綴或關鍵字的來快速定位一個字的位置&#xff0c;進行快速查找。 字典樹就是類似字典中索引表的一種數據結構&#xff0c;能夠幫助我們快速定位一個字符串的位置。 字典樹是一種存儲字符串的數據結構…

二十五、實戰開發 uni-app x 項目(仿京東)- 前后端輪播圖

定義了一個名為 Swiper 的Java類,用于表示一個輪播圖實體。它使用了 Jakarta Persistence API (JPA) 來映射數據庫表,并使用了 Lombok 庫來簡化代碼。以下是對代碼的詳細講解: 1. 包聲明 package com.jd.jdmall.model; 這行代碼聲明了該類所在的包路徑為 com.jd.jdmall.mode…

游戲搖桿開發:利用 Windows API 實現搖桿輸入捕獲

在現代游戲開發中&#xff0c;游戲搖桿&#xff08;Joystick&#xff09;作為一種重要的輸入設備&#xff0c;能夠為玩家提供更加沉浸式的游戲體驗。Windows 操作系統提供了一系列 API 函數&#xff0c;允許開發者輕松地捕獲和處理游戲搖桿的輸入。本文將介紹如何使用 Windows …

Ceph集群2025(Squid版)快速對接K8S cephFS文件存儲

ceph的塊存儲太簡單了。所以不做演示 查看集群 創建一個 CephFS 文件系統 # ceph fs volume create cephfs01 需要創建一個子卷# ceph fs subvolume create cephfs01 my-subvol -----------------#以下全部自動創建好 # ceph fs ls name: cephfs01, metadata pool: c…

Python中數據結構元組詳解

在Python中&#xff0c;元組&#xff08;Tuple&#xff09;是一種不可變的序列類型&#xff0c;常用于存儲一組有序的數據。與列表&#xff08;List&#xff09;不同&#xff0c;元組一旦創建&#xff0c;其內容無法修改。本文將詳細介紹元組的基本操作、常見運算、內置函數以及…

游戲引擎學習第183天

回顧和今天的計劃 我對接下來的進展感到非常興奮。雖然我們可能會遇到一些問題&#xff0c;但昨天我們差不多完成了將所有內容遷移到新的日志系統的工作&#xff0c;我們正在把一些內容整合進來&#xff0c;甚至是之前通過不同方式記錄時間戳的舊平臺層部分&#xff0c;現在也…

Spring 如何處理循環依賴

在 Spring 框架里&#xff0c;循環依賴指的是多個 Bean 之間相互依賴&#xff0c;從而形成一個閉環。例如&#xff0c;Bean A 依賴 Bean B&#xff0c;而 Bean B 又依賴 Bean A。Spring 主要通過三級緩存機制來處理循環依賴&#xff0c;下面詳細介紹相關內容。 1. 三級緩存的定…

Android開發layer-list

Android開發layer-list 它的用處可以在drawable上進行多圖拼接&#xff0c;比如啟動頁&#xff0c;不想圖片被拉伸就這么做。還有做某些線突出來。 示例代碼&#xff1a; <?xml version"1.0" encoding"utf-8"?> <layer-list xmlns:android&q…