找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2080|回复: 5
收起左侧

51单片机4*4矩阵键盘如何扫描识别?自己的写法比较繁琐,求指教

[复制链接]
ID:485870 发表于 2019-3-13 14:07 | 显示全部楼层 |阅读模式
我感觉自己掌握的矩阵键盘扫描写法比较繁琐,希望有大佬指教好的方法,十分感谢!

uchar KeyScan()        //带返回值的子函数
{
        uchar cord_l,cord_h;//声明列线和行线的值的储存变量
        P3 = 0xf0;//1111 0000
        if( (P3 & 0xf0) != 0xf0)//判断是否有按键按下(按下就为与)
        {
                delay(5);//软件消抖
                if( (P3 & 0xf0) != 0xf0)//再次判断是否有按键按下
                {
                          cord_l = P3 & 0xf0;// 储存列线值
                          P3 = cord_l | 0x0f;
                          cord_h = P3 & 0x0f;// 储存行线值
                          while( (P3 & 0x0f) != 0x0f );//松手检测
                          return (cord_l + cord_h);//返回键值码
                }        
        }
               
}


void KeyPro()
{
        switch( KeyScan() )
        {
                 //第一行键值码
                case 0xee: P0 = leddata[0];                break;
                case 0xde: P0 = leddata[1];                break;
                case 0xbe: P0 = leddata[2];                break;
                case 0x7e: P0 = leddata[3];                break;
               
                //第二行键值码
                case 0xed: P0 = leddata[4];                break;
                case 0xdd: P0 = leddata[5];                break;
                case 0xbd: P0 = leddata[6];                break;
                case 0x7d: P0 = leddata[7];                break;


                //第三行键值码
                case 0xeb: P0 = leddata[8];                break;
                case 0xdb: P0 = leddata[9];                break;
                case 0xbb: P0 = leddata[10];        break;
                case 0x7b: P0 = leddata[11];        break;


                //第四行键值码
                case 0xe7: P0 = leddata[12];        break;
                case 0xd7: P0 = leddata[13];        break;
                case 0xb7: P0 = leddata[14];        break;
                case 0x77: P0 = leddata[15];        break;
        }        
}



回复

使用道具 举报

ID:490008 发表于 2019-3-13 15:27 | 显示全部楼层
最好不要delay   定时扫描获取键值就好了
回复

使用道具 举报

ID:466164 发表于 2019-3-13 20:18 | 显示全部楼层
给你截一段
if(jzaj!=0x0f) //再次判断
                {
                        jzaj=0x0f;
                        switch (jzaj)
                        {
                                case(0x07):ajsj=0;break;  //如果总线为0000 0111是按键数据存0
                                case(0x0b):ajsj=1;break;
                                case(0x0d):ajsj=2;break;
                                case(0x0e):ajsj=3;break;
                        }
                        jzaj=0xf0;
                        switch(jzaj)
                        {
                                case(0x70):ajsj=ajsj;break;
                                case(0xb0):ajsj=ajsj+4;break;
                                case(0xd0):ajsj=ajsj+8;break;
                                case(0xe0):ajsj=ajsj+12;break;
                        }
                        while((a<50)&&(jzaj!=0x0f))        //当a<50同时总线不等于00001111时,执行延时。
                        {
                                delay(1000);
                                a++;
                        }
                }
回复

使用道具 举报

ID:485458 发表于 2019-3-13 22:17 | 显示全部楼层

void keyscan()//高四位为列线,低四位为行线
{
        P3=0xf0;//列扫描,有键按下后该列会被拉低
        if(P3!=0xf0)//判断案件是否按下
        {
                delayms(5);//延时消抖
                if(P3!=0xf0)
                {
                        switch(P3)//判断哪一列被按下
                        {
                                case 0xe0:keyval=0;//1110 0000
                                        break;
                                case 0xd0:keyval=1;//1101 0000
                                        break;
                                case 0xb0:keyval=2;//1011 0000
                                        break;
                                case 0x70:keyval=3;//0111 0000
                                        break;
                        }
                        P3=0x0f;
                        switch(P3)//判断哪一行被按下
                        {
                                case 0x0e:keyval=keyval;
                                        break;
                                case 0x0d:keyval=keyval+4;
                                        break;
                                case 0x0b:keyval=keyval+8;
                                        break;
                                case 0x07:keyval=keyval+12;
                                        break;
                        }
                        while(P3!=0x0f);//松手检测,按键按住时P3始终不等于0x0f,始终执行循环,松手后P3=0x0f
                }
        }
}

评分

参与人数 1黑币 +6 收起 理由
_nop_() + 6 很给力!

查看全部评分

回复

使用道具 举报

ID:485870 发表于 2019-3-14 21:08 | 显示全部楼层
7358655 发表于 2019-3-13 20:18
给你截一段
if(jzaj!=0x0f) //再次判断
                {

非常感谢,希望您也能经常得到自己想要的回复
回复

使用道具 举报

ID:485870 发表于 2019-3-14 21:09 | 显示全部楼层
2678254412 发表于 2019-3-13 22:17
void keyscan()//高四位为列线,低四位为行线
{
        P3=0xf0;//列扫描,有键按下后该列会被拉低

非常感谢,希望您也能经常得到自己想要的回复
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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