四、GPIO中斷實現按鍵功能

4.1 GPIO簡介

????????輸入輸出(I/O)是一個非常重要的概念。I/O泛指所有類型的輸入輸出端口,包括單向的端口如邏輯門電路的輸入輸出管腳和雙向的GPIO端口。而GPIO(General-Purpose Input/Output)則是一個常見的術語,指的是通用輸入輸出接口。

? ? ? ? 下面有請DeepSeek發言

?

LPC1110系列Cortex-M0微控制器的GPIO口的結構特點:

1端口可由軟件配置為輸入輸出
2引腳默認為輸入(所以點燈時需要改下方向)
3端口引腳的讀寫操作可屏蔽
4每個單獨引腳可被用作外部中斷輸入引腳
5每個GPIO中斷可配置為 高、低電平、下降、上升沿或雙邊沿觸發
6可對單獨端口的中斷級別進行配置

4.2 GPIO口的寄存器

????????所有GPIO寄存器都為32位?

? ? ? ? GPIO端口基址為

端口0??0x5000 0000
端口1??0x5001 0000

端口2

?0x5002 0000
端口3?0x5003 0000

4.2.1 數據寄存器? GPIOnDATA

? ? ? ? 用于讀取輸入引腳的狀態數據或者配置輸出引腳的輸出狀態

? ? ? ? 對應端口位置后四位范圍為 0000 ~ 3FFC

11:0PIOn_0 ~ PIOn_11的輸入/輸出數據
31:12保留

4.2.2 方向寄存器 GPIOnDIR

11:0PIOn_0 ~ PIOn_11的輸入/輸出方向? ?0為輸入, 1為輸出? 位數0-11與0-11引腳一一對應
31:12保留

4.2.3 中斷觸發寄存器 GPIOnIS

? ? ? ? 相較于基地址偏移量0x8004 即0x500n 8004

11:0PIOn_x? ? 0為邊沿觸發,1為電平觸發
31:12保留

4.2.4 中斷雙邊沿觸發寄存器?GPIOnIBE

? ? ? ? 相較于基地址偏移量0x8008 即0x500n 8008

11:0

0為通過4.2.5中寄存器GPIOnIEV控制PIOn_x的中斷

1為通過PIOn_x上雙邊沿觸發中斷

31:12保留

4.2.5 中斷事件寄存器 GPIOnIEV

????????相較于基地址偏移量0x800C?即0x500n 800C

11:0

0為上升沿或者高電平觸發中斷

1為下降沿或者低電平觸發中斷

具體邊沿還是電平 看4.2.3中GPIOnIS的設置

31:12保留

4.2.6 中斷屏蔽寄存器 GPIOnIE

????????相較于基地址偏移量0x8010?即0x500n 8010

11:0

0為中斷被屏蔽

1為中斷不被屏蔽

31:12保留

4.2.7 原始中斷狀態寄存器 GPIOnIRS

? ? ? ??相較于基地址偏移量0x8014?即0x500n 8014

? ? ? ? 屏蔽之前的中斷狀態

11:0

0為無中斷

1為滿足中斷要求

31:12保留

4.2.8 屏蔽中斷狀態寄存器 GPIOnMIS

????????相較于基地址偏移量0x8018?即0x500n 8018

? ? ? ? 考慮了屏蔽操作之后是否有中斷

11:0

0為無中斷,或者中斷被屏蔽

1為滿足中斷要求

31:12保留

4.2.9 中斷清除寄存器 GPIOnIC

????????相較于基地址偏移量0x801C?即0x500n 801C

11:0

0無操作

1為清除PIOn_x上的邊沿檢測邏輯

31:12保留

4.3 LPC上的GPIO按鍵

? ? ? ? 按鍵按下引腳低電平,不按是高電平

4.4 按鍵控制LED閃爍頻率

任務:

1.?BUTTON(PIO3_5)按鍵按下,閃爍頻率為1Hz,再次按下,恢復閃爍頻率為0.5Hz;

2. WEAKUP(PIO1_4)按鍵按下,閃爍頻率為2Hz,再次按下,恢復閃爍頻率為0.5Hz;

3. 適當考慮按鍵防抖功能。? ? ? ? ? ??

思路:

? ? ? ? 對于閃爍頻率的修改,首先考慮用什么控制LED閃爍,結合上章可以用SysTick,然后按鍵按下改變SysTick周期即可

? ? ? ? 對于按鍵防抖,由于按鍵固有的物理結構,按下后彈簧一上一下會影響中斷,需要用延時函數過濾抖動。

抖動時間大概10ms這樣, 我們可以用個延時函數過濾掉這個抖動過程,延時20ms就足夠了

代碼:

利用之前寫過的函數即可,復制個新工程,然后main文件里代碼如下

#include <LPC11xx.h>
#include "LED.h"//延時ms函數 // 太粗糙了,而且要根據機器指令與時鐘周期關系調整,也就防抖延時用一下
__inline void delay_ms(uint32_t a)    //約1ms延時函數 
{                           uint32_t i;while( a -- != 0){for(i = 0; i<5500; i++);}             
}int flag1 = 0, flag2 = 0; // 判斷botton 和 wakeup 按鍵上一次狀態
int main()
{LED_Init(); // PIO1_4LPC_IOCON->PIO1_4 &= ~(0x1F);  // 清除之前的配置LPC_IOCON->PIO1_4 |= 0x00;     // 配置為GPIO功能LPC_GPIO1->DIR &= ~(1UL << 4);// 設置GPIO方向為輸入LPC_GPIO1->IS &= ~(0x1 << 4); // 清除第 4 位,設置為邊沿觸發LPC_GPIO1->IBE &= ~(0x1 << 4); // 清除第 4 位,設置為單邊沿觸發LPC_GPIO1->IEV &= ~(0x1 << 4); // 清除第 4 位,設置為低電平觸發LPC_GPIO1 -> IE |= (0x1<<4); // 使能端口中斷LPC_IOCON->PIO1_4 |= (1UL << 5);          // 使能滯后模式LPC_GPIO1->IC |= (1UL << 4); // 清除中斷標志位NVIC_EnableIRQ(EINT1_IRQn); // 使能GPIO1中斷// PIO3_5LPC_IOCON->PIO3_5 &= ~(0x1F);   // 清除之前的配置LPC_IOCON->PIO3_5 |= 0x00;      // 配置為GPIO功能LPC_GPIO3->DIR &= ~(1UL << 5);// 設置GPIO方向為輸入LPC_GPIO3->IS &= ~(0x1 << 5); // 清除第 5 位,設置為邊沿觸發LPC_GPIO3->IBE &= ~(0x1 << 5); // 清除第 5 位,設置為單邊沿觸發LPC_GPIO3->IEV &= ~(0x1 << 5); // 清除第 5 位,設置為低電平觸發LPC_GPIO3 -> IE |= (0x1<<5); // 使能端口中斷LPC_IOCON->PIO3_5 |= (1UL << 5);  // 使能滯后模式LPC_GPIO3->IC |= (1UL << 5); //清除中斷標志NVIC_EnableIRQ(EINT3_IRQn);SysTick_Config(SystemCoreClock/100); // 0.01s進一次中斷 1s翻轉一次 0.5 Hzwhile(1){}
}void SysTick_Handler() /// 系統節拍定時器中斷函數
{static unsigned long ticks;if(ticks++ >= 99){ticks = 0;LED_Toggle();}
}// GPIO3_5的中斷服務函數,處理BUTTON按鍵按下事件
void PIOINT3_IRQHandler(void)
{if((LPC_GPIO3->MIS & (1UL << 5)) == (1UL << 5))// 檢查是否是PIO3_5的中斷{ delay_ms(20); // 消抖while((LPC_GPIO3->DATA & (1UL << 5)) == 0);delay_ms(20);if(flag1)SysTick_Config(SystemCoreClock/100); // 0.01s進一次中斷 1s翻轉一次 0.5 Hzelse SysTick_Config(SystemCoreClock/200); // 0.005s進一次中斷 0.5s翻轉一次 1 Hzflag1 = !flag1;LPC_GPIO3->IC |= (1UL << 5);          // 清除中斷標志}
}
// GPIO1_4的中斷服務函數,處理WAKEUP按鍵按下事件
void PIOINT1_IRQHandler(void)
{if((LPC_GPIO1->MIS & (1UL << 4)) == (1UL << 4)) // 檢查是否是PIO1_4的中斷{delay_ms(20);while((LPC_GPIO1->DATA & (1UL << 4)) == 0);delay_ms(20);if(flag2)SysTick_Config(SystemCoreClock/100); // 0.01s進一次中斷 1s翻轉一次 0.5 Hzelse SysTick_Config(SystemCoreClock/400); // 0.0025s進一次中斷 0.2s翻轉一次 2 Hz flag2 = !flag2;LPC_GPIO1->IC |= (1UL << 4);           // 清除中斷標志}
}

模塊化一下,新建Button.c Button.h文件,便于之后移植工程

main.c

#include <LPC11xx.h>
#include "LED.h"
#include "Button.h"int main()
{LED_Init(); WAKEUP_Init();Button_Init();while(1){}
}void SysTick_Handler() /// 系統節拍定時器中斷函數
{static unsigned long ticks;if(ticks++ >= 99){ticks = 0;LED_Toggle();}
}

Button.c

#include "Button.h"
int flag1 = 0, flag2 = 0; // 判斷botton 和 wakeup 按鍵上一次狀態//延時ms函數 // 太粗糙了,而且要根據機器指令與時鐘周期關系調整,也就防抖延時用一下
__inline void delay_ms(uint32_t a)    //約1ms延時函數 
{                           uint32_t i;while( a -- != 0){for(i = 0; i<5500; i++);}             
}void WAKEUP_Init(void)
{LPC_SYSCON -> SYSAHBCLKCTRL |= (1UL << 6) | (1UL << 16); // 使能GPIO時鐘和IO時鐘// PIO1_4LPC_IOCON->PIO1_4 &= ~(0x1F);  // 清除之前的配置LPC_IOCON->PIO1_4 |= 0x00;     // 配置為GPIO功能LPC_GPIO1->DIR &= ~(1UL << 4);// 設置GPIO方向為輸入LPC_GPIO1->IS &= ~(0x1 << 4); // 清除第 4 位,設置為邊沿觸發LPC_GPIO1->IBE &= ~(0x1 << 4); // 清除第 4 位,設置為單邊沿觸發LPC_GPIO1->IEV &= ~(0x1 << 4); // 清除第 4 位,設置為低電平觸發LPC_GPIO1 -> IE |= (0x1<<4); // 使能端口中斷LPC_IOCON->PIO1_4 |= (1UL << 5);          // 使能滯后模式LPC_GPIO1->IC |= (1UL << 4); // 清除中斷標志位NVIC_EnableIRQ(EINT1_IRQn); // 使能GPIO1中斷
}void Button_Init(void)
{LPC_SYSCON -> SYSAHBCLKCTRL |= (1UL << 6) | (1UL << 16); // 使能GPIO時鐘和IO時鐘// PIO3_5LPC_IOCON->PIO3_5 &= ~(0x1F);   // 清除之前的配置LPC_IOCON->PIO3_5 |= 0x00;      // 配置為GPIO功能LPC_GPIO3->DIR &= ~(1UL << 5);// 設置GPIO方向為輸入LPC_GPIO3->IS &= ~(0x1 << 5); // 清除第 5 位,設置為邊沿觸發LPC_GPIO3->IBE &= ~(0x1 << 5); // 清除第 5 位,設置為單邊沿觸發LPC_GPIO3->IEV &= ~(0x1 << 5); // 清除第 5 位,設置為低電平觸發LPC_GPIO3 -> IE |= (0x1<<5); // 使能端口中斷LPC_IOCON->PIO3_5 |= (1UL << 5);  // 使能滯后模式LPC_GPIO3->IC |= (1UL << 5); //清除中斷標志NVIC_EnableIRQ(EINT3_IRQn);
}// GPIO3_5的中斷服務函數,處理BUTTON按鍵按下事件
void PIOINT3_IRQHandler(void)
{if((LPC_GPIO3->MIS & (1UL << 5)) == (1UL << 5))// 檢查是否是PIO3_5的中斷{ delay_ms(20); // 消抖while((LPC_GPIO3->DATA & (1UL << 5)) == 0);delay_ms(20);if(flag1)SysTick_Config(SystemCoreClock/100); // 0.01s進一次中斷 1s翻轉一次 0.5 Hzelse SysTick_Config(SystemCoreClock/200); // 0.005s進一次中斷 0.5s翻轉一次 1 Hzflag1 = !flag1;LPC_GPIO3->IC |= (1UL << 5);          // 清除中斷標志}
}
// GPIO1_4的中斷服務函數,處理WAKEUP按鍵按下事件
void PIOINT1_IRQHandler(void)
{if((LPC_GPIO1->MIS & (1UL << 4)) == (1UL << 4)) // 檢查是否是PIO1_4的中斷{delay_ms(20);while((LPC_GPIO1->DATA & (1UL << 4)) == 0);delay_ms(20);if(flag2)SysTick_Config(SystemCoreClock/100); // 0.01s進一次中斷 1s翻轉一次 0.5 Hzelse SysTick_Config(SystemCoreClock/400); // 0.0025s進一次中斷 0.2s翻轉一次 2 Hz flag2 = !flag2;LPC_GPIO1->IC |= (1UL << 4);           // 清除中斷標志}
}

Button.h

#ifndef _BUTTON_H_
#define _BUTTON_H_#include <LPC11xx.h>void WAKEUP_Init(void);
void Button_Init(void);#endif

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

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

相關文章

vscode+CMake+Debug實現 及權限不足等諸多問題匯總

環境說明 有空再補充 直接貼兩個json tasks.json {"version": "2.0.0","tasks": [{"label": "cmake","type": "shell","command": "cmake","args": ["../"…

【Elasticsearch】post_filter

post_filter是 Elasticsearch 中的一種后置過濾機制&#xff0c;用于在查詢執行完成后對結果進行過濾。以下是關于post_filter的詳細介紹&#xff1a; 工作原理 ? 查詢后過濾&#xff1a;post_filter在查詢執行完畢后對返回的文檔集進行過濾。這意味著所有與查詢匹配的文檔都…

《數據可視化新高度:Graphy的AI協作變革》

在數據洪流奔涌的時代&#xff0c;企業面臨的挑戰不再僅僅是數據的收集&#xff0c;更在于如何高效地將數據轉化為洞察&#xff0c;助力決策。Graphy作為一款前沿的數據可視化工具&#xff0c;憑借AI賦能的團隊協作功能&#xff0c;為企業打開了數據協作新局面&#xff0c;重新…

Vue 2 與 Vue 3 的主要區別

Vue.js 是一個流行的前端框架&#xff0c;用于構建用戶界面和單頁應用。自從 Vue 2 發布以來&#xff0c;社區對其進行了廣泛的應用和擴展&#xff0c;而 Vue 3 的發布則帶來了許多重要的改進和新特性。 性能提升 Vue 3 在響應式系統上進行了重大的改進&#xff0c;采用了基于…

從零開始:用Qt開發一個功能強大的文本編輯器——WPS項目全解析

文章目錄 引言項目功能介紹1. **文件操作**2. **文本編輯功能**3. **撤銷與重做**4. **剪切、復制與粘貼**5. **文本查找與替換**6. **打印功能**7. **打印預覽**8. **設置字體顏色**9. **設置字號**10. **設置字體**11. **左對齊**12. **右對齊**13. **居中對齊**14. **兩側對…

【IoCDI】_Spring的基本掃描機制

目錄 1. 創建測試項目 2. 改變啟動類所屬包 3. 使用ComponentScan 4. Spring基本掃描機制 程序通過注解告訴Spring希望哪些bean被管理&#xff0c;但在僅使用Bean時已經發現&#xff0c;Spring需要根據五大類注解才能進一步掃描方法注解。 由此可見&#xff0c;Spring對注…

vue 引入百度地圖和高德天氣 都得獲取權限

vue接入百度地圖---獲取ak https://blog.csdn.net/qq_57144407/article/details/143430661 vue接入高德天氣&#xff0c; 需要授權----獲取key https://www.jianshu.com/p/09ddd698eebe

通向AGI之路:人工通用智能的技術演進與人類未來

文章目錄 引言:當機器開始思考一、AGI的本質定義與技術演進1.1 從專用到通用:智能形態的范式轉移1.2 AGI發展路線圖二、突破AGI的五大技術路徑2.1 神經符號整合(Neuro-Symbolic AI)2.2 世界模型架構(World Models)2.3 具身認知理論(Embodied Cognition)三、AGI安全:價…

python中的命名規范

在python中&#xff0c;命名規范是編寫清晰&#xff0c;可讀性強代碼的重要部分&#xff0c;遵循這些規范可以使代碼更易于理解和維護。 Type命名約定命名例子函數&#xff08;Function&#xff09;小寫單詞&#xff0c;下劃線分割單詞function,delta_function方法&#xff08…

【工具變量】中國省級八批自由貿易試驗區設立及自貿區設立數據(2024-2009年)

一、測算方式&#xff1a;參考C刊《中國軟科學》任曉怡老師&#xff08;2022&#xff09;的做法&#xff0c;使用自由貿易試驗區(Treat Post) 表征&#xff0c;Treat為個體不隨時間變化的虛擬變量&#xff0c;如果該城市設立自由貿易試驗區則賦值為1&#xff0c;反之賦值為0&am…

Java進階總結——集合

Java進階總結——集合 說明&#xff1a;對于以上的框架圖有如下幾點說明 1.所有集合類都位于java.util包下。Java的集合類主要由兩個接口派生而出&#xff1a;Collection和Map&#xff0c;Collection和Map是Java集合框架的根接口&#xff0c;這兩個接口又包含了一些子接口或實…

計算機視覺和圖像處理

計算機視覺與圖像處理的最新進展 隨著人工智能技術的飛速發展&#xff0c;計算機視覺和圖像處理作為其中的重要分支&#xff0c;正逐步成為推動科技進步和產業升級的關鍵力量。 一、計算機視覺的最新進展 計算機視覺&#xff0c;作為人工智能的重要分支&#xff0c;主要研究如…

3.PPT:華老師-計算機基礎課程【3】

目錄 NO12? NO34? NO56? NO789? NO12 根據考生文件夾下的Word文檔“PPT素材.docx”中提供的內容在PPT.pptx中生成初始的6張幻燈片 新建幻燈片6張→ctrlc復制→ctrlv粘貼開始→新建幻燈片→幻燈片(從大綱)→Word文檔注?前提是&#xff1a;Word文檔必須應用標題1、標題2…

(三)QT——信號與槽機制——計數器程序

目錄 前言 信號&#xff08;Signal&#xff09;與槽&#xff08;Slot&#xff09;的定義 一、系統自帶的信號和槽 二、自定義信號和槽 三、信號和槽的擴展 四、Lambda 表達式 總結 前言 信號與槽機制是 Qt 中的一種重要的通信機制&#xff0c;用于不同對象之間的事件響…

藍橋杯備賽題目練習(一)

一. 口算練習題 ## 題目描述 王老師正在教簡單算術運算。細心的王老師收集了 i 道學生經常做錯的口算題&#xff0c;并且想整理編寫成一份練習。 編排這些題目是一件繁瑣的事情&#xff0c;為此他想用計算機程序來提高工作效率。王老師希望盡量減少輸入的工作量&#xff0c;比…

深入探討:服務器如何響應前端請求及后端如何查看前端提交的數據

深入探討&#xff1a;服務器如何響應前端請求及后端如何查看前端提交的數據 一、服務器如何響應前端請求 前端與后端的交互主要通過 HTTP 協議實現。以下是詳細步驟&#xff1a; 1. 前端發起 HTTP 請求 GET 請求&#xff1a;用于從服務器獲取數據。POST 請求&#xff1a;用…

毫秒級響應的VoIP中的系統組合推薦

在高并發、低延遲、毫秒級響應的 VoIP 場景中&#xff0c;選擇合適的操作系統組合至關重要。以下是針對 Ubuntu linux-lowlatency、CentOS Stream kernel-rt 和 Debian 自定義 PREEMPT_RT 的詳細對比及推薦&#xff1a; 1. 系統組合對比 特性Ubuntu linux-lowlatencyCentO…

【LeetCode 刷題】回溯算法(4)-排列問題

此博客為《代碼隨想錄》二叉樹章節的學習筆記&#xff0c;主要內容為回溯算法排列問題相關的題目解析。 文章目錄 46.全排列47.全排列 II 46.全排列 題目鏈接 class Solution:def permute(self, nums: List[int]) -> List[List[int]]:res, path [], []used [0] * len(n…

基于多智能體強化學習的醫療AI中RAG系統程序架構優化研究

一、引言 1.1 研究背景與意義 在數智化醫療飛速發展的當下,醫療人工智能(AI)已成為提升醫療服務質量、優化醫療流程以及推動醫學研究進步的關鍵力量。醫療 AI 借助機器學習、深度學習等先進技術,能夠處理和分析海量的醫療數據,從而輔助醫生進行疾病診斷、制定治療方案以…

深度學習篇---張量數據流動處理

文章目錄 前言第一部分&#xff1a;張量張量的基本概念1.維度標量&#xff08;0維&#xff09;向量&#xff08;1維&#xff09;矩陣&#xff08;2維&#xff09;三維張量 2.形狀 張量運算1.基本運算加法減法乘法除法 2.廣播3.變形4.轉置5.切片6.拼接7.矩陣分解8.梯度運算&…