找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3738|回复: 26
收起左侧

关于单片机多按键按下的检测程序问题

  [复制链接]
ID:516612 发表于 2021-1-28 16:32 | 显示全部楼层 |阅读模式
我是初学单片机和C语言,觉得很有意思。所以在网上买了套件。学到4*4矩阵键盘的时候,一开始就发现这个教程的程序太低级,用while去卡住cpu只为了检测一个按键是否松开,商家说没有更好的办法,太扯淡了,绝不可能!
所以这几天在找一些资料,也没找到。自己也过一些办法尝试写过,但始终无法跳出教程给的框架。
所以在论坛发了求助帖,也有大神回复了办法,可能我悟性确实太低,没代码根本想不通,即使有代码没注释可能也看不懂。有那么难吗?可能我不适合学编程吧,我想我最终也能解决这个问题,不过估计是几年后了。

1

1

2

2

3

3

4

4
回复

使用道具 举报

ID:807591 发表于 2021-1-28 17:04 | 显示全部楼层
那些客服就是糊弄人的,度娘一圈应该能找到你想要的,不要拘泥于别人的套路,自己得思考,也不要看那些代码写的多高端,甚至一段时间后自己都看不懂,编译器很可能会把那看似高级的代码编译成效率更低下的
回复

使用道具 举报

ID:516612 发表于 2021-1-28 17:24 | 显示全部楼层
szb314 发表于 2021-1-28 17:04
那些客服就是糊弄人的,度娘一圈应该能找到你想要的,不要拘泥于别人的套路,自己得思考,也不要看那些代码 ...

我就是找了几天没找到才去问的,结果商家的技术水平这么低。有点失望。其实实现什么功能倒是次要的,重要的是实现按键不冲突的编程思路。有些老哥回答的又看不懂,说的很简单,但实际又写不出来。这东西对新手太劝退了,跟着教程走一点拔高的思维都没有,要我照本宣科,讲的比他们还好些。
回复

使用道具 举报

ID:633344 发表于 2021-1-28 18:09 | 显示全部楼层
就我的认知来说键盘分两种,有些老式的电脑的键盘是编码键盘(电路设计复杂编程简单)早期IBM的个人计算机键盘是非编码式的,现在的部分薄膜键盘也是非编码键盘(电路简单编程稍复杂)单片机使用最多的就是非编码按键也就是需要行和列扫描通过电平的高低来实现检测按键是否按下
回复

使用道具 举报

ID:633344 发表于 2021-1-28 18:13 | 显示全部楼层
还有CPU和MCU是两个不同的东西哦,可以MCU是将计算机的CPU、RAM、ROM、定时计数器和多种I/O接口集成在一片芯片上,形成芯片级的芯片,内部除了CPU外还有RAM、ROM,可以直接加简单的外围器件(电阻,电容)就可以运行代码了。
回复

使用道具 举报

ID:232366 发表于 2021-1-28 18:14 来自手机 | 显示全部楼层
也有别的办法  多加学习已经就知道了我也是这样的
回复

使用道具 举报

ID:633344 发表于 2021-1-28 18:17 | 显示全部楼层
https://blog.csdn.net/andrewniu/article/details/53315881对于你说的键盘冲突可以参见这篇文章,讲解了如何处理非编码键盘的冲突
回复

使用道具 举报

ID:390416 发表于 2021-1-28 18:29 | 显示全部楼层
代码 矩阵键盘.jpg 不就是矩阵键盘吗 你早说啊。给你一个 自己看图片
回复

使用道具 举报

ID:390416 发表于 2021-1-28 18:29 | 显示全部楼层
  1. u8 xdata Key4x4_Read_Byte=3;//矩阵结果输出变量
  2. u8 code Key4x4_Buffer[4]={0xfe,0xfd,0xfb,0xf7};
  3. void Key4x4_Scan_Drive()
  4. {
  5.         static xdata u16 count=0;
  6.         u8 i,j,Value;
  7.         count++;
  8.         if(count>1000)
  9.         {
  10.                 count=0;
  11.                 IE2&=~0x08;
  12.                 for(i=0;i<4;i++)
  13.                 {
  14.                         P0=Key4x4_Buffer[i];
  15.                         Value=0x80;
  16.                         for(j=0;j<4;j++)
  17.                         {
  18.                                 if((P0&Value)==0)
  19.                                 {
  20.                                         Key4x4_Read_Byte=j*4+i+1;
  21.                                 }
  22.                                 Value>>=1;
  23.                         }
  24.                 }
  25.                 P0=0xff;
  26.                 IE2|=0x08;
  27.         }
  28. }
复制代码
回复

使用道具 举报

ID:516612 发表于 2021-1-28 18:40 | 显示全部楼层
yousir 发表于 2021-1-28 18:13
还有CPU和MCU是两个不同的东西哦,可以MCU是将计算机的CPU、RAM、ROM、定时计数器和多种I/O接口集成在一片 ...

哎。这我当然知道,你都把重点搞错了。重点是那个技术用这种话骗我好让我打消问他的念头
回复

使用道具 举报

ID:516612 发表于 2021-1-28 18:54 | 显示全部楼层
yousir 发表于 2021-1-28 18:09
就我的认知来说键盘分两种,有些老式的电脑的键盘是编码键盘(电路设计复杂编程简单)早期IBM的个人计算机 ...

按键检测不是重点,重点是无冲突,和按键松开后的检测问题,电脑键盘就可以实现这个功能,一般都是3键无冲,高级点的6键无冲,有的甚至是全键无冲。这个功能是肯定能实现的,而且应该不是太难的东西。PC键盘的资料我也查过,都是发通断码的,我这里说的是灯,其实是一个道理,无非就是改灯的电平,实现什么功能是次要的。包括多个按键按下之后的检测,看起来也是没问题的,可是当按键松开的时候,比如现在按顺序按下123,这3个键,当1键松开后怎么检测是1键松开了,而且这时候2和3还在工作。
回复

使用道具 举报

ID:879809 发表于 2021-1-28 19:08 | 显示全部楼层
18674201426 发表于 2021-1-28 18:54
按键检测不是重点,重点是无冲突,和按键松开后的检测问题,电脑键盘就可以实现这个功能,一般都是3键无 ...

Rf0c80fc1455509fe0ad497cee4ee4cbd.png
想要任意按键同时按下无冲突需要硬件支持,楼主的开发板显然没有。纯软件实现无冲突那是白日做梦。
回复

使用道具 举报

ID:516612 发表于 2021-1-28 19:39 | 显示全部楼层
rundstedt 发表于 2021-1-28 19:08
想要任意按键同时按下无冲突需要硬件支持,楼主的开发板显然没有。纯软件实现无冲突那是白日做梦。

嗯,那我知道,这种是极端情况,因为不仅要考虑软件的冲突,还要考虑硬件的冲突,因为按键都是并联的。我想知道的是,至少软件上不能有冲突,这样我们就能挑选出无硬件冲突的按键来制作扩展功能,毕竟那个教程里面给的用while来检测按键松开是不科学的。
回复

使用道具 举报

ID:516612 发表于 2021-1-28 23:21 | 显示全部楼层
人人学会单片机 发表于 2021-1-28 18:29
u8 xdata Key4x4_Read_Byte=3;//矩阵结果输出变量
u8 code Key4x4_Buffer[4]={0xfe,0xfd,0xfb,0xf7};
v ...

研究了一下,大概看懂了,这个应该是逐行扫描法吧。
那个count++应该就是延时吧,每隔10ms运行一次扫描程序,然后通过Key4x4_Read_Byte来判断键位,继而可以通过数组来发送数据。
但是这个应该还是不行,当按下多个键的时候,那每隔10ms就会从最靠近第一个键位的地方依次连续发送多个数据,而且没有按键松开的检测,那按键松开需要执行的就没法操作了。
回复

使用道具 举报

ID:798201 发表于 2021-1-29 00:23 | 显示全部楼层
请看这个大神的贴,里面有解决方法
http://www.51hei.com/bbs/dpj-162218-1.html
回复

使用道具 举报

ID:235954 发表于 2021-1-29 09:01 | 显示全部楼层
  1.                         if(key_pumb!=0) // 按键没有按下的时候
  2.                         {
  3.                                 key_pumb_flag=0;// 标志位清零
  4.                         }
  5.                 //按住开始跑灯,抽气(与开瓶不能同时按下兼容)       
  6.                 if(key_pumb==0&&key_motor==0)
  7.                 {
  8.                         delay100us(100);// 消除抖动延时       
  9.                 if(key_pumb==0&&key_motor==0)
  10.                  {
  11.                         //while(key_pumb==0);
  12.                         L_time_all=288;
  13.                         if(key_pumb_flag==0)// 消除抖动后再次判断按键是否按下
  14.                         {
  15.                                 key_pumb_num++;if(key_pumb_num>=2){key_pumb_num=0;}//按下抽气,再按下关闭
  16.                                 if(key_pumb_num==1){work=1;pumb=1;num++;auto_led_on(4,num);led_start_68();led_start_6A();}
  17.                                 if(key_pumb_num==0){work=0;pumb=0;}
  18.                         }
  19.                         key_pumb_flag=1;// 将标志位置1锁住 表示已经按下
  20.                  }
  21.                 }
复制代码
回复

使用道具 举报

ID:420836 发表于 2021-1-29 09:19 | 显示全部楼层
感谢楼主的分享。 希望您很快就能解决。
回复

使用道具 举报

ID:330938 发表于 2021-1-29 09:24 | 显示全部楼层
楼主不必纠结了,51开发板现在很多都做的很全面,很显然你买的这个牌子是个不咋样,至于这个技术人员目前还没法确定是不是垃圾,但沟通理解能力明显有缺陷,他根本就没有理解你的问题就瞎回答.
至于楼主适不适合编程这个还不能下结论,至少你能发现问题,没法解决问题只是你经验和能力还需要积累.
WHILE做按键是新手入门最常用的方式,等你学多了之后这个问题自然就能理解了
回复

使用道具 举报

ID:332444 发表于 2021-1-29 09:28 | 显示全部楼层
要能自主写矩阵驱动就得充分了解工作原理才能发挥得淋漓尽致,多看看其他人写的驱动代码,这个看看能否有点启示https://blog.csdn.net/xianfajushi/article/details/80884859
回复

使用道具 举报

ID:451718 发表于 2021-1-29 11:51 | 显示全部楼层
你要的应该是类似这样的解决方案吧?
http://www.51hei.com/bbs/dpj-161402-1.html

把每个键都对应一个键值,组合键也对应一个键值, 没有按键也对应一个键值,你的问题不就解决了?
回复

使用道具 举报

ID:516612 发表于 2021-1-29 12:39 | 显示全部楼层
yousir 发表于 2021-1-28 18:17
https://blog.csdn.net/andrewniu/article/details/53315881对于你说的键盘冲突可以参见这篇文章,讲解了如 ...

这个我很早就看过了,他这主要讲的是PC键盘与PC机的PS2通信协议,然后大概的讲了一下冲突的产生原因,但是并没有讲解如何从软件和硬件层面去解决这个问题,如果我现在连软件层面的问题都解决不了,赢了做了也没用。
回复

使用道具 举报

ID:392485 发表于 2021-1-29 14:23 | 显示全部楼层
不考虑硬件冲突的原因,但从软件方面说可以尝试将读回来的键值放在一个变量里。让这个变量每一位代表一个按键,然后判断每一位的变化,应该可以实现。
回复

使用道具 举报

ID:516612 发表于 2021-1-29 16:10 | 显示全部楼层
robinsonlin 发表于 2021-1-29 11:51
你要的应该是类似这样的解决方案吧?
http://www.51hei.com/bbs/dpj-161402-1.html

昨天有个老铁也说用标识位的方式试试,通过数组对应按键,但是没有办法解决按键松开的问题,并且多键位按下时扫描键盘状态会顺序发送按键值,但是他的示例给了我一些灵感,好像有点眉目,所以我也还在考虑标识位这种方式。
回复

使用道具 举报

ID:516612 发表于 2021-1-29 16:12 | 显示全部楼层
xianfajushi 发表于 2021-1-29 09:28
要能自主写矩阵驱动就得充分了解工作原理才能发挥得淋漓尽致,多看看其他人写的驱动代码,这个看看能否有点启 ...

就是因为目前想不出又找不到这个原理,所以才来问,你发的那些都是基础的按键检测方式,和教程一样的。
回复

使用道具 举报

ID:516612 发表于 2021-1-29 16:20 | 显示全部楼层
zwf33 发表于 2021-1-29 00:23
请看这个大神的贴,里面有解决方法
http://www.51hei.com/bbs/dpj-162218-1.html

嗯,这个我很早就看过了,他的示例是有借鉴的价值的。
回复

使用道具 举报

ID:392485 发表于 2021-1-30 12:36 | 显示全部楼层
18674201426 发表于 2021-1-29 16:10
昨天有个老铁也说用标识位的方式试试,通过数组对应按键,但是没有办法解决按键松开的问题,并且多键位按 ...

可以检测的,当按键按下的时候相应位是0,松开后相应位变为1,你只需要检测相应的位的变化就可以了。只要和前一次的不同就说明按键有变化了。
回复

使用道具 举报

ID:275826 发表于 2021-1-31 16:10 | 显示全部楼层
送你一个程序,可以满足你的按键要求
#include<reg51.h>
#define uchar unsigned char
#define keyport P1

void scan1(void);

/****************************************************************/
void        tim0()        interrupt    1       
{            
         TH0=(65536-10000)/256;
     TL0=(65536-10000)%256;
         scan1();
          
}
       
/****************************************************************/                       
unsigned tmp[4];               

/****************************************************************/
void scan1(void)       
{  unsigned        char j;
   unsigned int itmp=0;
   for(j=0;j<4;j++)       
   {keyport=~(0x10<<j);       
        tmp[j]=~(keyport&0x0f)&0x0f;
        itmp=itmp|(tmp[j]<<(4*j));
        }
        itmp=~itmp;
        P0=itmp;
        P2=itmp>>8;               
                    
}                       
/****************************************************************/                       

void main(void)
  {        TH0=(65536-10000)/256;
    TL0=(65536-10000)%256;
        TMOD=0x01;
        EA=ET0=TR0=1;
       
        while(1);
  }
/****************************************************************/
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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