按鍵識別(基於STM32F103ZET6)

前面我們熟悉了跑馬燈,其實蜂鳴器是一個原理,只是輸出的電平不同而已
今天我們使用板載KEY0,KEY1,KEY_UP來控制DS0,DS1,和蜂鳴器,剛剛學習的朋友可能會有疑惑,難道按鍵和led燈在硬件上是相連的嗎?當然不是,只是我們在識別了按鍵之後,再來操作led或者蜂鳴器的!
我們拿着已經配置好的新工程或者之前的工程也可以,都是需要用到的,下面就開始思維梳理:
想要用按鍵控制led(蜂鳴器也可以),操作的是哪些io口,並且是什麼模式,這樣我們纔好去初始化我們的io口,包括兩部分,一端是識別端,按鍵識別,另一端是外設(led或者其他),他們都是由goio控制,分別配置各自的模式等等,在led端之前的博客有講到,就不提了,主要是gpio的識別,小編曾經也是爲了這些苦惱了好半天,雖然我們的按鍵可以用gpio中斷來寫,但是爲什麼要使用普通方法來控制呢?我覺得學習的一種算法,思維,所以gpio中斷後面我還會寫,我們直接上代碼,我會對代碼進行我自己的理解講給大家:
我命名的按鍵頭文件:key.h::

#ifndef KEY_H
#define KEY_H
#include "sys.h"//
#define key_up GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#define key1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)
#define key0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)
#define KEYUP 1
#define KEY1 2
#define KEY0 3
void keyinit(void);
int keyscan(void);
#endif

h文件中,sys.h主要是實現io口的讀入和輸出,並且在按鍵宏定義中使用了read函數,是必不可少的,這裏我們把按鍵值直接宏定義爲gpio讀到的值,方便我們在主函數中調用
key.c

#include "key.h"
void keyinit(void)
{
	   GPIO_InitTypeDef GPIO_InitStructure;
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOA,ENABLE);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;
GPIO_Init(GPIOE,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;
GPIO_Init(GPIOE,&GPIO_InitStructure);
}
int keyscan(void)
{
	static int check=1;
	if(check&&(key_up==1||key1==0||key0==0))
		{
			check=0;
			  delay_ms(10);
			if(key_up==1||key1==0||key0==0)
			{
					if(key_up==1)
					{
						return KEYUP;
					}
					else if(key1==0)
					{
						return KEY1;
					}
						else if(key0==0)
					{
					return KEY0;	
					}
					else
					{
						return 0;
					}		
			}
		}
		else if(key_up==0&&key1==1&&key0==1)
		check=1;
		return 0;
}

重點就在.c文件裏,我相信大家一千到這裏都會有疑惑,資料上明明分了連按和非連按,有什麼作用呢,小編也試了,當能連按時,我們的操作是不穩定的(正點原子上的資料),也就是gpio(按鍵)的識別是不怎麼成功的,當不能連按時,按鍵的識別是很穩定的(正點原子上的資料),我當時寫出來就是連按的邏輯,導致識別不穩定,採用了非連按(跑空一掃描環節,相當於降低了掃描頻率),就能很好的識別,並控制led和外設了,當然,我在編寫代碼的時候直接默認了非連續按鍵識別
還有就是模式的選擇,在配置三個io口時,配置了兩個上拉輸入,一個下拉輸入,爲什麼是這樣呢?
其實這個很像“線與“,在led配置中,我們選擇了上拉,如果說這時候來了高電平,與我們的上拉相與,結果也是高電平,然而我們led是低電平,如果這時候來一個低電平與我們的上拉電平相與,結果爲低,就能點亮我們的led,蜂鳴器也是這樣,如果將他們的應該拉高的拉低了,led或者蜂鳴器將處於常亮或者蜂鳴器不響等等,還需要自己去探索!
main.c

#include "sys.h"
#include "delay.h"
#include "led.h"
#include "beep.h"
#include "key.h"
int main(void)
{
	int key=0;
	delay_init();
	ledinit();
	beepinit();
	keyinit();	
	while(1)
	{
		key=keyscan();
		if(key)
		{
			if(key==3)
			{
				           led1=!led1;
							led0=!led0;
							key=0;
			}
			else if(key==2)
			{
				led1=!led1;
				key=0;
			}
			else if(key==1)
			{
				beep=!beep;
				key=0;
			}
			delay_ms(10);
		}
	}	
} 

實驗很簡單,我講了我的真實經歷,希望能夠幫到大家!
問題
如果大家有好的處理方法,還請留個言!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章