找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4450|回复: 19
收起左侧

求大神指导我需要一个能做到30个按键扫描的键盘用51单片机

[复制链接]
回帖奖励 60 黑币 回复本帖可获得 20 黑币奖励! 每人限 1 次
ID:696382 发表于 2020-5-29 11:33 | 显示全部楼层 |阅读模式
需要用lcd液晶显示来显示按键扫描里哪里没有被按下希望得到大神指点
回复

使用道具 举报

ID:401564 发表于 2020-5-29 15:16 | 显示全部楼层
使用ADC端口加分压电阻,三四个端口就可以有30个按键了,自己参考一下 51hei截图20200529151533.jpg
回复

使用道具 举报

ID:332444 发表于 2020-5-29 19:22 | 显示全部楼层
除了按下的就是都没按下!
回复

使用道具 举报

ID:420836 发表于 2020-5-29 22:53 | 显示全部楼层
可以使用IO扩展电路,或IO和电阻矩阵电路来创建大键盘。
回复

使用道具 举报

ID:213173 发表于 2020-5-29 23:29 | 显示全部楼层
给你写一个5*6矩阵键盘数码管动态显示示例参考,端口可以按实际需要自行更改,再把数码管显示改为LCD显示。
无标题.jpg

  1. //P1.0~1.5接行线,P1.6~1.7、P2.0~2.2接列线
  2. //数码管显示键值
  3. #include<reg51.h>
  4. #define uint unsigned int
  5. #define uchar unsigned char
  6. #define PD (P2&0x07)<<8|P1 //宏定义5*6矩阵端口
  7. sbit wela1=P2^6;//数码管十位
  8. sbit wela2=P2^7;//数码管个位
  9. uchar code table[]={//共阴数码管段码"0~f"
  10.                 0x3f,0x06,0x5b,0x4f,
  11.                 0x66,0x6d,0x7d,0x07,
  12.                 0x7f,0x6f,0x77,0x7c,
  13.                 0x39,0x5e,0x79,0x71};
  14. uint key=0;                                                        //键值变量
  15. uchar ge,shi;
  16. bit flag;

  17. void PX(uint i)                                        //写入16位数据
  18. {   
  19.         P1=i;
  20.         P2&=0xf8;//清0 P2低3位不影响高5位状态
  21.         P2|=i>>8;//
  22. }

  23. void keyscan()                                                //按键扫描程序
  24. {
  25.         static bit sign=0;                                //按键自锁标志
  26.         static uint count=0;                        //消抖计数变量                       
  27.         uint num=0;                                                //临时变量
  28.         PX(0x07C0);                                                //赋值PX 11111 000000
  29.         num=PD;                                                        //保存PD值 xxxxx 000000,x为0或1
  30.         if(num!=0x07C0)                                        //检测有按键按下
  31.         {
  32.                 if(++count>=10 && sign==0)  //根据主循环周期调整约10~20ms
  33.                 {                       
  34.                         sign=1;                                        //按键自锁标志置1
  35.                         num|=0x003f;                        //保存num按位或003f值 xxxxx 111111
  36.                         PX(num);                                //赋值PX              xxxxx 111111
  37.                         num=PD;                                        //保存PD值            xxxxx xxxxxx
  38.                         switch(num)
  39.                         {
  40.                                 case 0x07be: key= 1; break;//011110 111110
  41.                                 case 0x077e: key= 2; break;//011101 111110
  42.                                 case 0x06fe: key= 3; break;//011011 111110
  43.                                 case 0x05fe: key= 4; break;//010111 111110
  44.                                 case 0x03fe: key= 5; break;//001111 111110

  45.                                 case 0x07bd: key= 6; break;//011110 111101
  46.                                 case 0x077d: key= 7; break;//011101 111101
  47.                                 case 0x06fd: key= 8; break;//011011 111101
  48.                                 case 0x05fd: key= 9; break;//010111 111101
  49.                                 case 0x03fd: key=10; break;//001111 111101

  50.                                 case 0x07bb: key=11; break;//011110 111011
  51.                                 case 0x077b: key=12; break;//011101 111011
  52.                                 case 0x06fb: key=13; break;//011011 111011
  53.                                 case 0x05fb: key=14; break;//010111 111011
  54.                                 case 0x03fb: key=15; break;//001111 111011

  55.                                 case 0x07b7: key=16; break;//011110 110111
  56.                                 case 0x0777: key=17; break;//011101 110111
  57.                                 case 0x06f7: key=18; break;//011011 110111
  58.                                 case 0x05f7: key=19; break;//010111 110111
  59.                                 case 0x03f7: key=20; break;//001111 110111

  60.                                 case 0x07af: key=21; break;//011110 101111
  61.                                 case 0x076f: key=22; break;//011101 101111
  62.                                 case 0x06ef: key=23; break;//011011 101111
  63.                                 case 0x05ef: key=24; break;//010111 101111
  64.                                 case 0x03ef: key=25; break;//001111 101111

  65.                                 case 0x079f: key=26; break;//011110 011111
  66.                                 case 0x075f: key=27; break;//011101 011111
  67.                                 case 0x06df: key=28; break;//011011 011111
  68.                                 case 0x05df: key=29; break;//010111 011111
  69.                                 case 0x03df: key=30; break;//001111 011111
  70.                         }
  71.                 }
  72.         }
  73.         else                                                //键抬起
  74.         {
  75.                 sign=0;                                        //按键自锁标志清0
  76.                 count=0;                                //消抖计数清0
  77.         }
  78. }
  79. void main()                                                //主函数
  80. {
  81.         while(1)
  82.         {
  83.                 keyscan();                                //按键扫描程序
  84.                 if(flag)
  85.                 {
  86.                         P0=0x00;
  87.                         wela1=0;
  88.                         wela2=1;
  89.                         P0=table[key/10];
  90.                         flag=~flag;
  91.                 }
  92.                 else
  93.                 {
  94.                         P0=0x00;
  95.                         wela1=1;
  96.                         wela2=0;
  97.                         P0=table[key%10];
  98.                         flag=~flag;
  99.                 }
  100.         }
  101. }
复制代码




回复

使用道具 举报

ID:386602 发表于 2020-5-30 07:15 | 显示全部楼层
可以做成按钮矩阵链接占用11个IO口
回复

使用道具 举报

ID:307407 发表于 2020-5-30 08:56 | 显示全部楼层
有很多种方法:
第一种:采用独立按键直接并接到I/O口上;
优点:程序和硬件电路都简单;
缺点:占用过多的I/O口,需用到I/O口比较多的单片机;
第二种:矩阵扫描,使用12个I/O口,就可以扫描6x6=36个按键,只需用到30个按键就能完成此功能;
优点:硬件电路简单;
缺点:矩阵按键扫描程序变得更复杂;
第三种:采用并转串芯片增加I/O口,例如74HC165;
缺点:须另加多片165芯片,硬件电路复杂,软件也相对复杂
第四种:采用自带ADC的单片机;每个开关都接上不同的分压比,将不同的电压值送入单片机ADC处理,转换成对应的ADC数值,再通过程序对应每个开关,即可实现一个I/O口扫描30个按键;
优点:占用极少的I/O资源,电路也相对容易;
缺点:需要用到带ADC的单片机,如STC12C5612AD;

以上方法都可以实现30个按键的扫描!!
回复

使用道具 举报

ID:696382 发表于 2020-5-30 08:57 | 显示全部楼层
Y_G_G 发表于 2020-5-29 15:16
使用ADC端口加分压电阻,三四个端口就可以有30个按键了,自己参考一下

谢谢大佬提供新思路
回复

使用道具 举报

ID:696382 发表于 2020-5-30 08:58 | 显示全部楼层
TTQ001 发表于 2020-5-29 22:53
可以使用IO扩展电路,或IO和电阻矩阵电路来创建大键盘。

谢谢,我去查一下资料
回复

使用道具 举报

ID:332444 发表于 2020-5-30 14:09 | 显示全部楼层
不用扩展不用6*6,使用4*4就可以组合实现32个按键,之前发布的电路图已经24个按键了,可再加8个按键。
回复

使用道具 举报

ID:332444 发表于 2020-5-30 21:37 | 显示全部楼层
无标题.png

评分

参与人数 1黑币 +12 收起 理由
8092553 + 12 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:332444 发表于 2020-5-30 21:51 | 显示全部楼层
这个图调整的精致点好看点
无标题.png


回复

使用道具 举报

ID:332444 发表于 2020-5-31 05:40 | 显示全部楼层
无标题.png

回复

使用道具 举报

ID:332444 发表于 2020-5-31 14:42 | 显示全部楼层
2种按键扫描结合起来即可实现32按键功能。4*4矩阵按键扫描代码也不多可参
回复

使用道具 举报

ID:332444 发表于 2020-6-1 08:26 | 显示全部楼层
录像14_转.gif
回复

使用道具 举报

ID:332444 发表于 2020-6-1 15:07 | 显示全部楼层
录像15_转.gif
回复

使用道具 举报

ID:696382 发表于 2020-6-2 11:57 | 显示全部楼层
wulin 发表于 2020-5-29 23:29
给你写一个5*6矩阵键盘数码管动态显示示例参考,端口可以按实际需要自行更改,再把数码管显示改为LCD显示。 ...

谢谢大佬
回复

使用道具 举报

ID:696382 发表于 2020-6-2 13:33 | 显示全部楼层

谢谢大佬提供思路,我现在是使用的38译码器来设计的,我的按键都是常开继电器,我想通电后线路无误,其对应的继电器就会闭合,但是我没技术找到比较好的存储按键信息的方法,我想用显示屏来显示某号继电器未闭合。请问大佬有案例供我们初学者学习的吗
回复

使用道具 举报

ID:332444 发表于 2020-6-2 13:59 | 显示全部楼层
你的30个常开继电器触点按4*4矩阵按键电路接法来检测?如果是的话,那么,对应不同的IO读取值,是可以判断哪个没闭合。
回复

使用道具 举报

ID:332444 发表于 2020-6-2 16:03 | 显示全部楼层
扯点闲篇,这是刚设计出来的使用数码管显示A-Z字母,有些字母需要一点想象力。
录像17_转.gif

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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