按鍵輸入實驗
阿新 • • 發佈:2021-02-18
一、硬體設計
本實驗用到的硬體資源有: 1 ) 指示燈 DS0 、 DS1 2 ) 3 個按鍵: KEY0 、 KEY1 和 KEY_UP 。 DS0 、 DS1 和 STM32 的連線在上一章已經介紹了,在 MiniSTM32 開發板上的按鍵 KEY0連線在 PC5 上、 KEY1 連線在 PA15 上、 WK_UP 連線在 PA0 上。如圖 7.2.1 所示: 圖 7.2.1 按鍵與 STM32 連線原理圖 這裡需要注意的是: KEY0 和 KEY1 是低電平有效的,而二、軟體設計
1、先開啟 key.c 檔案,程式碼如下:
這段程式碼包含 2 個函式, void KEY_Init(void) 和 u8 KEY_Scan(u8 mode) , KEY_Init 是用來初始化按鍵輸入的 IO 口的。實現 PA0 、 PA15 和 PC5 的輸入設定,注意這呼叫了: GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); 這個函式,用於禁止 JTAG , 開啟 SWD ,因為 PA15 佔用了 JTAG 的一個 IO ,所以要禁止 JTAG ,從而讓 PA15 用作普通 IO 輸入。 KEY_Scan 函式,則是用來掃描這#include "key.h" #include "delay.h" //按鍵初始化函式 //PA15 和 PC5 設定成輸入 void KEY_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; ALIENTEK MiniSTM32 V3.0 開發板教程 140 STM32 不完全手冊(庫函式版) RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC, ENABLE);//使能 PORTA,PORTC 時鐘 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); //關閉 jtag,使能 SWD,可以用 SWD 模式除錯 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;//PA15 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //設定成上拉輸入 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 GPIOA15 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;//PC5 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //設定成上拉輸入 GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化 GPIOC5 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//PA0 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 設定成輸入,預設下拉 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化 GPIOA.0 } //按鍵處理函式 //返回按鍵值 //mode:0,不支援連續按;1,支援連續按; //返回值: //0,沒有任何按鍵按下 //KEY0_PRES,KEY0 按下 //KEY1_PRES,KEY1 按下 //WKUP_PRES,WK_UP 按下 //注意此函式有響應優先順序,KEY0>KEY1>WK_UP!! u8 KEY_Scan(u8 mode) { static u8 key_up=1;//按鍵按鬆開標誌 if(mode)key_up=1; //支援連按 if(key_up&&(KEY0==0||KEY1==0||WK_UP==1)) { delay_ms(10);//去抖動 key_up=0; if(KEY0==0)return KEY0_PRES; else if(KEY1==0)return KEY1_PRES; else if(WK_UP==1)return WKUP_PRES; }else if(KEY0==1&&KEY1==1&&WK_UP==0)key_up=1; return 0;// 無按鍵按下 }
2、接下來我們看看標頭檔案 key.h 裡面的程式碼
#ifndef __KEY_H
#define __KEY_H
#include "sys.h"
#define KEY0 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)//讀取按鍵 0
#define KEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)//讀取按鍵 1
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//讀取按鍵 2
#define KEY0_PRES 1 //KEY0
#define KEY1_PRES 2 //KEY1
#define WKUP_PRES 3 //WK_UP
void KEY_Init(void);//IO 初始化
u8 KEY_Scan(u8 mode); //按鍵掃描函式
#endif
這段程式碼裡面最關鍵就是
3
個巨集定義:
#define KEY0 GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)//讀取按鍵 0
#define KEY1 GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)//讀取按鍵 1
#define WK_UP GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)//讀取按鍵 2
前面跑馬燈實驗用的是位帶操作實現設定某個
IO
口的位。這裡我們採取的是庫函式的讀取
IO
口的值。當然,上面的功能也同樣可以通過位帶操作來簡單的實現:
//#define KEY0 PCin(5)
//#define KEY1 PAin(15)
//#define WK_UP PAin(0)
3、最後,我們看看 main.c 裡面編寫的主函式程式碼如下:
#include "led.h"
#include "delay.h"
#include "sys.h"
#include "key.h"
//ALIENTEK Mini STM32 開發板範例程式碼 2
//按鍵輸入實驗
//技術支援:www.openedv.com
//廣州市星翼電子科技有限公司
int main(void)
{
u8 t;
delay_init(); //延時函式初始化
LED_Init(); //初始化與 LED 連線的硬體介面
KEY_Init(); //初始化與按鍵連線的硬體介面
LED0=0; //點亮 LED
while(1)
{
t=KEY_Scan(0); //得到鍵值
switch(t)
{
case KEY0_PRES:
LED0=!LED0;
break;
case KEY1_PRES:
LED1=!LED1;
break;
case WKUP_PRES:
LED0=!LED0;
LED1=!LED1;
break;
default:
delay_ms(10);
}
} }
編譯結果: