原标题:键盘: 基于STC89C52的键盘设计详解
一. 硬件设计详解
说明:
1. 独立键盘部分
S2~S5为4个独立键盘, 与 的P3.4~P3.7分别相连
2. 矩阵键盘部分
S6~S21为16个矩阵键盘,8条线分别与单片机的P3口相连, 其中矩阵键盘的4行分别与单片机的P3.0~P3.3相连,矩阵键盘的4列分别与单片机的P3.4~P3.7相连.
二. 程序设计详解
1. 用数码管的前两位显示一个十进制数,变化范围为00-59.
程序功能:
用数码管的前两位显示一个十进制数,变化范围为00-59,开始时显示00,每按下S2键一次,数值加1;每按下S3键一次,数值减1;每按下S4键一次,数值归零;按下S5键一次,利用定时器功能使数值开始每秒加1,再次按下S5键,数值停止自动加1,保持原数.
程序源码:
#include
#define uchar unsigned char
#define uint unsigned int
sbit key1 = P3 ^ 4;
sbit key2 = P3 ^ 5;
sbit key3 = P3 ^ 6;
sbit key4 = P3 ^ 7;
sbit dula = P2 ^ 6;
sbit wela = P2 ^ 7;
uchar code table[] = {
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
void init();
void keyscan();
void display(uchar);
void delayms(uint);
uchar t0, num;
void main()
{
init();
while (1)
{
keyscan();
display(num);
}
}
void init()
{
TMOD = 0x01;
TH0 = (65536 - 45872) / 256;
TL0 = (65536 - 45872) % 256;
EA = 1;
ET0 = 1;
}
void keyscan()
{
if (key1 == 0)
{
delayms(10);
if (key1 == 0)
{
if (num == 60)
num = 0;
num++;
while (!key1)
display(num);
}
}
if (key2 == 0)
{
delayms(10);
if (key2 == 0)
{
if (num == 0)
num = 60;
num--;
while (!key2)
display(num);
}
}
if (key3 == 0)
{
delayms(10);
if (key3 == 0)
{
num = 0;
while (!key3)
display(num);
}
}
if (key4 == 0)
{
delayms(10);
if (key4 == 0)
{
TR0 = ~TR0;
while (!key4)
display(num);
}
}
}
void display(uchar numDis)
{
dula = 1;
P0 = table[numDis / 10];
dula = 0;
P0 = 0xff;
wela = 1;
P0 = 0xfe;
wela = 0;
delayms(5);
dula = 1;
P0 = table[numDis % 10];
dula = 0;
P0 = 0xff;
wela = 1;
P0 = 0xfd;
wela = 0;
delayms(5);
}
void delayms(uint xms)
{
uint i, j;
for (i = xms; i > 0; i--)
for (j = 110; j > 0; j--)
;
}
void T0_timer() interrupt 1
{
TH0 = (65536 - 45872) / 256;
TL0 = (65536 - 45872) % 256;
t0++;
if (t0 == 20)
{
t0 = 0;
num++;
if (num == 60)
num = 0;
}
}
程序小结:
a. 键盘按键检测需要做两次 (每个键盘按键用了两个if)
b. 键盘按键退出也需要检测 (每次按键退出用了一个while(!key))
c. 这段程序包含按键加1,按键减1,按键归零,按键开始计数,再按停止计数
2. 按矩阵键盘,在数码管上显示0~F,6个数码管同时静态显示即可.
程序功能
上电不显示, 按矩阵键盘,在数码管上显示0~F,6个数码管同时静态显示即可.
程序源码
#include
#define uchar unsigned char
#define uint unsigned int
sbit dula = P2 ^ 6;
sbit wela = P2 ^ 7;
uchar code table[] = {
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
void delayms(uint);
void display(uchar);
void matrixkeyscan();
void main()
{
dula = 1;
P0 = 0;
dula = 0;
wela = 1;
P0 = 0xc0;
wela = 0;
while (1)
{
matrixkeyscan();
}
}
void delayms(uint xms)
{
uint i, j;
for (i = xms; i > 0; i--)
for (j = 110; j > 0; j--)
;
}
void display(uchar num)
{
dula = 1;
P0 = table[num];
dula = 0;
}
void matrixkeyscan()
{
uchar temp, key;
P3 = 0xfe;
temp = P3;
temp = temp & 0xf0;
if (temp != 0xf0)
{
delayms(10);
temp = P3;
temp = temp & 0xf0;
if (temp != 0xf0)
{
temp = P3;
switch(temp)
{
case 0xee:
key = 0;
break;
case 0xde:
key = 1;
break;
case 0xbe:
key = 2;
break;
case 0x7e:
key = 3;
break;
}
while (temp != 0xf0)
{
temp = P3;
temp = temp & 0xf0;
}
display(key);
}
}
P3 = 0xfd;
temp = P3;
temp = temp & 0xf0;
if (temp != 0xf0)
{
delayms(10);
temp = P3;
temp = temp & 0xf0;
if (temp != 0xf0)
{
temp = P3;
switch(temp)
{
case 0xed:
key = 4;
break;
case 0xdd:
key = 5;
break;
case 0xbd:
key = 6;
break;
case 0x7d:
key = 7;
break;
}
while (temp != 0xf0)
{
temp = P3;
temp = temp & 0xf0;
}
display(key);
}
}
P3 = 0xfb;
temp = P3;
temp = temp & 0xf0;
if (temp != 0xf0)
{
delayms(10);
temp = P3;
temp = temp & 0xf0;
if (temp != 0xf0)
{
temp = P3;
switch(temp)
{
case 0xeb:
key = 8;
break;
case 0xdb:
key = 9;
break;
case 0xbb:
key = 10;
break;
case 0x7b:
key = 11;
break;
}
while (temp != 0xf0)
{
temp = P3;
temp = temp & 0xf0;
}
display(key);
}
}
P3 = 0xf7;
temp = P3;
temp = temp & 0xf0;
if (temp != 0xf0)
{
delayms(10);
temp = P3;
temp = temp & 0xf0;
if (temp != 0xf0)
{
temp = P3;
switch(temp)
{
case 0xe7:
key = 12;
break;
case 0xd7:
key = 13;
break;
case 0xb7:
key = 14;
break;
case 0x77:
key = 15;
break;
}
while (temp != 0xf0)
{
temp = P3;
temp = temp & 0xf0;
}
display(key);
}
}
}
程序小结
a. 先送行线低电平,检测列线信号
b. 通过延时来消抖
c. 需要检查释放
3. 数码管前三位显示一个跑表,从000到999之间以1%秒速度运行
程序功能
当按下一个独立键盘时跑表停止,松开手后跑表继续运行。用定时器设计表。
程序源码
#include
#define uint unsigned int
#define uchar unsigned char
sbit dula = P2 ^ 6;
sbit wela = P2 ^ 7;
sbit s2 = P3 ^ 4;
uchar code table[] = {
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71,
0x76,0x79,0x38,0x3f,0
};
uchar flag, t0, bai, shi, ge;
uint shu;
void init();
void display(uchar aa, uchar bb, uchar cc);
void delayms(uint);
void main()
{
init();
while (1)
{
display(bai, shi, ge);
if (s2 == 0)
{
delayms(10);
if (s2 == 0)
{
TR0 = 0;
while (!s2)
display(bai, shi, ge);
TR0 = 1;
}
}
}
}
void init()
{
TMOD = 0x01;
TH0 = (65536 - 10000) / 256;
TL0 = (65536 - 10000) % 256;
EA = 1;
ET0 = 1;
TR0 = 1;
}
void T0_timer() interrupt 1
{
TH0 = (65536 - 10000) / 256;
TL0 = (65536 - 10000) % 256;
责任编辑: