现在,我们开始步入按键程序设计的殿堂,在基于Arduino为核心构成的应用系统中,用户输入是必不可少的部分,输入可以由多种方式,这里我们来讲一下最高(chao)大(jian)上(dan)的按键。
原理大放送:
这是个有5个方向的操纵杆,包括上、下、左、右以及确定(就是往下按),每个按键分别与Arduino的引脚连接,原理图如下,其中AR_A1 -- AR_A5分别于Arduino的A1 -- A5相连。 由于Arduino的主控器内部有上拉电阻,所以我们原理图就没加;什么?你不知道上拉电阻时干什么的?上拉就是将不确定的信号通过一个电阻钳位在高电平,电阻同时起限流作用。下拉同理。也是将不确定的信号通过一个电阻钳位在低电平。为方便描述按键的检测原理,我们简化一下原理图如下:
简单分析一下按键检测原理,当按键没有按下的时候,单片机的引脚通过上拉电阻R接到VCC,程序在读取这个引脚的电平时值为1(高电平);当按键按下时,该引脚被短接到GND,此时程序读这个引脚的电平时值为0(低电平);因此,按键是否按下可以通过对应引脚的高低电平来反应,我们只要再程序中判断引脚的电平状态就可以识别按键是否按下,从而做出相应的处理; 一切看起来很美好,但现实并非理想状态! 我们在得出上述结论的时候其实忽略了一个重要的问题,那就是现实中按键按下时电压的变化状态不是理想的如下图: 二现实往往是残酷的,由于按键的弹片接触时,并不是一接触就紧紧的闭合,它还存在一定的抖动,尽管这个时间非常的短暂,但是对于执行速度以us为计算单位的微控制器来说就比较漫长了,实际的按键波形是下面这样的: 这样便存在这样一个问题,由于抖动的存在,程序会认为多次按下了按键,这并不是我们所需要的。解决办法就是软件延时消抖,由于抖动的时间大概维持20ms以内,只要软件第一次检测到按键按下时,延时20ms,避开这个抖动区间就可以了;
示例代码:
10 | int key_release_flag = 1, i; |
17 | pinMode(KEY_UP, INPUT); |
18 | digitalWrite(KEY_UP, HIGH); |
19 | pinMode(KEY_DOWN, INPUT); |
20 | digitalWrite(KEY_DOWN, HIGH); |
21 | pinMode(KEY_LEFT, INPUT); |
22 | digitalWrite(KEY_LEFT, HIGH); |
23 | pinMode(KEY_RIGHT, INPUT); |
24 | digitalWrite(KEY_RIGHT, HIGH); |
25 | pinMode(KEY_ENTER, INPUT); |
26 | digitalWrite(KEY_ENTER, HIGH); |
40 | digitalWrite(13, HIGH); |
42 | else if(time_ticks == 1000) |
44 | digitalWrite(13, LOW); |
51 | if((digitalRead(KEY_UP) == LOW) || (digitalRead(KEY_DOWN) == LOW) || (digitalRead(KEY_LEFT) == LOW) || (digitalRead(KEY_RIGHT) == LOW) || (digitalRead(KEY_ENTER) == LOW)) |
57 | if((digitalRead(KEY_UP) == LOW) || (digitalRead(KEY_DOWN) == LOW) || (digitalRead(KEY_LEFT) == LOW) || (digitalRead(KEY_RIGHT) == LOW) || (digitalRead(KEY_ENTER) == LOW)) |
60 | if(digitalRead(KEY_UP) == LOW) |
61 | Serial.print("you press UPn"); |
62 | else if(digitalRead(KEY_DOWN) == LOW) |
63 | Serial.print("you press DOWNn"); |
64 | else if(digitalRead(KEY_LEFT) == LOW) |
65 | Serial.print("you press LEFTn"); |
66 | else if(digitalRead(KEY_RIGHT) == LOW) |
67 | Serial.print("you press RIGHTn"); |
68 | else if(digitalRead(KEY_ENTER) == LOW) |
69 | Serial.print("you press ENTERn"); |
程序运行时板载的LED会以1秒为周期闪烁,提示系统正常工作;当按下任意一个按键时,串口监视器会显示当前按下的键位,例如“you press UP”。现象如下图:
|