立即注册 找回密码

微雪课堂

搜索
微雪课堂 外围模块 Accessory Shield 查看内容

Accessory Shield学习1:五向摇杆

2015-5-6 15:00| 发布者: yanwl| 查看: 4593| 评论: 0

摘要: 现在,我们开始步入按键程序设计的殿堂,在基于Arduino为核心构成的应用系统中,用户输入是必不可少的部分,输入可以由多种方式,这里我们来讲一下最高(chao)大(jian)上(dan)的按键。 这是个有5个方向的操纵杆,包括 ...
现在,我们开始步入按键程序设计的殿堂,在基于Arduino为核心构成的应用系统中,用户输入是必不可少的部分,输入可以由多种方式,这里我们来讲一下最高(chao)大(jian)上(dan)的按键。

原理大放送:
这是个有5个方向的操纵杆,包括上、下、左、右以及确定(就是往下按),每个按键分别与Arduino的引脚连接,原理图如下,其中AR_A1 -- AR_A5分别于Arduino的A1 -- A5相连。

由于Arduino的主控器内部有上拉电阻,所以我们原理图就没加;什么?你不知道上拉电阻时干什么的?上拉就是将不确定的信号通过一个电阻钳位在高电平,电阻同时起限流作用。下拉同理。也是将不确定的信号通过一个电阻钳位在低电平。为方便描述按键的检测原理,我们简化一下原理图如下:

简单分析一下按键检测原理,当按键没有按下的时候,单片机的引脚通过上拉电阻R接到VCC,程序在读取这个引脚的电平时值为1(高电平);当按键按下时,该引脚被短接到GND,此时程序读这个引脚的电平时值为0(低电平);因此,按键是否按下可以通过对应引脚的高低电平来反应,我们只要再程序中判断引脚的电平状态就可以识别按键是否按下,从而做出相应的处理;

一切看起来很美好,但现实并非理想状态!

我们在得出上述结论的时候其实忽略了一个重要的问题,那就是现实中按键按下时电压的变化状态不是理想的如下图:

二现实往往是残酷的,由于按键的弹片接触时,并不是一接触就紧紧的闭合,它还存在一定的抖动,尽管这个时间非常的短暂,但是对于执行速度以us为计算单位的微控制器来说就比较漫长了,实际的按键波形是下面这样的:

这样便存在这样一个问题,由于抖动的存在,程序会认为多次按下了按键,这并不是我们所需要的。解决办法就是软件延时消抖,由于抖动的时间大概维持20ms以内,只要软件第一次检测到按键按下时,延时20ms,避开这个抖动区间就可以了;


示例代码:

/*
I/O define
*/
#define    KEY_UP        A1
#define    KEY_DOWN      A5
#define    KEY_LEFT      A3
#define    KEY_RIGHT     A2
#define    KEY_ENTER     A4

int key_release_flag = 1, i; 
int time_ticks = 0;

void setup(void)
{
  pinMode(13, OUTPUT);
  
  pinMode(KEY_UP, INPUT);
  digitalWrite(KEY_UP, HIGH);
  pinMode(KEY_DOWN, INPUT);
  digitalWrite(KEY_DOWN, HIGH);
  pinMode(KEY_LEFT, INPUT);
  digitalWrite(KEY_LEFT, HIGH);
  pinMode(KEY_RIGHT, INPUT);
  digitalWrite(KEY_RIGHT, HIGH);
  pinMode(KEY_ENTER, INPUT);
  digitalWrite(KEY_ENTER, HIGH);
 
  Serial.begin(9600);
}

void loop(void)
{
  /*
  led flash
  */
  delay(1);
  time_ticks++;  
  if(time_ticks == 500)
  {
    digitalWrite(13, HIGH);
  }
  else if(time_ticks == 1000)
  {
    digitalWrite(13, LOW);
    time_ticks = 0;
  }
  
  /*
  keyboard scan
  */
  if((digitalRead(KEY_UP) == LOW) || (digitalRead(KEY_DOWN) == LOW) || (digitalRead(KEY_LEFT) == LOW) || (digitalRead(KEY_RIGHT) == LOW) || (digitalRead(KEY_ENTER) == LOW))
  {
    if(key_release_flag)
    {
      delay(10);
      
      if((digitalRead(KEY_UP) == LOW) || (digitalRead(KEY_DOWN) == LOW) || (digitalRead(KEY_LEFT) == LOW) || (digitalRead(KEY_RIGHT) == LOW) || (digitalRead(KEY_ENTER) == LOW))
      {
        key_release_flag = 0;
        if(digitalRead(KEY_UP) == LOW)
          Serial.print("you press UP\n");
        else if(digitalRead(KEY_DOWN) == LOW)
          Serial.print("you press DOWN\n");
        else if(digitalRead(KEY_LEFT) == LOW)
          Serial.print("you press LEFT\n");
        else if(digitalRead(KEY_RIGHT) == LOW)
          Serial.print("you press RIGHT\n");
        else if(digitalRead(KEY_ENTER) == LOW)
          Serial.print("you press ENTER\n");
      }
    }
  }
  else
    key_release_flag = 1;
}


程序运行时板载的LED会以1秒为周期闪烁,提示系统正常工作;当按下任意一个按键时,串口监视器会显示当前按下的键位,例如“you press UP”。现象如下图:


源代码下载:

joysticks.zip


165

顶一下

刚表态过的朋友 (165 人)

相关阅读

最新评论

微雪官网|产品资料|手机版|小黑屋|微雪课堂. ( 粤ICP备05067009号 )

GMT+8, 2024-4-19 18:58 , Processed in 0.020179 second(s), 21 queries .

返回顶部