||
//小菜出品---严禁抄袭,转载请注明出处
#include <reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar idata x,y;
uchar code disp_code[] =
{
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90,
// 0-9 0 1 2 3 4 5 6 7 8 9
0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,
// 10-15 a b c d e f
0x7F, 0xBF, 0x9C, 0xFF
// 16-19 . - 。null
}; //数码管显示值列表
void delay(uchar c) //延时函数
{
char a,b;
for(a=c;a>0;a--)
for(b=110;b>0;b--);
}
uchar key_scan() //键盘扫描函数
{
uchar k;
uchar z;
x=0x00;
y=0x00;
P3=0xf0; //先给P3赋一个初值
if(P3!=0xf0) //判断P3不等于所赋初值,说明有健按下
{
delay(10); //消除键盘抖动 延时10ms
if(P3!=0xf0)
{
x=P3; /*这里稍作解释:起初我们已经给P3赋了一个0xf0的值,如果有键按下,P3便一定不再是0xf0 ,
如果我们这时查看P3的值我们就能知道是哪一列的键按下了(说明一下,我的开发板上P3.0-P3.3接的是列)
但这时我们先不看P3的值,这时我们先把P3的值赋给x,再给P3赋一个0x0f的值,由于这两条语句执行的速度是
很快的,是us级的,而我们按一个按键怎么也得几十到上百ms,尽管我们在前面已经做过一个10ms的延时,但是
在我们给P3重新赋值后,按键一定还是闭合的,所以P3被赋0xof后由于有按键闭合,故P3的值又变了,这时候我们
查看P3的值就可以判断出来是是哪一行的按键按下了.然后我们把这时的P3值赋给y,再用x或上y,把他们的值赋给z
然后判断z的值就可以知道是具体哪一个键被按下了!(行和列都确定了,具体是哪一个键自然就确定了) */
P3=0x0f;
y=P3;
z=x|y;
switch(z)
{
case 0xee: k=0; break;
case 0xed: k=1; break;
case 0xeb: k=2; break;
case 0xe7: k=3; break;
case 0xde: k=4; break;
case 0xdd: k=5; break;
case 0xdb: k=6; break;
case 0xd7: k=7; break;
case 0xbe: k=8; break;
case 0xbd: k=9; break;
case 0xbb: k=10;break;
case 0xb7: k=11;break;
case 0x7e: k=12;break;
case 0x7d: k=13;break;
case 0x7b: k=14;break;
case 0x77: k=15;break;
}
}
}
return(k);
}
void main()
{
uchar dat;
while(1)
{
P3=0xf0;
while(P3!=0xf0) /*刚开始运行程序就判断有没有按键按下,如果有在进入扫描程序,如果没有这个判断语句
单片机一上电,数码管就会显示0,因为k的初值是0(尽管我们没有给k赋初值)扫描函数
的返回值也就是0。 */
{
dat=key_scan();
P1=0;
P0=disp_code[dat];
}
}
}
我感觉一般初学者会有疑问的地方 已经做出了详细的解释
如果还有弄不明白的地方 可以回帖提问 我会尽量做出解答
以期共同进步