再造STM32---第十部分:GPIO輸入—按鍵檢測

2021-01-10 電子工程世界

       本章參考資料:《STM32F4xx 參考手冊》、庫幫助文檔《stm32f4xx_dsp_stdperiph_lib_um.chm》。

       按鍵檢測使用到 GPIO 外設的基本輸入功能,本章中不再贅述 GPIO 外設的概念,如您忘記了,可重讀前面「GPIO 框圖剖析」小節, STM32 標準庫中 GPIO 初始化結構體GPIO_TypeDef 的定義與「定義引腳模式的枚舉類型」小節中講解的相同。


10.1 硬體設計:

       按鍵機械觸點斷開、閉合時,由於觸點的彈性作用,按鍵開關不會馬上穩定接通或一下子斷開,使用按鍵時會產生圖 10-1 中的帶波紋信號,需要用軟體消抖處理濾波,不方便輸入檢測。本實驗板連接的按鍵帶硬體消抖功能,見圖 10-2,它利用電容充放電的延時,消除了波紋,從而簡化軟體的處理,軟體只需要直接檢測引腳的電平即可。


       從按鍵的原理圖可知,這些按鍵在沒有被按下的時候, GPIO 引腳的輸入狀態為低電平(按鍵所在的電路不通,引腳接地),當按鍵按下時, GPIO 引腳的輸入狀態為高電平(按鍵所在的電路導通,引腳接到電源)。只要我們檢測引腳的輸入電平,即可判斷按鍵是否被按下。

       若您使用的實驗板按鍵的連接方式或引腳不一樣,只需根據我們的工程修改引腳即可,程序的控制原理相同。


10.2 軟體設計:

       同 LED 的工程,為了使工程更加有條理,我們把按鍵相關的代碼獨立分開存儲,方便以後移植。在「工程模板」之上新建「bsp_key.c」及「bsp_key.h」文件,這些文件也可根據您的喜好命名,這些文件不屬於 STM32 標準庫的內容,是由我們自己根據應用需要編寫的。


10.2.1 編程要點:

1. 使能 GPIO 埠時鐘;

2. 初始化 GPIO 目標引腳為輸入模式(引腳默認電平受按鍵電路影響,浮空/上拉/下拉均沒有區別);

3. 編寫簡單測試程序,檢測按鍵的狀態,實現按鍵控制 LED 燈。


10.2.2 代碼分析:

1. 按鍵引腳宏定義:

       同樣,在編寫按鍵驅動時,也要考慮更改硬體環境的情況。我們把按鍵檢測引腳相關的宏定義到 「bsp_key.h」文件中,見代碼清單 10-1。

代碼清單 10-1 按鍵檢測引腳相關的宏


//引腳定義

/*******************************************************/

#define KEY1_PIN GPIO_Pin_0

#define KEY1_GPIO_PORT GPIOA

#define KEY1_GPIO_CLK RCC_AHB1Periph_GPIOA

#define KEY2_PIN GPIO_Pin_13

#define KEY2_GPIO_PORT GPIOC

#define KEY2_GPIO_CLK RCC_AHB1Periph_GPIOC

/*******************************************************/

       以上代碼根據按鍵的硬體連接, 把檢測按鍵輸入的 GPIO 埠、 GPIO 引腳號以及

GPIO 埠時鐘封裝起來了。


2. 按鍵 GPIO 初始化函數:

       利用上面的宏,編寫按鍵的初始化函數,見代碼清單 10-2。

代碼清單 10-2 按鍵 GPIO 初始化函數


/**

* @brief 配置按鍵用到的 I/O 口

* @param 無

* @retval 無

*/

void Key_GPIO_Config(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/*開啟按鍵 GPIO 口的時鐘*/

RCC_AHB1PeriphClockCmd(KEY1_GPIO_CLK|KEY2_GPIO_CLK,ENABLE);

/*選擇按鍵的引腳*/

GPIO_InitStructure.GPIO_Pin = KEY1_PIN;

/*設置引腳為輸入模式*/

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

/*設置引腳不上拉也不下拉*/

GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

/*使用上面的結構體初始化按鍵*/

GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);

/*選擇按鍵的引腳*/

GPIO_InitStructure.GPIO_Pin = KEY2_PIN;

/*使用上面的結構體初始化按鍵*/

GPIO_Init(KEY2_GPIO_PORT, &GPIO_InitStructure);

}

同為 GPIO 的初始化函數,初始化的流程與「LED GPIO 初始化函數」章節中的類似,主要區別是引腳的模式。函數執行流程如下:

       (1) 使用 GPIO_InitTypeDef 定義 GPIO 初始化結構體變量,以便下面用於存儲 GPIO 配置。

       (2) 調用庫函數 RCC_AHB1PeriphClockCmd 來使能按鍵的 GPIO 埠時鐘,調用時我們使用「|」操作同時配置兩個按鍵的時鐘。

       (3) 向 GPIO 初始化結構體賦值,把引腳初始化成浮空輸入模式,其中的 GPIO_Pin 使用宏「KEYx_PIN」來賦值,使函數的實現方便移植。 由於引腳的默認電平受按鍵電路影響,所以設置成「浮空/上拉/下拉」模式均沒有區別。

       (4) 使用以上初始化結構體的配置,調用 GPIO_Init 函數向寄存器寫入參數,完成 GPIO 的初始化,這裡的 GPIO 埠使用「KEYx_GPIO_PORT」宏來賦值,也是為了程序移植方便。

       (5) 使用同樣的初始化結構體,只修改控制的引腳和埠,初始化其它按鍵檢測時使用的GPIO 引腳。

3. 檢測按鍵的狀態:

       初始化按鍵後,就可以通過檢測對應引腳的電平來判斷按鍵狀態了,見代碼清單 10-3。

代碼清單 10-3 檢測按鍵的狀態


/** 按鍵按下標置宏

* 按鍵按下為高電平,設置 KEY_ON=1, KEY_OFF=0

* 若按鍵按下為低電平,把宏設置成 KEY_ON=0 , KEY_OFF=1 即可

*/

#define KEY_ON 1

#define KEY_OFF 0

/**

* @brief 檢測是否有按鍵按下

* @param GPIOx:具體的埠, x 可以是(A...K)

* @param GPIO_PIN:具體的埠位, 可以是 GPIO_PIN_x(x 可以是 0...15)

* @retval 按鍵的狀態

* @arg KEY_ON:按鍵按下

* @arg KEY_OFF:按鍵沒按下

*/

uint8_t Key_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)

{

/*檢測是否有按鍵按下 */

if (GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON ) {

/*等待按鍵釋放 */

while (GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == KEY_ON);

return KEY_ON;

} else

return KEY_OFF;

}

       在這裡我們定義了一個 Key_Scan 函數用於掃描按鍵狀態。 GPIO 引腳的輸入電平可通過讀取 IDR 寄存器對應的數據位來感知,而 STM32 標準庫提供了庫函數GPIO_ReadInputDataBit 來獲取位狀態,該函數輸入 GPIO 埠及引腳號,函數返回該引腳的電平狀態,高電平返回 1,低電平返回 0。 Key_Scan 函數中以 GPIO_ReadInputDataBit 的返回值與自定義的宏「KEY_ON」對比,若檢測到按鍵按下,則使用 while 循環持續檢測按鍵狀態,直到按鍵釋放,按鍵釋放後 Key_Scan 函數返回一個「KEY_ON」值;若沒有檢測到按鍵按下,則函數直接返回「KEY_OFF」。若按鍵的硬體沒有做消抖處理,需要在這個 Key_Scan 函數中做軟體濾波,防止波紋抖動引起誤觸發。

4. 主函數:

       接下來我們使用主函數編寫按鍵檢測流程,見代碼清單 10-4。

代碼清單 10-4 按鍵檢測主函數


/**

* @brief 主函數

* @param 無

* @retval 無

*/

int main(void)

{

/* LED 埠初始化 */

LED_GPIO_Config();

/*初始化按鍵*/

Key_GPIO_Config();

/* 輪詢按鍵狀態,若按鍵按下則反轉 LED */

while (1) {

if ( Key_Scan(KEY1_GPIO_PORT,KEY1_PIN) == KEY_ON ) {

/*LED1 反轉*/

LED1_TOGGLE;

}

if ( Key_Scan(KEY2_GPIO_PORT,KEY2_PIN) == KEY_ON ) {

/*LED2 反轉*/

LED2_TOGGLE;

}

}

}

       代碼中初始化 LED 燈及按鍵後,在 while 函數裡不斷調用 Key_Scan 函數,並判斷其返回值,若返回值表示按鍵按下,則反轉 LED 燈的狀態。


10.2.3 下載驗證:

       把編譯好的程序下載到開發板並復位,按下按鍵可以控制 LED 燈亮、滅狀態。


關鍵字:STM32  GPIO輸入  按鍵檢測 編輯:什麼魚 引用地址:http://news.eeworld.com.cn/mcu/ic466103.html

推薦閱讀

STM32項目(三)——通用LIN控制器

需求:LIN馬達控制器:AFS(DHL+AFL)——彎道輔助照明系統DHL:上極限,下極限,零位,馬達老化循環;AFL:左極限,右極限,零位,馬達老化循環;所有參數可配置:上極限,下極限,零位,左極限,右極限,馬達循環上極限,馬達循環下極限,馬達循環次數,馬達循環等待時間;保存至少30款產品的配置,配置界面需要有添加,讀取,查找,刪除功能。方案:STM32 + LIN + 串口(使用NXP的串口屏,TJA系列的LIN晶片)STM32的LIN接口作為主節點,馬達作為從節點。系統設計:RTX多任務設計,串口處理任務,顯示屏處理任務,LIN發送任務;(1)、串口處理任務:點擊串口屏會獲取到點擊的坐標值,串口中斷接受到數據加入到隊列;任務

發表於 2020-12-09

STM32項目(二) —— 車燈測試臺架

需求:(1)、點燈控制器:在線節拍,離線節拍;(2)、PWM控制盒:在線PWM,離線PWM;(3)、電流測試模塊:檢測車燈電流校準係數;方案:點燈控制器:STM32 + CAN + GPIO節拍:比如亮多長時間,滅多長時間;大節拍中嵌套多個小節拍,每個燈對應相同或者不同的節拍。上位機下發控制指令,表明此時是在線還是離線。(離線跑的節拍是在在線模式下下載的)在線模式:如果是直接輸出,按照指定格式下發CAN消息,MCU接受消息並解析,切繼電器點燈;如果是存儲節拍,MCU內部Flash存儲上位機通過CAN下發的點燈節拍。離線模式:從內部Flash中讀取節拍,並控制繼電器點燈;模式切換按鈕:不僅可以通過上位機控制在線/離線模式,還可

發表於 2020-12-09

STM32項目(一) —— 展示車座椅

功能:模擬人開車時,ACR和ABL的變化。 主控制器:STM32(CAN,串口,網口,輸入,輸出)上位機:LibView ACR:卷收器(座椅上面的安全帶)ABL:電機(座椅右下角接安全帶的插孔)PUMA:控制器發送CAN給PUMA,PUMA控制ACR和ABL(DBC文件的解析);ACR通過CAN控制,ABL通過PWM控制電機。 STM32硬體接口:按鍵盒8路輸入,網口與工控機軟體通信,CAN1直接控制ACR,CAN2給PUMA信號控制ACR,串口與上位機軟體通信(控制方向盤震動)。 主要有兩塊功能:靜態模式和遊戲模式。 靜態模式:UC-WinRoad沒工作時,STM32檢測

發表於 2020-12-09

STM32——GPIO(2)

, GPIO_InitTypeDef* GPIO_InitStruct){  uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;  uint32_t tmpreg = 0x00, pinmask = 0x00;  /* 斷言,用於檢查輸入的參數是否正確 */  assert_param(IS_GPIO_ALL_PERIPH(GPIOx));  assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));  assert

發表於 2020-12-09

Octonion全新AI工業狀態監測擴展軟體包可在STM32 MCU完美運行

專業開發工業設備診斷邊緣人工智慧(AI)的深度技術軟體公司Octonion 發布了一個STM32Cube擴展軟體包。該軟體包是針對來自橫跨多重電子應用領域的全球領先的半導體供應商意法半導體(STMicroelectronics,簡稱ST;紐約證券交易所代碼:STM)的工業級STM32L4 +微控制器開發板的優化過的狀態監測解決方案。 Octonions的新軟體包支持意法半導體在快速增長的工業狀態監測和預測性維護市場上發起的使用STM32微控制器和微處理器開發人工智慧應用的市場活動。Octonion的I-CUBE-OCTMI 軟體包是一個運行在STM32 超低功耗MCU上的自我維護系統,系統

發表於 2020-12-09

STM32——流水燈

stm32f10x_conf.h:打開stm32f10x_gpio.h和stm32f10x_rcc.h;stm32f10x_gpio.c 和 stm32f10x_rcc.c加入工程模板中,只說重點。【stm32f10x_rcc.c用於配置系統時鐘 和外設時鐘,由於每個外設都要配置時鐘,所以它是每個外設都需要用到的庫文件。】// 新建led.h  led.c#ifndef  _LED_H_#define  _LED_H_ #include "stm32f10x.h" #define ON  0#define OFF 1 #define LED1

發表於 2020-12-08

相關焦點

  • STM32關於GPIO的問題
    答:當TPAL=0時:如果在啟動侵入檢測TAMPER引腳前(通過設置TPE位)該引腳已經為高電平,一旦啟動侵入檢測功能,則會產生一個額外的侵入事件(儘管在TPE位置』1』後並沒有出現上升沿)。 ● 當TPAL=1時:如果在啟動侵入檢測引腳TAMPER前(通過設置TPE位)該引腳已經為低電平,一旦啟動侵入檢測功能,則會產生一個額外的侵入事件(儘管在TPE位置』1』後並沒有出現下降沿)。
  • STM32 CubeMX按鍵中斷
    應用場合模擬輸入:應用ADC模擬輸入,或者低功耗下省電  浮空輸入:可以做KEY識別,外部按鍵輸入,IO的電平狀態是不確定,完全由外部輸入決定下拉輸入:IO內部下拉電阻輸入上拉輸入:IO內部上拉電阻輸入
  • STM32 嵌入式學習入門(3)——STM32F103 按鍵輸入控制LED燈
    按鍵是單片機上一個很重要的輸入設備,也很容易掌握,只要明白了IO口最基本的使用,就可以操作按鍵了。我們的目的是控制開發板上板載的三個按鍵來操作開發板上板載的兩個LED燈實現亮或滅(按鍵第一次按下時燈亮,再按下時燈滅,以此類推)。
  • stm32晶片被鎖,使用jlink就能輕輕鬆鬆解鎖
    如果一不小心將stm32開發板的晶片給鎖了,那原因可能是忽略了一個比較低級的問題,就是將stm32中的一些不能獨立使用的IO口給了高電平,stm32中有很多口是不能獨立使用的,如圖(以stm32103rct6  正點原子的mini板為例):(N:表示不能獨立使用,Y:表示能獨立使用)
  • stm32的USART如何發送字符、字符串
    一、stm32有自己的字符發送函數。void PC_SendChar(uint8_t DataToSend){USART_SendData (USART1 ,DataToSend);while(USART_GetFlagStatus (USART1 ,USART_FLAG_TC )!
  • 關於stm32的GPIO的操作
    > 首先簡述一下stm3的gpio接口(interface):主機(CPU)與外部設備(指MCU片上外設)之間緩衝電路。    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推輓輸出  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//50M  GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIOF}以下是配置按鍵的接口
  • STM32_GPIO配置及庫函數講解——獨立按鍵
    UserButton硬體連接如下圖所示:當按鍵被按下,PB9檢測到低電平,相反PB9被3.3V電源拉高。輸入模式還是輸出模式。STM32_GPIO配置及庫函數講解——LED跑馬燈已講過。
  • STM32串口接收數據保存到數組——遇到問題及解決方法
    遇到問題:PC端發送給stm32的字符串數據,只有最後一個字節被保存在數組的首地址,其他數據都丟失,而且數組中只有首地址有數據。比如我用PC給stm32發送abcd,返回到PC串口助手的數據只有d,查看數組發現裡面數據[d,0,0,0,0,0,0,0,0........]。
  • 通過stm32 cubemx 配置 串口中斷
    ④部分代碼:voidHAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){ voidHAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)//中斷回調函數{  自己的代碼; } 關鍵字:stm32
  • STM32的GPIO使用的函數剖析
    這個函數的實現是在Stm32f10x_gpio.c文件中,若要使用該函數在相應的應用程式的前面包含Stm32f10x_gpio.h頭文件。1、參數GPIO_TypeDef該函數的第一個參數為GPIO_TypeDef,它是一個結構體類型,該類型在Stm32f10x.h中被定義。
  • STM32-按鍵輸入實驗學習筆記
    按鍵掃描函數key.c片段://按鍵初始化函數//特別注意:在該函數之後,JTAG將無法使用(SWD也無法使用)//如果想JTAG仿真,可以屏蔽該函數。
  • stm32與FPGA通信代碼實現方案spi
    //為什麼要邊沿檢測,在SPI主從機通信中FPGA在sclk上升沿接收數據,在sclk下降沿進行數據發送//第一部分:sclk上升沿檢測模塊:存儲在scl_up_flag中搞個always@(posedge clk )如同步復位的話就先清零spi_scl_flag,else只是clk上升沿的話就再判斷
  • stm32通過spi連接esp8266的hspi 開發
    剛剛做了stm32通過spi連接esp8266的開發,目前已經解決了遇到的大多數問題,基本可以交付使用了,寫一篇文章留作記錄,也可以給以後做這個的朋友做為參考。1,stm32 spi驅動開發我使用了stm32的標準庫,並沒用hal庫,因為之前stm32的大部分其它的程序用的都是標準庫開發的,所以沒有改為hal庫。對於spi協議,可以參考另外的文檔,我已經將其傳到了CSDN上可以到我的CSDN的資源頁中下載。如果下載不到可以email 聯繫我,abc_123_ok at 163.com。
  • Longan nano(GD32VF103)GPIO最小配置
    gd32vf103cbt6跟stm32的使用非常相似,如果使用C開發,基本上與指令集架構沒啥關係。本文介紹GPIO的最小配置,不使用sdk,直接操作寄存器,這樣可以更加直觀的了解晶片和外設。控制gpio就跟學程式語言列印hello world一樣,是開始學習新知識的第一步。
  • 「正點原子FPGA連載」第三十一章Linux按鍵輸入實驗
    領航者開發板上有5個按鍵,四個輕觸式按鍵和一個觸摸按鍵,本章我們就以PS_KEY0按鍵為例,使用此按鍵來完成GPIO輸入驅動程序,同時利用第三十章講的互斥鎖來對按鍵值進行保護。31.1Linux下按鍵驅動原理按鍵驅動和LED驅動原理上來講基本都是一樣的,都是操作GPIO,只不過一個是讀取GPIO的高低電平,一個是從GPIO輸出高低電平。
  • STM32常用數據類型分析
    typedef unsigned       __INT64 uint64_t;/*stm32f10x.h*/typedef uint32_t  u32;typedef uint16_t u16;typedef uint8_t  u8;mdk char的默認類型是unsigned charstm32
  • 基於Linux系統實現DragonBoard 410c GPIO的控制
    ,檢測開關是否被按下,開關每次按下LED燈狀態改變一次,整個控制電路硬體連接如圖2所示。,起命令如下:mkdir key_led_testvim key_led_test.c通過GPIO口控制LED和檢測按鍵信號的基本原理如下:首先需要對使用的GPIO口進行導入,完成導入後的GPIO口才可以進讀寫,起導入GPIO口的函數機代碼如下:int Export_GPIO(int gpio) {int fd;
  • 關於stm32硬體spi的miso口配置
    其實配置為復用推輓輸出也是可以正常工作的,只不過配置成浮空輸入和上拉輸入更容易理解。具體產生這一問題的原因是:從功能上來說,MISO應該配置為輸入模式才對,但為什麼也可以配置為GPIO_Mode_AF_PP?實際上當一個GPIO埠配置為GPIO_Mode_AF_PP時,片上外設的復用功能輸出信號會連接到輸出控制電路,然後在埠上產生輸出信號。
  • STM32的GPIO輸入輸出模式配置
    最近在看數據手冊的時候,發現STM32的GPIO輸入輸出模式的配置種類有8種之多(輸入和輸入各4種):(1)GPIO_Mode_AIN模擬輸入(2)GPIO_Mode_IN_FLOATING浮空輸入(3)GPIO_Mode_IPD下拉輸入(4)GPIO_Mode_IPU
  • 詳解STM32 ISP設置及使用說明
    1.FlyMcu.exe可以正常使用,選擇好對應串口後,按下讀器件信息,軟體開始與stm32通訊,並讀取到晶片的型號,版本,容量等信息,表明通訊成功;如果顯示一直連接中,則需reset一下stm32電路板,即可聯通成功.