[code]/***************************************************************
江西理工大学3+1创新教育实验班单片机矩阵扫描键盘程序
**程序作者:朱兆祺(宁静致远)
**程序时间:2011年3月22日
**程序版本:单片机矩阵扫描键盘程序1.0版
**运行环境:TKS
****************************************************************/
#include"config.h"
#include"Port.h"
//宏定义
#define uchar unsigned char
#define uint unsigned int
//键盘行列的变量
//x表示键盘的行
//y表示键盘的列
uchar idata x,y;
//数码管显示值列表
uchar code disp_code[] =
{
// 黑码、1-9 1 2 3 4 5 6 7 8 9
0xFF,0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90,
//点,0,H . 0 H
//这里用 . 代替 * ,用 H 代替 #
0x7F,0xC0, 0x89
};
/*****************************************************************
**函数名称:delay()
**函数功能:软件延时
**入口参数:uchar c
**出口参数:无
****************************************************************/
void delay(uchar c)
{
char a,b;
for(a=c;a>0;a--)
for(b=110;b>0;b--);
}
/*****************************************************************
**函数名称:key_scan()
**函数功能:键盘扫描函数
**入口参数:
**出口参数:k
****************************************************************/
uchar key_scan()
{
uchar k;
uchar z;
x=0x00;
y=0x00;
P2=0xf0; //先给P2赋一个初值
//P2的高四位
if(P2!=0xf0) //判断P2不等于所赋初值,说明有健按下
{
delay(10); //消除键盘抖动 延时10ms
if(P2!=0xf0) //如果P2此时改变就说明有按键按下
{
y=P2; //把P2的值赋给列y
P2=0x0f; //P2的低四位
/*这里稍作解释:起初我们已经给P2赋了一个0xf0的值,如果有键按下,P2便一定不再是0xf0
如果我们这时查看P2的值我们就能知道是哪一列的键按下了(说明一下,我的C51单片机上P2.0-P2.3接的是行)
但这时我们先不看P2的值,这时我们先把P2的值赋给y,再给P2赋一个0x0f的值,由于这两条语句执行的速度是
很快的,是us级的,而我们按一个按键怎么也得几十到上百ms,尽管我们在前面已经做过一个10ms的延时,但是
在我们给P2重新赋值后,按键一定还是闭合的,所以P2被赋0x0f后由于有按键闭合,故P2的值又变了,这时候我们
查看P2的值就可以判断出来是是哪一行的按键按下了.然后我们把这时的P2值赋给x,再用x或上y,把他们的值赋给z
然后判断z的值就可以知道是具体哪一个键被按下了!(行和列都确定了,具体是哪一个键自然就确定了) */
x=P2;
z=x|y;
switch(z)
{
case 0xee: k=1; break;
case 0xde: k=2; break;
case 0xbe: k=3; break;
case 0xed: k=4; break;
case 0xdd: k=5; break;
case 0xbd: k=6; break;
case 0xeb: k=7; break;
case 0xdb: k=8; break;
case 0xbb: k=9;break;
case 0xe7: k=10; break;
case 0xd7: k=11; break;
case 0xb7: k=12;break;
}
}
}
return(k);
}
/*****************************************************************
**函数名称:main
**函数功能:主函数
**入口参数:
**出口参数:
****************************************************************/
void main()
{
uchar dat;
while(1)
{
P2=0xf0;
while(P2!=0xf0) /*刚开始运行程序就判断有没有按键按下,如果有在进入扫描程序,如果没有这个判断语句
单片机一上电,数码管就会显示0,因为k的初值是0(尽管我们没有给k赋初值)扫描函数
的返回值也就是0。 */
{
dat=key_scan();
P0=disp_code[dat];
}
}
}