异组端口组成4*4矩阵键盘的端口状态读写方法
#include <AT89X51.H>
#define uint unsigned int //宏定义数据类型uint
#define uchar unsigned char //宏定义数据类型uchar
sbit code0=P3^0; //定义4*4键盘端口
sbit code1=P3^1;
sbit code2=P3^2;
sbit code3=P3^3;
sbit code4=P3^4;
sbit code5=P3^5;
sbit code6=P2^2;
sbit code7=P2^4;
uchar key=0xff; //键值变量初始值
void PX(uchar i) //写入8位数据
{
code0=i&0x01;i>>=1;
code1=i&0x01;i>>=1;
code2=i&0x01;i>>=1;
code3=i&0x01;i>>=1;
code4=i&0x01;i>>=1;
code5=i&0x01;i>>=1;
code6=i&0x01;i>>=1;
code7=i&0x01;
}
uchar PD() //读取8位数据
{
uchar i;
i=code7;
i=(i<<1)|code6;
i=(i<<1)|code5;
i=(i<<1)|code4;
i=(i<<1)|code3;
i=(i<<1)|code2;
i=(i<<1)|code1;
i=(i<<1)|code0;
return i;
}
void key_scan() //矩阵键盘扫描函数
{
uchar temp1,temp2,temp3; //临时变量
static bit sign=0; //按键自锁标志
static uint count=0; //消抖计数变量
PX(0xf0); //先给矩阵端口赋一个初值0xf0
if(PD()!=0xf0) //判断矩阵端口不等于所赋初值,说明有健按下
{
if(sign==0) //如果按键自锁标志为0
{
count++; //消抖计数
if(count>=1000) //消抖计数自>=200,估算主循环周期调整
{ //摒弃Delay延时方式,
count=1000; //防止溢出
sign=1; //按键自锁标志置1,键不抬起,按其他键无效
temp1=PD(); //temp1保存矩阵端口高4位变化
PX(0x0f); //再给矩阵端口赋值0x0f
temp2=PD(); //temp2保存矩阵端口低4位变化
temp3=temp2|temp1; //temp3=高4位+低4位
key=temp3; //保存键值
}
}
}
else //按键抬起
{
sign=0; //按键自锁标志清0
count=0; //消抖计数清0
}
}
void main()
{
while(1)
{
key_scan(); //键盘扫描
P1=key; //LED低电平亮显示键值
}
} |