搜索
bottom↓
回复: 8

4x4键盘消抖总是做不好,各位帮忙看下

[复制链接]

出0入0汤圆

发表于 2013-3-7 10:27:24 | 显示全部楼层 |阅读模式
刚学单片
  1. #include "reg51.h"

  2. #define uchar unsigned char
  3. #define uint unsigned int


  4. //定义要发送的数组SendBuf[]并进行初始
  5. uchar SendBuf_1[]={0XF0,0X03,0X26,0X01,0X00,0X27,0XFF};


  6. void Delay1ms(uint count)
  7. {
  8.         uint i,j;
  9.         for(i=0;i<count;i++)
  10.         for(j=0;j<110;j++);
  11. }  

  12. /********数据发送函数********/
  13. void send_dat_1()
  14. {
  15.         uchar i;
  16.         for(i=0;i<7;i++)
  17.                 {
  18.                         SBUF =SendBuf_1[i];
  19.                         while(!TI);    // 等待数据发送完成
  20.                         TI = 0;    // 清发送标志位
  21.                  }
  22. }

  23. /********4X4键盘扫描函数********/
  24. uchar keyscan()
  25. {
  26.         uchar cord_h,cord_l;
  27.         P1=0x0f;                                //行线输出全为0
  28.         cord_h=P1&0x0f;                        //读入列线值
  29.         if(cord_h!=0x0f)                //先检测有无按键按下
  30.         {
  31.                 Delay1ms(20);                //去抖
  32.                 if(cord_h!=0x0f)
  33.                 {
  34.                          cord_h=P1&0x0f;                //读入列线值
  35.                          P1=cord_h|0xf0;               //输出当前列线值
  36.                          cord_l=P1&0xf0;               //读入行线值
  37.                          return(cord_h+cord_l);
  38.                 }
  39.         }
  40.         return(0xff);
  41. }


  42. /********以下是串行口初始化函数********/
  43. void series_init()
  44. {
  45.         SCON=0x50;                //串口工作方式1,允许接收
  46.         TMOD=0x20;                //定时器T1工作方式2
  47.         TH1=0xfd;
  48.         TL1=0xfd;           //定时初值
  49. //        PCON&=0x00;                //SMOD=0  电源控制寄存器PCON SMOD=1时波特率倍增
  50.         PCON=0x80;                //SMOD=1时波特率倍增为19200
  51.         TR1=1;                        //开启定时器1
  52. }

  53. /********以下是主函数********/

  54. void main()
  55. {
  56.         uchar key;
  57.         series_init();                        //调串行口初始化函数
  58.         while(1)
  59.         {
  60.                 key=keyscan();           
  61.                 switch(key)
  62.                   {
  63.                     case 0x7e:send_dat_1();break;//0 按下相应的键调数据发送函数
  64.                     case 0x7d:send_dat_2();break;//1
  65.                     case 0x7b:send_dat_3();break;//2
  66.                     case 0x77:send_dat_4();break;//3
  67.                     case 0xbe:send_dat_5();break;//4
  68.                     case 0xbd:send_dat_6();break;//5
  69. //                        case 0xbb:P0=table[6];break;//6
  70. //                    case 0xb7:P0=table[7];break;//7
  71. //                    case 0xde:P0=table[8];break;//8
  72. //                    case 0xdd:P0=table[9];break;//9
  73. //                    case 0xdb:P0=table[10];break;//a
  74. //                    case 0xd7:P0=table[11];break;//b
  75. //                    case 0xee:P0=table[12];break;//c
  76. //                    case 0xed:P0=table[13];break;//d
  77. //                    case 0xeb:P0=table[14];break;//e
  78. //                    case 0xe7:P0=table[15];break;//f
  79.                     default:        break;    //无键按下       
  80.                 }                                                                                                  
  81.         }
  82. }
复制代码
机,直接进入主题吧。4x4键盘反转法,按下按键发送相应的串口数据,但是上位机收到的确是一堆数据,数据是正确的,只是多收到了好几遍,判定键盘消抖没做好!

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

发表于 2013-3-7 10:57:47 | 显示全部楼层
用定时器中断隔时扫描,每隔几ms扫描一次键盘,看与上一次扫描是否有变化,进而判断是否有按下、弹起

出0入0汤圆

发表于 2013-3-7 10:59:34 | 显示全部楼层
把松手检测加上

出0入0汤圆

 楼主| 发表于 2013-3-7 11:17:04 | 显示全部楼层
这个松手检测好像还真不好加唉,在cord_l=P1&0xf0; 后加了一句while(P1!=0X0f),没什么效果

出0入0汤圆

发表于 2013-3-7 11:54:54 | 显示全部楼层
void main()
{
        uchar key,CurrenKey=0xff;
        series_init();                        //调串行口初始化函数
        while(1)
         {
                key=keyscan();
                                if(key!=CurrentKey)
                                {           
                  CurrentKey=key;
                                  switch(key)
                  {
                    case 0x7e:send_dat_1();break;//0 按下相应的键调数据发送函数
                    case 0x7d:send_dat_2();break;//1
                    case 0x7b:send_dat_3();break;//2
                    case 0x77:send_dat_4();break;//3
                    case 0xbe:send_dat_5();break;//4
                    case 0xbd:send_dat_6();break;//5
//                        case 0xbb:P0=table[6];break;//6
//                    case 0xb7:P0=table[7];break;//7
//                    case 0xde:P0=table[8];break;//8
//                    case 0xdd:P0=table[9];break;//9
//                    case 0xdb:P0=table[10];break;//a
//                    case 0xd7:P0=table[11];break;//b
//                    case 0xee:P0=table[12];break;//c
//                    case 0xed:P0=table[13];break;//d
//                    case 0xeb:P0=table[14];break;//e
//                    case 0xe7:P0=table[15];break;//f
                    default:CurrentKey=0xff; break;    //无键按下        
                 }
                           }                                                                                                
        }
}

楼主可以试试这样,加一个当前按键中间变量,相同则不重复动作,释放后则设为初始值。

出0入0汤圆

发表于 2013-3-7 11:56:20 | 显示全部楼层
mcu_Lei 发表于 2013-3-7 11:54
void main()
{
        uchar key,CurrenKey=0xff;

回复初始值,应该在按键释放后,应该单列一个case条件。

出0入4汤圆

发表于 2013-3-7 12:16:00 | 显示全部楼层
弄个按键扫描子程序,开个定时器,10ms调用一次,扫描按键的时候有键按下就执行一次你的相应程序,在此之后如果按键没松开且按键值跟上一次一样不处理,否则你懂得。

出0入0汤圆

 楼主| 发表于 2013-3-7 13:09:16 | 显示全部楼层
非常感谢  mcu_Lei  按你的方法问题解决了

出0入442汤圆

发表于 2013-3-7 15:09:09 | 显示全部楼层
其实我觉得,应该使用定时器中断的方式来捕捉按键信号,第一次检测到按下时,把第一个比特字置1,第二次检测到按下时,就发出一个按下标志。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-23 18:25

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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