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

2020-01-30 14:08发布

刚学单片
  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键盘反转法,按下按键发送相应的串口数据,但是上位机收到的确是一堆数据,数据是正确的,只是多收到了好几遍,判定键盘消抖没做好!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
dashashi
1楼-- · 2020-01-30 17:22
用定时器中断隔时扫描,每隔几ms扫描一次键盘,看与上一次扫描是否有变化,进而判断是否有按下、弹起
xllsh
2楼-- · 2020-01-30 22:03
把松手检测加上
weimas
3楼-- · 2020-01-31 00:06
这个松手检测好像还真不好加唉,在cord_l=P1&0xf0; 后加了一句while(P1!=0X0f),没什么效果
mcu_Lei
4楼-- · 2020-01-31 02:03
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;    //无键按下        
                 }
                           }                                                                                                
        }
}

楼主可以试试这样,加一个当前按键中间变量,相同则不重复动作,释放后则设为初始值。
mcu_Lei
5楼-- · 2020-01-31 07:42
 精彩回答 2  元偷偷看……
ibichao
6楼-- · 2020-01-31 13:06
弄个按键扫描子程序,开个定时器,10ms调用一次,扫描按键的时候有键按下就执行一次你的相应程序,在此之后如果按键没松开且按键值跟上一次一样不处理,否则你懂得。

一周热门 更多>