51单片机学习-矩阵式键盘的应用

1.电路结构

       行线Row0~3接到P0.0~P0.3端口,通过4个1K上拉电阻接+5V,置“1”,作为输入状态;列线Col0~3接到P2.0~P2.3端口,作为输出状态。按键设在行、列交点上。

 2.原理:扫描法---逐一送低电平

        在某一时刻只让一条列线处于电平,均其余列线处于高电平。则当这一列有按键按下时,该键所在的电平将会有电平变为电平,可判定该列相应的行有键按下。

/*流程:当第0列处于低电平时,逐行查找是否有行线变低,若有,则第0列与该行的交叉点按键按下;若无,则表示第0列无键按下,再让下一列处于低电平,依次循环。

键值 =行号*4+列号        //KeyNum =Row*4+Col

/*第0列送低电平:若第0列无按键按下,则P0=0xff,temp=0x00。//temp=P0;temp=~temp%0x0f

                              若第0列第0行按键按下P0不全高,temp=0x01,Row=0,Col=0,KeyNum=Row*4+Col =0----可知按键0按下

                              若第1列第0行按键按下P0不全高,temp=0x01,Row=0,Col=1,KeyNum=Row*4+Col =1----可知按键1按下

                              若第2列第0行按键按下P0不全高,temp=0x01,Row=0,Col=2,KeyNum=Row*4+Col =2----可知按键2按下

                              若第3列第0行按键按下P0不全高,temp=0x01,Row=0,Col=3,KeyNum=Row*4+Col =3----可知按键3按下

                              若第0列第1行按键按下P0不全高,temp=0x02,Row=1,Col=0,KeyNum=Row*4+Col =4----可知按键4按下

                              若第0列第2行按键按下P0不全高,temp=0x04,Row=2,Col=0,KeyNum=Row*4+Col =8----可知按键8按下

........

        

 3.程序源码

//功能:矩阵键盘扫面程序
#include <reg51.h>
#define uchar unsigned char
#define uint  unsigned int
uchar code Table[] ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//LED码表

void KeyScam();//键盘扫描函数
void main()
{
    uchar KeyNum;    //按键值变量
    while(1)
    {
        KeyNum =KeyScam();    //调用扫描函数
        P3 =Table[KeyNum];    //显示按键值,显示数码管接到P3口
    }
}
//扫描子程序
//返回值:KeyNum
void KeyScam()
{
    uint Row,Col,KeyNum,j,temp;    //定义行、列、返回值、temp-临时变量存储P0状态
    P0 =0xff;        //P0初始状态 
    for(j =0;j<4;j++)      //分4次(列)扫描
    {
        P2 =0xfe<<j;       //扫描列扫描码P2口(低4位),每次扫描一次
        temp =P0;          //读回行值  
        temp =~temp&0x0f;  //读回行值取反,并去掉高4位 
        if(temp !=0x00)    //如果读回行值为0则没有按键按下
        {
            Delay(5);    //消抖延时
            temp =P0;    //读回行值
            temp =~temp&0x0f;   //读回行值取反,并去掉高4位(P0.4~0.7没有用到,故去掉)
            if(temp !=0x00)     //如果读回行值为0则没有按键按下
            {
                Col =j;         //保存列值
                switch(temp)    //确定被按下的键所在第几行
                {
                    case 0x01:Row =0;break;    //读取值是0x01,说明按下的键在第0行,Row=0
                    case 0x02:Row =1;break;    //读取值是0x02,说明按下的键在第1行,Row=1
                    case 0x04:Row =2;break;    //读取值是0x04,说明按下的键在第2行,Row=2
                    case 0x08:Row =3;break;    //读取值是0x08,说明按下的键在第3行,Row=3
                    default:break;             //读取值是其他参数不处理
                }
                break;    //已经确定行列值,提前结束扫描
            }
        }
    }
    KeyNum =Row*4+Col;    //确定键值,公式计算
    return KeyNum;        //键值返回主函数
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值