找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1981|回复: 1
收起左侧

51单片机4行6列矩阵按键源代码(注释很全)

[复制链接]
ID:492417 发表于 2019-3-17 10:52 | 显示全部楼层 |阅读模式
这是一个4行6列矩阵按键原代码


  1. #include <reg52.h>
  2. sbit KEY_IN_0 = P1^0;
  3. sbit KEY_IN_1 = P1^1;
  4. sbit KEY_IN_2 = P1^2;
  5. sbit KEY_IN_3 = P1^3;
  6. sbit KEY_IN_4 = P1^4;
  7. sbit KEY_IN_5 = P1^5;
  8. sbit KEY_OUT_1 = P3^0;
  9. sbit KEY_OUT_2 = P3^1;
  10. sbit KEY_OUT_3 = P3^2;
  11. sbit KEY_OUT_4 = P3^6;


  12. unsigned char code KeyCodeMap[4][6] = { //矩阵按键编号到标准键盘键码的映射表
  13. { 0x1B,'1', '2', '3', 0x2A, 0x27 }, //ESC 键、数字键 1、数字键 2、数字键 3、向上键
  14. { 0x1A,'4', '5', '6', 0x2B, 0x26 }, //开关屏、数字键 4、数字键 5、数字键 6、向左键
  15. { 0x1C,'7', '8', '9', 0x2D, 0x25 }, //电机开、数字键 7、数字键 8、数字键 9、向下键
  16. { 0x1D,0X06,'0',0x2F, 0x0D, 0x28 }  //功能键、DEL 键、  数字键 0、回车键、  向右键
  17. };


  18. unsigned char pdata KeySta[4][6] = { //全部矩阵按键的当前状态
  19. {1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1}
  20. };


  21. extern void KeyAction(unsigned char keycode);



  22. /* 按键驱动函数,检测按键动作,调度相应动作函数,需在主循环中调用 */
  23. void KeyDriver()
  24. {
  25.    unsigned char i, j;
  26.    static unsigned char pdata backup[4][6] = { //按键值备份,保存前一次的值
  27.    {1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1}, {1, 1, 1, 1, 1, 1}
  28.    };
  29.    for (i=0; i<4; i++) //循环检测 4*4 的矩阵按键
  30.    {
  31.       for (j=0; j<6; j++)
  32.       {
  33.          if (backup[i][j] != KeySta[i][j]) //检测按键动作
  34.          {
  35.             if (backup[i][j] != 0) //按键按下时执行动作
  36.             {
  37.                 KeyAction(KeyCodeMap[i][j]); //调用按键动作函数
  38.             }
  39.             backup[i][j] = KeySta[i][j]; //刷新前一次的备份值
  40.          }
  41.       }
  42.    }
  43. }



  44. /* 按键扫描函数,需在定时中断中调用,推荐调用间隔 1ms */
  45. void KeyScan()
  46. {
  47.    unsigned char i;
  48.    static unsigned char keyout = 0; //矩阵按键扫描输出索引
  49.    static unsigned char keybuf[4][6] = { //矩阵按键扫描缓冲区
  50.    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
  51.    {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
  52.    };
  53. //将一行的 4 个按键值移入缓冲区
  54.    keybuf[keyout][0] = (keybuf[keyout][0] << 1) | KEY_IN_0;
  55.    keybuf[keyout][1] = (keybuf[keyout][1] << 1) | KEY_IN_1;
  56.    keybuf[keyout][2] = (keybuf[keyout][2] << 1) | KEY_IN_2;
  57.    keybuf[keyout][3] = (keybuf[keyout][3] << 1) | KEY_IN_3;
  58.    keybuf[keyout][4] = (keybuf[keyout][4] << 1) | KEY_IN_4;
  59.    keybuf[keyout][5] = (keybuf[keyout][5] << 1) | KEY_IN_5;
  60. //消抖后更新按键状态
  61.    for (i=0; i<6; i++) //每行 4 个按键,所以循环 4 次
  62.    {
  63.       if ((keybuf[keyout][i] & 0x0F) == 0x00)
  64.       { //连续 4 次扫描值为 0,即 4*4ms 内都是按下状态时,可认为按键已稳定的按下
  65.          KeySta[keyout][i] = 0;
  66.       }
  67.       else if ((keybuf[keyout][i] & 0x0F) == 0x0F)
  68.       { //连续 4 次扫描值为 1,即 4*4ms 内都是弹起状态时,可认为按键已稳定的弹起
  69.          KeySta[keyout][i] = 1;
  70.       }
  71.    }
  72. //执行下一次的扫描输出
  73.     keyout++; //输出索引递增
  74.     keyout &= 0x03; //索引值加到 4 即归零
  75.     switch (keyout) //根据索引,释放当前输出引脚,拉低下次的输出引脚
  76.     {
  77.         case 0: KEY_OUT_4 = 1; KEY_OUT_1 = 0; break;
  78.         case 1: KEY_OUT_1 = 1; KEY_OUT_2 = 0; break;
  79.         case 2: KEY_OUT_2 = 1; KEY_OUT_3 = 0; break;
  80.         case 3: KEY_OUT_3 = 1; KEY_OUT_4 = 0; break;
  81.         default: break;
  82.     }
  83. }
复制代码


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:328014 发表于 2019-3-20 19:45 | 显示全部楼层
楼主能分享下原理图吗?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表