实现功能:
按下按键时,数码管动态显示 ‘ 键值-扫描值 ’
按键松开时,数码管动态显示 ‘ 0-00 ’
#include
#include
#define LED_port XBYTE[0XFDFF]//A9
#define uint unsigned int
#define uchar unsigned char
uchar line, row, kvalue, kscan, kscanA, kscanB;
// 共阴极数码表
uchar dispcode[] =
{0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71,
0x40}; //最后一个为实现视觉效果‘键值-扫描值’而设置只有g亮
void delay1ms(uchar n)
{
uint t = n * 1000;
TMOD = 0x01;
TH0 = (65536 - t) / 256;
TL0 = (65536 - t) % 256;
TR0 = 1;
while (TF0 != 1)
{
/* code */
}
TF0 = 1;
}
/*矩阵按键函数开始*/
// 行列反转法
uchar keyRowLine()
{
P1 = 0x0f;
line = P1;
if (line != 0x0f)
{
/* 判断行状态 */
delay1ms(20);
line = P1;
if (line != 0x0f)
{
/* 有按键按下 */
line = line & 0x0f;
P1 = 0xf0;
delay1ms(1); //等待变化时间
row = P1;
row = row & 0xf0;
kscan = line | row;
return kscan;
}
}
return 0xff;
}
// 获得键编码
void getKeyVaule()
{
uchar Kscan;
Kscan = keyRowLine();
switch (Kscan)
{
case 0xee:
kvalue = 0;
kscanA = 14;
kscanB = 14;
break;
case 0xde:
kvalue = 1;
kscanA = 13;
kscanB = 14;
break;
case 0xbe:
kvalue = 2;
kscanA = 11;
kscanB = 14;
break;
case 0x7e:
kvalue = 3;
kscanA = 7;
kscanB = 14;
break;
case 0xed:
kvalue = 4;
kscanA = 14;
kscanB = 13;
break;
case 0xdd:
kvalue = 5;
kscanA = 13;
kscanB = 13;
break;
case 0xbd:
kvalue = 6;
kscanA = 11;
kscanB = 13;
break;
case 0x7d:
kvalue = 7;
kscanA = 7;
kscanB = 13;
break;
case 0xeb:
kvalue = 8;
kscanA = 14;
kscanB = 11;
break;
case 0xdb:
kvalue = 9;
kscanA = 13;
kscanB = 11;
break;
case 0xbb:
kvalue = 10;
kscanA = 11;
kscanB = 11;
break;
case 0x7b:
kvalue = 11;
kscanA = 7;
kscanB = 11;
break;
case 0xe7:
kvalue = 12;
kscanA = 14;
kscanB = 7;
break;
case 0xd7:
kvalue = 13;
kscanA = 13;
kscanB = 7;
break;
case 0xb7:
kvalue = 14;
kscanA = 11;
kscanB = 7;
break;
case 0x77:
kvalue = 15;
kscanA = 7;
kscanB = 7;
break;
default:
kvalue = 0;
kscanA = 0;
kscanB = 0;
break;
}
}
/*矩阵按键函数结束*/
// 主函数
void main()
{
while (1)
{
getKeyVaule();
P3 = 0Xff; //消隐
LED_port = dispcode[kvalue];
P3 = 0Xfe;
delay1ms(5);
P3 = 0Xff; //消隐
LED_port = dispcode[16];
P3 = 0Xfd;
delay1ms(5);
P3 = 0Xff; //消隐
LED_port = dispcode[kscanA];
P3 = 0Xfb;
delay1ms(5);
P3 = 0Xff; //消隐
LED_port = dispcode[kscanB];
P3 = 0Xf7;
delay1ms(5);
}
}
使用中断方式
#include
#include
#define LED_port XBYTE[0XFDFF] //A9
#define uint unsigned int
#define uchar unsigned char
uchar line, row, kvalue, kscan, kscanA, kscanB;
uchar dat[4] = {0, 0, 0, 0};
uchar led_active = 0;
// 共阴极数码表
uchar dispcode[] =
{0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07,
0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71,
0x40}; //最后一个为实现视觉效果‘键值-扫描值’而设置只有g亮
void delay1ms(uchar n)
{
uint t = n * 1000;
TH0 = (65536 - t) / 256;
TL0 = (65536 - t) % 256;
TR0 = 1;
while (TF0 != 1)
{
/* code */
}
TF0 = 1;
}
/*矩阵按键函数开始*/
// 行列反转法
uchar keyRowLine()
{
P1 = 0x0f;
line = P1;
if (line != 0x0f)
{
/* 判断行状态 */
delay1ms(20);
line = P1;
if (line != 0x0f)
{
/* 有按键按下 */
line = line & 0x0f;
P1 = 0xf0;
delay1ms(1); //等待变化时间
row = P1;
row = row & 0xf0;
kscan = line | row;
return kscan;
}
}
return 0xff;
}
// 获得键编码
void getKeyVaule()
{
uchar Kscan;
Kscan = keyRowLine();
switch (Kscan)
{
case 0xee:
kvalue = 0;
kscanA = 14;
kscanB = 14;
break;
case 0xde:
kvalue = 1;
kscanA = 13;
kscanB = 14;
break;
case 0xbe:
kvalue = 2;
kscanA = 11;
kscanB = 14;
break;
case 0x7e:
kvalue = 3;
kscanA = 7;
kscanB = 14;
break;
case 0xed:
kvalue = 4;
kscanA = 14;
kscanB = 13;
break;
case 0xdd:
kvalue = 5;
kscanA = 13;
kscanB = 13;
break;
case 0xbd:
kvalue = 6;
kscanA = 11;
kscanB = 13;
break;
case 0x7d:
kvalue = 7;
kscanA = 7;
kscanB = 13;
break;
case 0xeb:
kvalue = 8;
kscanA = 14;
kscanB = 11;
break;
case 0xdb:
kvalue = 9;
kscanA = 13;
kscanB = 11;
break;
case 0xbb:
kvalue = 10;
kscanA = 11;
kscanB = 11;
break;
case 0x7b:
kvalue = 11;
kscanA = 7;
kscanB = 11;
break;
case 0xe7:
kvalue = 12;
kscanA = 14;
kscanB = 7;
break;
case 0xd7:
kvalue = 13;
kscanA = 13;
kscanB = 7;
break;
case 0xb7:
kvalue = 14;
kscanA = 11;
kscanB = 7;
break;
case 0x77:
kvalue = 15;
kscanA = 7;
kscanB = 7;
break;
default:
kvalue = 0;
kscanA = 0;
kscanB = 0;
break;
}
/*swich语句太长,改进一下,建议换成下面语句:
for ( i = 0; i < 16; i++)
{
if (Kscan==dispcode[i])
{
kvalue=i;
}
}
kscanA=Kscan>>4;
kscanB=Kscan&0x0f;
swich语句太长,改进一下*/
dat[0] = kvalue;
dat[1] = 16;
dat[2] = kscanA;
dat[3] = kscanB;
}
/*矩阵按键函数结束*/
// 主函数
void main()
{
TMOD = 0x11;
TH1 = (65536 - 5000) / 256;
TL1 = (65536 - 5000) % 256;
EA = 1;
ET1 = 1;
TR1 = 1;
while (1)
{
getKeyVaule();
}
}
void TIMER1() interrupt 3
{
TR1 = 0;
TH1 = (65536 - 5000) / 256;
TL1 = (65536 - 5000) % 256;
// getKeyVaule(); 该函数内部有延时,违背中断的设计,不推荐在中断内部使用
P3 = P3 | 15; //消隐
LED_port = dispcode[dat[led_active]];
P3 = ~(1 << led_active);
led_active++;
if (led_active >= 4)
{
led_active = 0;
}
TR1 = 1;
}