PIC单片机常用模块与综合系统设计实例精讲
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

5.1 4×4扫描键盘设计实例

键盘是大家非常熟悉而且经常用到的部分,在大部分的单片机系统中都存在键盘,因为键盘是最实用、最简单的一种输入设备,是用于控制整个系统的主要工具。

5.1.1 实例说明

本节将详细介绍4×4扫描式键盘的电路设计和程序编写,通过本实例,读者将了解4×4扫描键盘的结构和工作原理;熟悉PIC单片机I/O口的应用方法;掌握键盘扫描程序的编写及其注意事项。

5.1.2 键盘知识介绍

4×4扫描键盘本身的电路结构如图5-1所示。这种键盘通常称为行列式键盘,由横竖两排线路组成,在每个行与列的交叉点有一个按键,当键盘按下时就将相互交叉的两条线路导通。其中电阻R1~R4是上拉电阻,JP5是连接键盘的插座。

图5-1 连接键盘部分的电路

键盘原理虽然看上去比较简单,但是在编程时仍需要注意以下两个问题。

(1)要能不断地扫描键盘并判断是否有键按下

判断的方法为:首先控制单片机向行或列的4个引脚输出高电平,然后再读取其余4个引脚的电平。如果此时其中一个键被按下则其对应的引脚应为高电平,否则为低电平。例如:在图5-2中,当向RB0~RB7引脚输出高电平时按下键1,那么引脚RB3(37)即与引脚RB4(36)导通,因为RB3(37)引脚输出了高电平,所以RB4(36)引脚也是高电平。

图5-2 RB4(36)引脚也是高电平

(2)要消除键盘抖动的问题

因为在实际应用中键盘上的电压有时会出现瞬间的电平波动而并非有键按下,所以在程序中需要使用一定的方法消除抖动的影响。

通常采用的消除抖动的方法是“判断延时再判断”的方法,即当检测到有某个按键按下时不是立刻断定此键已经按下,而是延时一段时间后再次判断此键是否处于按下状态,若是即认定此键已经按下,否则即认为是抖动现象而非键盘按下。这其中延时的时间是个重点,既不能太短也不能过长,延时时间太短起不到消除抖动的效果,而如果延时超过了键被按下的时间则不能判断出键被按下。具体的延时长短要根据实际情况确定。

5.1.3 硬件电路设计

4×4扫描键盘的电路原理图如图5-3所示。电路连接较简单,主要是单片机部分的复位和晶振电路。

图5-3 单片机部分的复位和晶振电路图

5.1.4 软件设计

1.程序流程介绍

程序流程图如图5-4所示,基本流程描述如下:

图5-4 程序流程图

首先初始化单片机,并将RB0~RB3口设置为输出,将RB4~RB7口设置为输入。然后开始执行扫描程序,轮流向RB0~RB3口输出高电平,并在每次输出后读取RB4~RB7口的值。对读取的值进行判断,若值为0,则表示没有键被按下,继续扫描;若某一位的值不为0,则在短暂延时后再次读取RB4~RB7口的值,若此时值变为0,则认为是抖动现象,继续进行扫描;若此时值仍然不为0,则根据值判断出是哪个按键被按下,并将结果发送,然后继续回到扫描程序。

2.程序代码与注释

相应程序代码与注释如下:

      /*********************************************
      example program for PIC download board
      16F877A @ 4MHz
      *********************************************/
      //#include  <pic.h>
      //#include  <pic1687x.h>
      #include "usart.h"
      void DELAY1(int time);
      unsigned char keyboard(unsigned char x);
      void main(void)
      {
          unsigned char  key,sendkey;
          init_comms();   // 初始化串口
          TRISB=0xf0;     //设置RB口的输入输出方向
          PORTB=0;        //清P2口
          while(1)
            {
            RB0=1;
            key=(PORTB&0xf0)>>4; //清低4位,只保留高4位的值,即保留RB4~RB7
            if(key!=0)
                  {
                      DELAY1(5);//延时125ms消抖
                      key=(PORTB&0xf0)>>4;
                      if(key!=0)
                      {
                          sendkey=keyboard(key);
                          putch(sendkey);
                                          }
                  }
            RB1=1;
      key=(PORTB&0xf0)>>4; //清低4位,只保留高4位的值,即保留RB4~RB7
                  if(key!=0)
                  {
                      DELAY1(5);//延时125ms消抖
                      key=(PORTB&0xf0)>>4;
                      if(key!=0)
                      {
                          sendkey=keyboard(key);
                          putch(sendkey+4);
                      }
                  }
            RB2=1;
            key=(PORTB&0xf0)>>4; //清低4位,只保留高4位的值,即保留RB4~RB7
                  if(key!=0)
                  {
                      DELAY1(5);//延时125ms消抖
                      key=(PORTB&0xf0)>>4;
                      if(key!=0)
                      {
                          sendkey=keyboard(key);
                          putch(sendkey+8);
                      }
                  }
            RB3=1;
            key=(PORTB&0xf0)>>4; //清低4位,只保留高4位的值,即保留RB4~RB7
                  if(key!=0)
                  {
                      DELAY1(5);//延时125ms消抖
                      key=(PORTB&0xf0)>>4;
                      if(key!=0)
                      {
                          sendkey=keyboard(key);
                          putch(sendkey+12);
                      }
                  }
            }
      }
      void DELAY1(int time)
      {
          int x,y;
          for(x=0;x<100;x++)
          {
            for(y=0;y<time;y++);
          }
      }
      unsigned char keyboard(unsigned char x)
      {
      unsigned char key;
      switch(x)
            {
                  case 1:
                          {   key=1;
                              break;
                          }
                      case 2:
                                  {   key=2;
                                      break;
                                  }
                      case 4:
                                  {   key=3;
                                      break;
                                  }
                      case 8:
                                  {
                                        key=4;
                                      break;
                                  }
                      default:    break;
      }
          return key;
      }

5.1.5 实例总结

键盘是单片机系统中经常使用的一个功能模块,本节详细介绍了最常用的4×4行列式键盘。读者通过本节的学习将掌握以下几个内容:

● 掌握行列式键盘的工作原理和电路设计方法。

● 熟悉软件编写的流程和需要注意的要点。

● 能根据具体情况和实际需要设计不同的键盘电路和软件。

在实际设计中还要特别注意如下几个要点:

● 键盘与单片机接口之间一定要添加合适的电阻,确保电路工作稳定。

● 编写键盘扫描程序要合理加入延时消抖程序,防止对键盘按下与否的误判断。

● 这种扫描键盘的方式适合程序不太复杂且系统空闲时间较多的情况,若系统较复杂且空闲时间较少,则可采用中断的方式。