单片机为AT89S52,P1口接矩阵键盘!
//4X4按键扫描测试!
#include <reg52.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
uint8 code table[]={ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //共阳极数码管扫描吗
uint8 keyvalue[]={1,2,3,12,4,5,6,13,7,8,9,14,10,0,11,15}; //键盘码
uint8 keyset=0; //按键值与按下标志位,第7位为按下标志位
void delay(unsigned int delaynums) //延时函数,测试用
{
for(;delaynums>1;delaynums--);
}
void ledout(unsigned char lednum,unsigned char ledbit) //数码管单位显示函数
{
//lednum是需要显示的数值
//ledbit是显示的位置
if (ledbit<5)
{
P0|=255; //关闭led显示
P1|=15; //关闭led片选
P0=lednum; //led显示数据准备
P1&=~(16>>ledbit); //led片选打开
}
}
uint8 keyboard(uint8 key_value) //根据扫描码返还扫描行或列数
{
uint8 key_line;
if(key_value & 3)
{
if(key_value & 1)
{
key_line = 0;
}
else
{
key_line = 1;
}
}
else
{
if(key_value & 4)
{
key_line = 2;
}
else
{
key_line = 3;
}
}
return key_line;
}
void keyscanning()
{
uint8 key_value,key_line,key_column;
if( P2<240) //按键是否被按下查询
{
if(keyset&128){} //按键按下标志位检查,按下就不再扫描
else //按键标志位未被置位,延时后再次检查按键是否按下
{
delay(10);
if(P2<240)
{
key_value = (~P2)>>4; //高4位扫描码转换
key_line=keyboard(key_value); //返回按键行数值
P2=255; //拉低高4位,准备再次扫描
P2=15;
delay(10);
key_value =~( P2|240); //取出低4位扫描码
key_column=keyboard(key_value); //返回按键列数
P2=255;
P2=240;
keyset=keyvalue[key_line+(key_column<<2)]; //根据行列数值,在数组中取出按键码
keyset |=224; //置位按键按下标志位,
}
}
}
else
{
if(keyset&128) //按键未按下时如果标志位未被置零
{
keyset=keyset-32; //3次扫描后按下标志位置零
}
else
{
keyset=0; //标志位为零时,按键值归零
}
}
}
void main()
{
P2=240;
while(1)
{
keyscanning();
if(keyset&128) //检查按下标志位,如按下则显示键值,未按下数码管关闭
{
ledout(table[keyset&15],1);
}
else
{
P1|=15;
}
delay(100);
}
}
原理图见附件
LY5A-L2A V3.pdf
(37.74 KB, 下载次数: 4)
2012-3-29 22:22 上传
点击文件名下载附件
原理图
百家讲坛:三言二拍 百度影音
一周热门 更多>