天天看點

STM32學習筆記之按鍵輸入實驗

借助正點原子F103戰艦V3開發闆進行學習,采用庫函數程式設計。

參考資料:正點原子教學視訊,《STM32F1開發指南-庫函數版本_V3.3》

**硬體連接配接:**KEY0連接配接到PE4,KEY1連接配接到PE3,KEY2連接配接到PE2,另一端接地,KEY_UP連接配接到PA0,另一端接高電平。

是以PE2、PE3、PE4低電平時表示按鍵按下,PA0高電平時表示WK_UP按下。

STM32學習筆記之按鍵輸入實驗

與前兩個實驗不同,LED和蜂鳴器實驗均是GPIO輸出,按鍵實驗是輸入,需要用庫函數GPIO_ReadInputDataBit()讀取GPIO口電平。

在key.h中定義好讀取到的電平标志,按鍵按下标志并建立一個按鍵初始化函數和按鍵掃描函數,完整代碼如下:

/**********  key.h **********/

#ifndef __KEY_H
#define __KEY_H
#include "sys.h"

#define KEY0 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_4)       //電平标志
#define KEY1 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_3)
#define KEY2 GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2)
#define WK_UP GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)

#define KEY0_PRES   1		//KEY0按下
#define KEY1_PRES   2		//KEY1按下
#define KEY2_PRES	3		//KEY2按下
#define KEY_UP_PRES 4	    //KEY_UP按下(即WK_UP/KEY_UP)

void KEY_Init(void);	    //按鍵初始化函數
u8 KEY_Scan(u8);			//按鍵掃描函數

#endif
           

在key.c中寫好前面定義好的按鍵初始化函數和按鍵掃描函數,GPIO初始化與LED實驗和蜂鳴器實驗有些不同,KEY0,KEY1,KEY2接地采用上拉輸入,WK_UP接高電平采用下拉輸入。按鍵初始化函數如下:

void KEY_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOA, ENABLE);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;		//KEY0,KEY1,KEY2一端接的地,需上拉輸入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_3 | GPIO_Pin_2;	//初始化GPIOE2,3,4
	GPIO_Init(GPIOE, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;		//KEY_UP一端接的高電平,需下拉輸入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;		//初始化GPIOA0
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}
           

按鍵掃描有兩種模式,一種是支援連按、一種不支援連按,設定一個輸入參數mode,mode=1時表示支援連按,mode=0時表示不支援連按;同時需要延時去抖,定義一個按鍵松開标志key_up,key_up=1時表示按鍵松開,按鍵掃描函數如下:

u8 KEY_Scan(u8 mode)		
{
	static u8 key_up = 1;		// 按鍵松開标志
	if(mode)
		key_up = 1;
	if(key_up&&(KEY0==0 || KEY1==0 || KEY2==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(KEY2==0)
			return KEY2_PRES;
		else if(WK_UP==1)
			return KEY_UP_PRES;
	}
	
	else if(KEY0==1 || KEY1==1 || KEY2==1 || WK_UP==0)		//按鍵松開
		key_up = 1;
	return 0;
}
           

用KEY0控制LED0翻轉,KEY1控制LED1翻轉,KEY2控制LED0和LED1同時翻轉,用WK_UP控制LED0和LED1同時亮起并使蜂鳴器響起,主函數代碼如下:

int main(void)
{
	vu8 key = 0;
	LED_Init();
	delay_init();
	BEEP_Init();
	KEY_Init();
	
	while(1)
	{
		key = KEY_Scan(0);	// 得到不支援連按的鍵值
		if(key)
		{
			switch(key)
			{
			case KEY0_PRES:		
				LED0 = !LED0;		//控制LED0翻轉
			break;
			case KEY1_PRES:
				LED1 = !LED1;		//控制LED1翻轉
			break;
			case KEY2_PRES:		
				LED0 = !LED0;
				LED1 = !LED1;		//控制LED0和LED1同時翻轉
			break;
			case KEY_UP_PRES:
				BEEP = !BEEP;
				LED0 = 0;
				LED1 = 0;				//控制LED0和LED1亮起起蜂鳴器響起
			}
		}
		else delay_ms(10);
	}
}
           

編譯無誤後,用ST-Link将程式下載下傳到開發闆中,實驗效果如預期。

繼續閱讀