STM32按鍵輸入


引言

這一節通過按鍵輸入的實驗,完成對IO口配置輸入的學習,同時學習如何通過軟件去抖動。這一節最終可以實現利用WK_UP按鍵控制LED亮滅的效果。




准備環節

與上一節點亮LED相類似,這一節也需要在 HARDWARE 文件夾內新建文件 key.hkey.c 。同時將相應的文件加入到工程中。

查看原理圖,獲取WK_UP按鍵的相關信息。對應IO口 PA0 。高電平為有效電平,且沒有外接下拉電阻。需要利用軟件設置IO口為下拉狀態。

GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) 該函數可以獲取到相應IO口的電平狀態。




編碼

步驟:

  • 使能IO口所在總線的時鍾
  • 配置按鍵相應IO口
  • 配置按鍵檢測函數
  • main函數調用

key.h

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

#define WK_UP   GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)	//WK_UP作為相應IO口狀態讀取的簡寫
//#define WK_UP PAin(0)	上一行代碼與該行效果相同

void KEY_Init(void);	//相應IO口配置初始化
u8 KEY_Scan(void);		//WK_UP按鍵處理函數
#endif

key.c

#include "key.h"
#include "sys.h" 
#include "delay.h"

void KEY_Init(void){
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//使能時鍾
	//IO口配置  由於是輸入模式,所以不需要配置輸出速度
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				//WK_UP對應PA0
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;			//初始化 下拉

	GPIO_Init(GPIOA, &GPIO_InitStructure);					//用上述配置的結構體初始化
}

u8 KEY_Scan(void){			//按鍵檢測
	static char flag = 0;	//默認WK_UP按鍵沒有按下
	if (WK_UP == 1){		//此時按鍵按下,可能是誤觸
		delay_ms(10);		
		if (WK_UP == 1){	//延遲10ms,再次判斷,可以排除誤觸的情況,稱為“軟件消抖”
			flag = 1;		//代表按鍵已經按過,但還未對其處理
		}
	}
	if (WK_UP == 0 && flag == 1){	//此時上一次按鍵未處理,且上次按鍵已經釋放
		flag = 0;			//復位flag
		return 1;			//主函數根據返回值的不同,進行不同的按鍵處理
	}
	return 0;
}

//以下是按鍵檢測的另一種寫法
//mode為1時,按鍵支持連按;為0時不支持連按
u8 KEY_Scan(u8 mode){
	static u8 flag = 1;
	if (mode)	flag = 1;	//mode為1時,進入檢測函數時,flag就始終為1,即實現按鍵連按

	if (flag && WK_UP){ 

		delay_ms(10);
		flag = 0;			//flag復位,若mode為0,則下次檢測不會再成功,即可阻止按鍵連按
		if(WK_UP)	return 1;

	}else if(!WK_UP){		//若上次flag被復位,這次按鍵檢測中將會對其置位,使得下次按鍵檢測正常進行
		flag = 1;
	}
	return 0;				//未檢測到按鍵按下,就會返回0
}

main.c

//此處省略頭文件,之后一般都會省略頭文件

int main(void){
	delay_init();
	LED_Init();		//LED相應IO口初始化
	KEY_Init();		//按鍵相應IO口初始化

	LED1 = 0;		//點亮LED1

	while(1){
		u8 key = KEY_Scan();	//檢測按鍵狀態,返回值是1或0
		if(key == 1){			//按鍵按下未處理
			LED1 = !LED1;		//點亮或熄滅LED1
		}else{
			delay_ms(10);		//未檢測到按鍵,進行下一次按鍵檢測
		}
	}
}

至此,將程序燒寫進單片機,就可以實現開篇提到的按鍵控制LED亮滅的功能了。這是不是非常的“阿美zing”呢?




補充

main.c中的LED_Init()相關配置代碼可以參看之前的這篇文章:

\(\color{#0000FF}{STM32點亮LED(學習IO口配置輸出)}\)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM