按键识别(基于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);
		}
	}	
} 

实验很简单,我讲了我的真实经历,希望能够帮到大家!
问题
如果大家有好的处理方法,还请留个言!

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