以下为程序:
/*反转法矩阵键盘的应用,我认为这是一个编程简便又容易理解的矩阵键盘编程应用,因此拿来与大家共享*/
/*殷传东对此程序拥有独家版权,仅可用于研究学习,严禁用于商业目的,欢迎喜爱
单片机的大虾小虾皮皮虾联系交流QQ:77329961*/
#include<reg52.h> //头文件
#define uchar unsigned char //宏定义
#define uint unsigned int
uchar key,n; //定义变量
uchar code table[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77}; //反转法矩阵键盘的各个按键的计算值
uchar code yin[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共阴极数码管显示0~F
void delay(uint i) //延时函数
{
while(i--);
}
void keyscan()
{
uchar l,h,i; //定义局部变量,用l得出低4位的值,用h得出高4位的值
P1=0x0f; //给P1赋值00001111
l=P1&0x0f;
if(l!=0x0f)
{
delay(100);
if(l!=0x0f)
l=P1&0x0f; //若有键按下,得出低四位的值
}
P1=0xf0; //给P1赋值11110000
h=P1&0xf0;
if(h!=0xf0)
{
delay(100);
if(h!=0xf0)
h=P1&0xf0; //若有键按下,得出高4位的值
}
key=l+h; //高4位的值与低4位的值相加
for(i=0;i<16;i++)
{
if(key==table) //通过查表得出n的值
n=i;
}
}
void main()
{
while(1)
{
keyscan();
P0=yin[n]; //在数码管上显示相应的键值
}
}
程序基于AT89S51芯片,两个573锁存器(控制 段选位选)
P3口接矩阵键盘,其中P3.0~P3.3接行线,P3.4~P3.7接列线,P0口接共阴极7段数码管。
反转法的原理:
反转法就是通过给单片机的端口赋值两次,最后得出所按键的值的一种算法。
给P3口赋值0x0f,即00001111,假设0键按下了,则这时P3口的实际值为00001110;
给P3口再赋值0xf0,即11110000,如果0键按下了,则这时P3口的实际值为11100000;
通过这两次P3口的实际值相加得11101110,即0xee。
由此我们便得到了按下0键时所对应的数值0xee,以此类推可得出其他15个按键对应的数值,有了这种对应关系,矩阵键盘编程问题也就解决了,也就是程序的算法已经有了。
(上述方法来源于网络)
好了下面直接进入程序
#include<at89x52.h> //头文件
#define uchar unsigned char //宏定义
#define uint unsigned int
uchar key,n,i; //定义变量
uchar code table[]={0xee,0xde,0xbe,0x7e,0xed,0xdd,0xbd,0x7d,0xeb,0xdb,0xbb,0x7b,0xe7,0xd7,0xb7,0x77}; //反转法矩阵键盘的各个按键的计算值
uchar code yin[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共阴极数码管显示0~F
void delay(uint i) //延时函数
{
while(i--);
}
void keyscan()
{
uchar l,h,i; //定义局部变量,用l得出低4位的值,用h得出高4位的值
P3=0x0f; //给P3赋值00001111
l=P3&0x0f;
if(l!=0x0f)
{
delay(100); //延迟后再检测
P3=0x0f;
l=P3&0x0f;
if(l!=0x0f)
{
h=P3&0xf0; //若有键按下,得出高四位的值
P3=0xf0; //给P3赋值11110000
h=P3&0xf0; //若有键按下,得出低四位的值
key=l+h; //高4位的值与低4位的值相加
for(i=0;i<16;i++)
{
if(key==table[i]) //通过查表得出n的值
n=i;
}
}
}
}
void main()
{
while(1)
{
keyscan();
for(i=0;i<6;i++) //送入位选信号控制数码管
{
P2_6=1;P2_7=0;
P0=yin[n];
P2_6=0;P2_7=1;
switch(i)
{
case 0:P0=0xfe;break;
case 1:P0=0xfd;break;
case 2:P0=0xfb;break;
case 3:P0=0xf7;break;
case 4:P0=0xef;break;
case 5:P0=0xdf;break;
default:break;
}
P2_6=0;P2_7=0;
delay(100);
}
}
}
新手标注可能不够到位,多多理解,如有错误请多多指教。
也是新手?
/****************************************************************************************************
4*4=16个矩阵键盘,开始数码管不显示,在分别按下这16个按键时,数码管静态分别显示0-F
实现电路:郭天祥GTX-1C,4*4矩阵键盘的4行和4列分别连接P3.0-P3.7口
****************************************************************************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
sbit dula=P2^6; //定义段拉
sbit wela=P2^7; //定义位拉
uchar key;
void delay(uint x) //延时子函数500uS
{
uchar y;
for(x;x>0;x--)
for(y=225;y>0;y--);
}
void scankey() //按键扫描程序
{
uchar tmp,tmp1;
if(P3!=0x0f) //在主函数中,先给P3送了0x0f(00001111)电平,以检测按下的是哪一行,如果有按键按下,这个值都会变化。
{
tmp1=P3; //如果是1-4按键按下,则变为00001110,5-8为00001101,9-12为00001011,13-16为00000111,把这个值赋给tmp1
delay(20); //延时10mS,消抖
P3=0xf0; //再次给P3送0xf0(11110000)电平,以检测是那一列按键按下
if(P3!=0xf0) //消抖后仍然检测到按键按下,值发生变化,P3不等于0xf0
{ //如果是1.5.9.13按键按下,则变为11100000,2.6.10.14为11010000,3.7.11.15为10110000,4.8.12.16为01110000
tmp=(tmp1|P3); //将检测的行值和列值进行或运算
switch(tmp) //switch语句对tmp值进行多条件选择
{
case 0xee: //如果是1按键按下,这个值对应为11101110,则显示数组的0位数
key=0;
break;
case 0xde:
key=1;
break;
case 0xbe:
key=2;
break;
case 0x7e:
key=3;
break;
case 0xed:
key=4;
break;
case 0xdd:
key=5;
break;
case 0xbd:
key=6;
break;
case 0x7d:
key=7;
break;
case 0xeb:
key=8;
break;
case 0xdb:
key=9;
break;
case 0xbb:
key=10;
break;
case 0x7b:
key=11;
break;
case 0xe7:
key=12;
break;
case 0xd7:
key=13;
break;
case 0xb7:
key=14;
break;
case 0x77:
key=15;
break;
}
while(P3!=0xf0); //等待按键放开
dula=1;
P0=table[key]; //送数码管段数据
dula=0;
}
}
}
void main()
{
wela=1;
P0=0x00;
wela=0; //因为是静态显示,所以就没有写单独的display显示子函数
while(1)
{
P3=0x0f; //先给P3送00001111电平
scankey(); //扫描按键子函数
}
}
一周热门 更多>