当前位置:   article > 正文

51单片机之矩阵键盘_单片机矩阵按键代码

单片机矩阵按键代码

      独立键盘与单片机连接时,每一个按键都需要单片机的一个I/O口若某单片机系统需较多按键,如果用独立按键便会占用过多的I/O口资源。单片机系统中I/O口资源往往比较宝贵,当用到多个按键时为了节省I/O口口线,我们引入矩阵键盘。

      我们以4X4矩阵键盘为例讲解其工作原理和检测方法。将16个按键排成4行4列,第一行将每个按键的一端连接在一起构成行线,第一列将每个按键的另一端连接在一起构成列线,这样便一共有4行4列共8根线,我们将这8根线连接到单片机的8个I/O口上,通过程序扫描键盘就可检测16个键。用这种方法我们也可实现3行3列9个键、5行5列25个键、6行6列36个键等。

     无论是独立键盘还是矩阵键盘,单片机检测其是否被按下的依据都是一样的,也就是检测与该键对应的I/O口是否为低电平。独立键盘有一端固定为低电平,单片机写程序检测时比较方便。而矩阵键盘两端都与单片机I/O口相连,因此在检测时需人为通过单片机I/O口送出低电平。检测时,先送一列为低电平,其余几列全为高电平(此时我们确定了列数),然后立即轮流检测一次各行是否有低电平,若检测到某一行为低电平(这时我们又确定了行数),则我们便可确认当前被按下的键是哪一行哪一列的,用同样方法轮流送各列一次低电平,再轮流检测一次各行是否变为低电平,这样即可检测完所有的按键,当有键被按下时便可判断出按下的键是哪一个键。当然我们也可以将行线置低电平,扫描列是否有低电平。这就是矩阵键盘检测的原理和方法。

    首先看一下电路图

    

      上图是一个4X4 的矩阵键盘,一共是16 个按键。我们照习惯称横为“行”,“竖”为列。那么5、6、7、8 我们称之为“行线”,则1、2、3、4 称为“列线”。要正确记住各个行列线各自对应的IO。注意看,每一个按键的两端,都分别接在某一个列线和行线上,即:“行线和列线是通过某个按键的按下和抬起实现联通和断开的”,和“导线两端上的信号是经过“与”的关系再体现到导线上的。”这两句话便构成了矩阵键盘扫描的全部。要理解好,理解不了就背下来。

现在详细讲述一下矩阵键盘扫描的原理和步骤:

    

矩阵键盘扫描原理
方法一:
             逐行扫描:我们可以通过高四位轮流输出低电平来对矩阵键盘进行逐行扫描,当低四位接收到的数据不全为1的时候,说明有按键按下,然后通过接收到的数据是哪一位为0来判断是哪一个按键被按下。
方法二:
             行列扫描:我们可以通过高四位全部输出低电平,低四位输出高电平。当接收到的数据,低四位不全为高电平时,说明有按键按下,然后通过接收的数据值,判断是哪一列有按键按下,然后再反过来,高四位输出高电平,低四位输出低电平,然后根据接收到的高四位的值判断是那一行有按键按下,这样就能够确定是哪一个按键按下了。
 

   接下来举一个矩阵键盘的程序例子,该例子使用了P0、P1两组IO口,P1用来检测矩阵键盘中是否有按键按下,P0用来驱动静态数码管的显示。

   以下是示例程序:

 

  1. #include "reg52.h"
  2. typedef unsigned char u8;
  3. typedef unsigned int u16;
  4. #define GPIO_DIG P0
  5. #define GPIO_KEY P1
  6. u8 code smgduan[16]= {0x3f, 0x06, 0x5b, 0x4f,
  7. 0x66, 0x6d, 0x7d, 0x07,
  8. 0x7f, 0x6f, 0x77, 0x7c,
  9. 0x39, 0x5e, 0x79, 0x71};//静态数码管码值
  10. u8 KeyColValue;
  11. u8 KeyLineValue;
  12. void delay(u16 i) //延时函数
  13. {
  14. while(i --);
  15. }
  16. void KeyDown() //键盘按键扫描函数
  17. {
  18. char a;
  19. GPIO_KEY = 0x0f;
  20. if(GPIO_KEY != 0x0f)//检测4行中哪一行按键是否按下
  21. {
  22. delay(1000); //延时消抖
  23. if(GPIO_KEY != 0x0f) //再次检测4行中哪一行按键是否按下
  24. {
  25. switch(GPIO_KEY) //根据IO的值来确定哪一行按键按下
  26. {
  27. case(0x07): KeyColValue = 0; break;
  28. case(0x0b): KeyColValue = 1; break;
  29. case(0x0d): KeyColValue = 2; break;
  30. case(0x0e): KeyColValue = 3; break;
  31. }
  32. }
  33. }
  34. GPIO_KEY = 0xf0;
  35. if(GPIO_KEY != 0xf0) //检测4行中哪一列按键是否按下
  36. {
  37. delay(1000); //延时消抖
  38. if(GPIO_KEY != 0xf0) //再次检测4行中哪一列按键是否按下
  39. {
  40. switch(GPIO_KEY) //根据IO的值来确定哪一列按键按下
  41. {
  42. case(0x70): KeyLineValue = 0; break;
  43. case(0xb0): KeyLineValue = 1; break;
  44. case(0xd0): KeyLineValue = 2; break;
  45. case(0xe0): KeyLineValue = 3; break;
  46. }
  47. }
  48. while((a < 50) && (GPIO_KEY != 0xf0)) //延时,确保没有按键再按下
  49. {
  50. delay(1000);
  51. a ++;
  52. }
  53. }
  54. }
  55. void main()
  56. {
  57. while(1)
  58. {
  59. KeyDown();//检测按键是否按下
  60. GPIO_DIG = ~smgduan[KeyLineValue*4 + KeyColValue];//根据按键的行列值,静态数码管显示相应的值
  61. }
  62. }

     

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/408731
推荐阅读
相关标签
  

闽ICP备14008679号