找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机4*4矩阵键盘扫描做的表决器与计算器源码

[复制链接]
ID:290170 发表于 2018-9-12 20:06 | 显示全部楼层 |阅读模式
表决器是用1602液晶显示的,基于51单片机和矩阵按键,计算器是用数码管显示的

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

0.png

ppt课件:
0.jpg

表决器单片机源程序如下:
  1. /**********************BST-M51实验开发板例程************************
  2. *  平台:BST-M51 + Keil U4 + STC89C52
  3. *  名称:表决器
  4. *  公司:深圳市亚博软件开发有限公司     
  5. *  日期:2012-8-12
  6. *  晶振:11.0592MHZ
  7. ******************************************************************
  8. 程序功能:表决器,模拟三位评委的表决,并做出判断,将结果显示于1602上。
  9.                   共用到薄膜键盘上的“1,2,4,5,7,8,*”
  10.                   其中“*”为清零键,对1602进行清屏和对相关变量清零。
  11.                   每位评委操控两个按键,分别代表“通过”和“不通过”。
  12.                   第一位评委控制“1”(通过)与“2”(不通过);
  13.                   第二位评委控制“3”(通过)与“4”(不通过);
  14.                   第三位评委控制“5”(通过)与“6”(不通过);
  15.                   当按“通过”次数多于“不通过”时,1602将显示“yes”,否则显示“no”。
  16.                   在一个回合中,每位评委只有一次按键的权利,一旦按下,其操控的两个
  17.                   按键均将被封锁,再按也不会有任何作用。除非按下清零键“*”清零后开始下一回合。
  18. ************************************************************************************/

  19. #include<reg52.h>
  20. #define uchar unsigned char
  21. #define uint unsigned int
  22. sbit rs=P1^0;
  23. sbit rw=P1^1;
  24. sbit beep=P2^3;
  25. sbit lcden=P2^5;

  26. bit ok1,ok2,ok3,clear;

  27. uchar pass,nopass,temp;
  28. uchar table[]="yes";
  29. uchar table1[]="no";
  30. uchar table2[]="agree";
  31. uchar table3[]="disagree";
  32. uchar table4[]="   ";
  33. uchar table5[]="  ";

  34. void delay(uint z)
  35. {
  36.         uint x,y;
  37.         for(x=z;x>0;x--)
  38.                 for(y=110;y>0;y--);
  39. }



  40. void write_com(uchar com)
  41. {
  42.         rs=0;
  43.         lcden=0;
  44.         P0=com;
  45.         delay(5);
  46.         lcden=1;
  47.         delay(5);
  48.         lcden=0;       
  49. }

  50. void write_date(uchar date)
  51. {
  52.         rs=1;
  53.         lcden=0;
  54.         P0=date;
  55.         delay(5);
  56.         lcden=1;
  57.         delay(5);
  58.         lcden=0;       
  59. }



  60. void init()
  61. {      
  62.     rw=0;
  63.         write_com(0x38);
  64.         delay(20);
  65.         write_com(0x0c);
  66.         delay(20);
  67.         write_com(0x06);
  68.         delay(20);
  69.         write_com(0x01);
  70.         delay(20);
  71.                
  72. }

  73. void yes()
  74. {
  75.         uchar a;
  76.         write_com(0x80+12);
  77.         delay(20);
  78.         for(a=0;a<3;a++)
  79.         {
  80.                 write_date(table[a]);
  81.                 delay(20);
  82.         }
  83. }

  84. void no()
  85. {
  86.         uchar a;
  87.         write_com(0x80+0x40+12);
  88.         delay(20);
  89.         for(a=0;a<2;a++)
  90.         {
  91.                 write_date(table1[a]);
  92.                 delay(20);
  93.         }
  94. }

  95. void agree()
  96. {
  97.         uchar a;
  98.         write_com(0x80);
  99.         delay(20);
  100.         for(a=0;a<5;a++)
  101.         {
  102.                 write_date(table2[a]);
  103.                 delay(20);
  104.         }
  105. }

  106. void disagree()
  107. {
  108.         uchar a;
  109.         write_com(0x80+0x40);
  110.         delay(20);
  111.         for(a=0;a<8;a++)
  112.         {
  113.                 write_date(table3[a]);
  114.                 delay(20);
  115.         }
  116. }

  117. void keyscan()
  118. {
  119.     if(!ok1)
  120.         {
  121.         P3=0xfe;
  122.     temp=P3;
  123.     temp=temp&0xf0;
  124.     if(temp!=0xf0)
  125.     {
  126.       delay(10);
  127.       if(temp!=0xf0)
  128.       {
  129.         temp=P3;
  130.                 switch(temp)
  131.         {
  132.           case 0xee:          //1110 1110 "1"被按下
  133.                pass++;
  134.                            ok1=1;                //一号评委已判决。
  135.                break;

  136.           case 0xde:          //1101 1110  "2"被按下
  137.                nopass++;
  138.                            ok1=1;
  139.                break;
  140.          }
  141.          while(temp!=0xf0)
  142.          {
  143.            temp=P3;
  144.            temp=temp&0xf0;
  145.            beep=0;
  146.          }
  147.          beep=1;
  148.       }
  149.     }
  150.         }
  151.         if(!ok2)
  152.         {
  153.     P3=0xfd;
  154.     temp=P3;
  155.     temp=temp&0xf0;
  156.     if(temp!=0xf0)
  157.     {
  158.       delay(10);
  159.       if(temp!=0xf0)
  160.       {
  161.         temp=P3;
  162.         switch(temp)
  163.         {
  164.           case 0xed:  //1110 1101 "4"被按下
  165.                pass++;
  166.                            ok2=1;
  167.                break;

  168.           case 0xdd:        //1101 1101  "5"被按下
  169.                nopass++;
  170.                            ok2=1;
  171.                break;
  172.          }
  173.          while(temp!=0xf0)
  174.          {
  175.            temp=P3;
  176.            temp=temp&0xf0;
  177.            beep=0;
  178.          }
  179.          beep=1;
  180.       }
  181.       }
  182.           }
  183.         if(!ok3)
  184.         {
  185.     P3=0xfb;
  186.     temp=P3;
  187.     temp=temp&0xf0;
  188.     if(temp!=0xf0)
  189.     {
  190.       delay(10);
  191.       if(temp!=0xf0)
  192.       {
  193.         temp=P3;
  194.         switch(temp)
  195.         {
  196.           case 0xeb:   //1110 1011 "7"被按下
  197.                pass++;
  198.                            ok3=1;
  199.                break;

  200.           case 0xdb:        //1101 1011  "8"被按下
  201.                nopass++;
  202.                            ok3=1;
  203.                break;
  204.          }
  205.          while(temp!=0xf0)
  206.          {
  207.            temp=P3;
  208.            temp=temp&0xf0;
  209.            beep=0;
  210.          }
  211.          beep=1;
  212.       }
  213.       }
  214.           }
  215.               P3=0xf7;
  216.     temp=P3;
  217.     temp=temp&0xf0;
  218.     if(temp!=0xf0)
  219.     {
  220.       delay(10);
  221.       if(temp!=0xf0)
  222.       {
  223.         temp=P3;
  224.         switch(temp)
  225.         {
  226.           case 0xe7:   //1110 0111 "*"被按下
  227.                clear=1;
  228.                break;
  229.          
  230.          }
  231.          while(temp!=0xf0)
  232.          {
  233.            temp=P3;
  234.            temp=temp&0xf0;
  235.            beep=0;
  236.          }
  237.          beep=1;
  238.       }
  239.     }
  240. }

  241. void main()
  242. {
  243.         uchar a,b;
  244.         init();
  245.         while(1)
  246.         {       
  247.                 agree();
  248.                 disagree();
  249.                 keyscan();
  250.                 if(pass||nopass)
  251.                 {
  252.                         write_com(0x80+10);
  253.                         delay(20);
  254.                         write_date(0x30+pass);
  255.                         write_com(0x80+0x40+10);
  256.                         delay(20);
  257.                         write_date(0x30+nopass);
  258.                 }
  259.                 a=pass+nopass;
  260.                 if(a==3)
  261.                 {
  262.                         if(pass>nopass)
  263.                         yes();
  264.                         if(pass<nopass)
  265.                         no();
  266.                 }
  267.                 if(clear)
  268.                 {
  269.                         ok1=0;        ok2=0;        ok3=0;       
  270.                         pass=0;        nopass=0;        clear=0;        a=0;
  271.                         agree();
  272.                         disagree();
  273.                         write_com(0x80+10);
  274.                         delay(20);
  275.                         write_date(0x30+pass);
  276.                         write_com(0x80+0x40+10);
  277.                         delay(20);
  278.                         write_date(0x30+nopass);
  279.        
  280.                         write_com(0x80+12);
  281.                         for(b=0;b<3;b++)
  282.                         {
  283.                                 write_date(table4[b]);
  284.                                 delay(20);
  285.                         }
  286.                         write_com(0x80+0x40+12);
  287.                         for(b=0;b<2;b++)
  288.                         {
  289.                                 write_date(table5[b]);
  290.                                 delay(20);
  291.                         }
  292.                 }           
  293.         }
  294. }
复制代码


单片机源程序如下:
  1. /**********************BST-M51实验开发板例程**************
  2. *  平台:BST-M51 + Keil U4 + STC89C52
  3. *  名称:矩阵键盘扫描 数码管显示
  4. *  公司:深圳市亚博软件开发有限公司      
  5. *  日期:2015-7
  6. *  晶振:11.0592MHZ
  7. *实验效果        :按4*4矩阵按键,数码管4位依次显示1,2,3,A,
  8.                                                                                           4,5,6,B,
  9.                                                                                           7,8,9,C,
  10.                                                                                           E,0,F,D
  11. *********************************************************/
  12. #include<reg52.h>
  13. #define uchar  unsigned char
  14. #define uint  unsigned int
  15. uchar code table[17]={0x3f , 0x06 , 0x5b ,0x4f , 0x66 , 0x6d ,0x7d ,
  16.                    0x07 , 0x7f , 0x6f ,0x77 , 0x7c , 0x39 ,
  17.                    0x5e , 0x79 , 0x71 , 0x00};         //0-9&A-F&“不显示” 字型码

  18. void delay(uint xms)        //延迟xms
  19. {
  20.     uint i,j;
  21.         for(i=xms;i>0;i--)
  22.           for(j=112;j>0;j--);
  23. }

  24. void display(uchar num)           //数码管显示函数
  25. {
  26.     P0=table[num];                 //段选
  27. }

  28. void keyscan4x4()
  29. {
  30.     uchar temp,key;


  31.         ///////////////第一行扫描///////////////////
  32.         P3=0xfe;//1111 1110 让P3.0口输出低
  33.         temp=P3;
  34.         temp=temp&0xf0;//1111 0000        位与操作 屏蔽后四位
  35.         if(temp!=0xf0)
  36.         {
  37.             delay(10);
  38.                 temp=P3;
  39.                 temp=temp&0xf0;
  40.                 if(temp!=0xf0)
  41.                 {
  42.                     temp=P3;
  43.                         switch(temp)
  44.                         {
  45.                           case 0xee:           //1110 1110 "1"被按下
  46.                                key=1;
  47.                                    break;
  48.                           case 0xde:                  //1101 1110  "2"被按下
  49.                                    key=2;
  50.                                    break;
  51.                           case 0xbe:                  //1011 1110  "3"被按下
  52.                                    key=3;
  53.                                    break;
  54.                           case 0x7e:                  //0111 1110  "A"被按下
  55.                                    key=10;
  56.                                    break;
  57.                         }
  58.                         while(temp!=0xf0)
  59.                         {
  60.                             temp=P3;
  61.                                 temp=temp&0xf0;
  62.                         }
  63.                         display(key);
  64.                 }
  65.         }
  66.                         ///////////////第二行扫描///////////////////
  67.         P3=0xfd;//1111 1101 让P3.1口输出低
  68.         temp=P3;
  69.         temp=temp&0xf0;//1111 0000        位与操作 屏蔽后四位
  70.         if(temp!=0xf0)
  71.         {
  72.             delay(10);
  73.                 temp=P3;
  74.                 temp=temp&0xf0;
  75.                 if(temp!=0xf0)
  76.                 {
  77.                     temp=P3;
  78.                         switch(temp)
  79.                         {
  80.                           case 0xed:           //1110 1101 "4"被按下
  81.                                key=4;
  82.                                    break;
  83.                           case 0xdd:                  //1101 1101  "5"被按下
  84.                                    key=5;
  85.                                    break;
  86.                           case 0xbd:                  //1011 1101  "6"被按下
  87.                                    key=6;
  88.                                    break;
  89.                           case 0x7d:                  //0111 1101  "B"被按下
  90.                                    key=11;
  91.                                    break;
  92.                         }
  93.                         while(temp!=0xf0)
  94.                         {
  95.                             temp=P3;
  96.                                 temp=temp&0xf0;
  97.                         }
  98.                         display(key);
  99.                 }
  100.          }
  101.                         ///////////////第三行扫描///////////////////
  102.         P3=0xfb;//1111 1011 让P3.2口输出低
  103.         temp=P3;
  104.         temp=temp&0xf0;//1111 0000        位与操作 屏蔽后四位
  105.         if(temp!=0xf0)
  106.         {
  107.             delay(10);
  108.                 temp=P3;
  109.                 temp=temp&0xf0;
  110.                 if(temp!=0xf0)
  111.                 {
  112.                     temp=P3;
  113.                         switch(temp)
  114.                         {
  115.                           case 0xeb:           //1110 1011 "7"被按下
  116.                                key=7;
  117.                                    break;
  118.                           case 0xdb:                  //1101 1011  "8"被按下
  119.                                    key=8;
  120.                                    break;
  121.                           case 0xbb:                  //1011 1011  "9"被按下
  122.                                    key=9;
  123.                                    break;
  124.                           case 0x7b:                  //0111 1011  "C"被按下
  125.                                    key=12;
  126.                                    break;
  127.                         }
  128.                         while(temp!=0xf0)
  129.                         {
  130.                             temp=P3;
  131.                                 temp=temp&0xf0;
  132.                         }
  133.                         display(key);
  134.                   }
  135.                 }

  136.                         ///////////////第四行扫描///////////////////
  137.         P3=0xf7;//1111 0111 让P3.0口输出低
  138.         temp=P3;
  139.         temp=temp&0xf0;//1111 0000        位与操作 屏蔽后四位
  140.         if(temp!=0xf0)
  141.         {
  142.             delay(10);
  143.                 temp=P3;
  144.                 temp=temp&0xf0;
  145.                 if(temp!=0xf0)
  146.                 {
  147.                     temp=P3;
  148.                         switch(temp)
  149.                         {
  150.                           case 0xe7:           //1110 0111 "*"被按下
  151.                                key=14;
  152.                                    break;
  153.                           case 0xd7:                  //1101 0111  "0"被按下
  154.                                    key=0;
  155.                                    break;
  156.                           case 0xb7:                  //1011 0111  "#"被按下
  157.                                    key=15;
  158.                                    break;
  159.                           case 0x77:                  //0111 0111  "D"被按下
  160.                                    key=13;
  161.                                    break;
  162.                         }
  163.                         while(temp!=0xf0)
  164.                         {
  165.                             temp=P3;
  166.                                 temp=temp&0xf0;
  167.                         }
  168.                         display(key);

  169.                  }
  170.          }

  171. }

  172. void main()
  173. {
  174.         P2 = P2 | 0xf0;                 //位选 锁存为4位同时显示
  175.         while(1)
  176.         {
  177.            keyscan4x4();
  178.         }
  179. }
复制代码

所有资料51hei提供下载:
矩阵键盘扫描.zip (4.68 MB, 下载次数: 29)
回复

使用道具 举报

ID:1 发表于 2018-9-13 00:46 | 显示全部楼层
补全原理图或者详细说明一下电路连接即可获得100+黑币
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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