本文为LCD-执棋困局,csdn原创首发。
发布人:LCD-执棋困局
欢迎大家与LCD-执棋困局相互点赞+关注+收藏+评论,也祝大家生活安康,学业愉快,工作顺利。
我的格言是:“尽最大努力,做最好的自己!”
上一篇我们讲了独立按键的单一键项目实战,为大家更好地理解行列扫描的使用。
想回顾上一次的学习或遗忘知识的伙伴们
请看:独立按键(二)——一键一义(多项目举例)
一、仿真图
如图,矩阵键盘是一个4×4排列的键盘组,其中代表行的一端接到P3的低4位,代表列的一端接到P3高4位。
二、理论细述
线反转法目的:通过读取被按下的键盘所在的行和列判断哪个键盘被按下。
假如第一个按键被按下:
第一步:将列(P3高4位)作为输入(电平为1),而行(P3低4位)作为输出(电平为0,接地)。P3此时是11110000
第二步:当第一个键盘被按下时,第一列所在的P3^4变成低电平0,P3口的8位二进制发生变化,由原来的11110000变成了11100000。
第三步:将列(P3高4位)作为输出(电平为0,接地),而行(P3低4位)作为输入(电平为1)。
第四步:当第一个键盘被按下时,第一行所在的P3^0变成低电平0,P3口的8位二进制发生变化,由原来的00001111变成了00001110。
第五步:将两者加起来:11100000+00001110=11101110,即0xe0+0x0e=0xee,这个结果是每一个按键的十六进制行列编号,不是人为规定的。
其他15个按键的十六进制结果也可以通过以上方法得到。
keynum代表的是第几个键盘,左边分别对应十六进制结果。
具体写时,要按上一文章写独立按键模块的步骤一步一步地写,不会或不记得的,可以看独立按键(二)——一键一义(多项目举例)
三、键盘按键函数
unsigned char key_scan()//键盘按键函数
{
unsigned char temp,temp2;
static unsigned char keynum=20;
KEYPIO=0xf0;//1为输入 0位输出 令高4位为1 低4位为0
temp=KEYPIO;
if(temp!=0xf0)//判断是否按下按键
{
delay(10);//消抖延时10ms
if(temp!=0xf0)//再次判断是否按下按键
{
temp=KEYPIO&0xf0;//确定行
KEYPIO=0x0f;//反转
temp2=KEYPIO&0x0f;//确定列
}
}
switch(temp+temp2)
{
case 0xee:keynum=1;break;
case 0xed:keynum=2;break;
case 0xeb:keynum=3;break;
case 0xe7:keynum=4;break;
case 0xde:keynum=5;break;
case 0xdd:keynum=6;break;
case 0xdb:keynum=7;break;
case 0xd7:keynum=8;break;
case 0xbe:keynum=9;break;
case 0xbd:keynum=0;break;
case 0xbb:keynum=10;break;
case 0xb7:keynum=11;break;
case 0x7e:keynum=12;break;
case 0x7d:keynum=13;break;
case 0x7b:keynum=14;break;
case 0x77:keynum=15;break;
default:break;
}
return keynum;
}
四、实战操作
1.项目功能
判断哪个按键被按下,将该按键人为规定的编号在数码管显示。
人为编码:从第一列开始,竖直方向编码,依次是0、1、2、3、…、9、0、a、b、c、e、f
2.代码
key_scan()最后会返回按键按下的一个值,要注意,这个值**不是上面所规定的编号**,而是0~15,最后**可以通过数码管模块中定义的缓冲区进行转换成人为规定的编号**。
key_scan.c
#include "key_scan.h"//键盘头文件
#include "delay.h"//延时头文件
/******************************************************************************************
函数名:key
功能: 键盘函数
参数: 无
返回值:unsigned char
******************************************************************************************/
unsigned char key_scan()//键盘按键函数
{
unsigned char temp,temp2;
static unsigned char keynum=20;
KEYPIO=0xf0;//1为输入 0位输出 令高4位为1 低4位为0
temp=KEYPIO;
if(temp!=0xf0)//判断是否按下按键
{
delay(10);//消抖延时10ms
if(temp!=0xf0)//再次判断是否按下按键
{
temp=KEYPIO&0xf0;//确定行
KEYPIO=0x0f;//反转
temp2=KEYPIO&0x0f;//确定列
}
}
switch(temp+temp2)
{
case 0xee:keynum=1;break;
case 0xed:keynum=2;break;
case 0xeb:keynum=3;break;
case 0xe7:keynum=4;break;
case 0xde:keynum=5;break;
case 0xdd:keynum=6;break;
case 0xdb:keynum=7;break;
case 0xd7:keynum=8;break;
case 0xbe:keynum=9;break;
case 0xbd:keynum=0;break;
case 0xbb:keynum=10;break;
case 0xb7:keynum=11;break;
case 0x7e:keynum=12;break;
case 0x7d:keynum=13;break;
case 0x7b:keynum=14;break;
case 0x77:keynum=15;break;
default:break;
}
return keynum;
}
key_scan.h
#ifndef __KEY_SCAN_H__
#define __KEY_SCAN_H__
#include <reg51.h>//51头文件
#define KEYPIO P3 //矩阵键盘两端所接的IO口
unsigned char key_scan();//独立键盘函数声明
#endif
main.c
#include <reg51.h>
#include "key_scan.h"
#include "display.h"
void main()
{
while(1)
{
LEDBuf[0]=23;
LEDBuf[1]=23;
LEDBuf[2]=23;
LEDBuf[3]=key_scan();
display();
}
}
数码管显示模块display.c和display.h可以通过关注LCD-执棋困局,在数码管一文中免费获得!