导航:首页 > 编程语言 > 基于扫描法的键盘led显示接口程序

基于扫描法的键盘led显示接口程序

发布时间:2025-06-21 08:50:39

⑴ 单片机汇编矩阵键盘实验(扫描法)

关于扫描按键的原理,可以看下面这篇文章。

本文以循序渐进的思路,引导大家思考如何用最少的IO驱动更多的按键,并依次给出5种方案原理图提供参考。在实际项目中我们经常会遇到有按键输入的需求,但有的时候为了节省资源成本,我们都会选择在不增加硬件的情况下使用最少的控制器IO驱动更多的按键,那么具体是怎么做的呢,下面我们就以用5个IO引脚为例,讲下怎么设计可以实现更多的按键?共有5种设计思路,下面依次介绍。

思路一

首先通常想到的可能是下面这样的设计:

这样我们可以先识别K01、K02、K03、K04、K05,若没有按键按下然后再和思路四的设计一样去识别其他按键。但这样存在一个问题,如果IO1配置为0,IO5读到0,那么怎么知道是K51按下还是K05按下呢,这里只需要在程序里做下判断,先判断下是不是K05按下,若不是就是K51,因为按键K01、K02、K03、K04、K05在5个IO口都为读取的情况下,就可以识别,不需要扫描识别处理,相当于这5个按键优先级高与其他按键。

总结

综合上述,5个IO口最多可以识别25个按键,思路五程序上处理比较麻烦,若实际中只按思路四设计,也可识别20个按键,那么如果有N个IO口可识别多少按键呢?这里给出如下公式:

假设有N个IO口按照思路三可以识别N*(N-1)/2个;

按照思路四可识别N*(N-1)个;

按照思路5可以识别N*(N-1)+N个。

最后再说下,如果实际设计时,还是按思路四设计好,软件也没那么麻烦。如果是你的话你会选择哪种方法呢?你还有没有其他的设计方法呢?

⑵ C51 4*4键盘扫描程序(c语言)

|代码
字符
代码
字符
代码
字符
代码
字符
代码
字符

32

52
4
72
H
92
\
112
p

33
!
53
5
73
I
93
]
113
q

34

54
6
74
J
94
^
114
r

35
#
55
7
75
K
95
_
115
s

36
$
56
8
76
L
96
`
116
t

37
%
57
9
77
M
97
a
117
u

38
&
58
:
78
N
98
b
118
v

39

59
;
79
O
99
c
119
w

40
(
60
<
80
P
100
d
120
x

41
)
61
=
81
Q
101
e
121
y

42
*
62
>
82
R
102
f
122
z

43
+
63
?
83
S
103
g
123
{

44
,
64
@
84
T
104
h
124
|

45
-
65
A
85
U
105
i
125
}

46
.
66
B
86
V
106
j
126
~版

47
/
67
C
87
W
107
k

48
0
68
D
88
X
108
l

49
1
69
E
89
Y
109
m

50
2
70
F
90
Z
110
n

51
3
71
G
91
[
111
o

对照相应的ASCII码输出权就可以了

⑶ 键盘扫描程序的调试方法是什么

逐行扫描法。改进后键盘扫描 接下来我们介绍一种代码效率极高的键盘扫描方法。键盘接口电路同样采用独立式,假设有8个按键,所有按键公共端接地,键盘扫描口为P0.7~P0.0。

⑷ 急求一个由89C51单片机的代码!要求用4*4矩阵键盘控制LED矩阵输出0~9的数字!

/*
分别按下4×4键盘的按键,显示0~16键值

*/
#include<reg51.h>
sbit speaker=P3^;
/////////////////键盘
sbit v1=P2^0;
sbit v2=P2^1;
sbit v3=P2^2;
sbit v4=P2^3;

sbit h1=P2^4;
sbit h2=P2^5;
sbit h3=P2^6;
sbit h4=P2^7;

/////////////////显示
sbit shu1=P1^3;/*第1位数码管共阴端*/
sbit shu2=P1^2;/*第2位数码管共阴端*/
sbit shu3=P1^1;/*第3位数码管共阴端*/
sbit shu4=P1^0;/*第4位数码管共阴端*/

////////////////
void delayms(unsigned int i);

unsigned char yima[]={0xeb,0x88,0xb3,0xba,0xd8,0x7a,0x7b,0xa8,0xfb,0xfa};/*译码表,此表数据和硬件相关*/
unsigned int b=0;/*要显示的数据*/
unsigned int b_count=0;/*扫描次数*/

void delayms(unsigned int i);
unsigned int keyboar();

unsigned int b;

void t0()interrupt 1 using 1 /*中断程序负责显示b的值 */
{
unsigned char a1=0,a2=0,a3=0,a4=0;

static int k=0;
/*数码管扫描显示*/
a1=b/1000;/*取b的千位*/
a2=b%1000/100;/*取b的百位*/
a3=b%100/10;/*取b的十位*/
a4=b%10;/*取b的个位*/
if(k==0){shu4=1;shu1=0;shu2=0;shu3=0;P0=yima[a1];}
else if(k==1){shu4=0;shu1=1;shu2=0;shu3=0;P0=yima[a4];}
else if(k==2){shu4=0;shu1=0;shu2=1;shu3=0;P0=yima[a3];}
else if(k==3){shu4=0;shu1=0;shu2=0;shu3=1;P0=yima[a2];}
k++;
if(k>3)k=0;

TH0=240;
}

main()
{

EA=1;/*开全局中断 */
TR0=1;/*定时器0开始计数 */
ET0=1;/*定时器0开中断 */
TMOD=0X01;/*定时器0工作在方式1:16位计数模式 */

while(1)
{
b= keyboar(); /*把按键的代表的值给b */
}

}

void delayms(unsigned int i)
{
unsigned int j;
for(;i>0;i--)
for(j=100;j>0;j--);
}
//////////////////////////////////////////////////////////////////////////////////
//扫描法:逐行扫描查询 一般用在按键比较少的场合
int keyscan()
{
unsigned char k k_temp;
P1=0xf0; //低位置0,准备查询按键
k=P1; //取得当前P1口状态
if(k!=0xf0) //如果有变化则表示有按键按下
{
delay(10); //延迟 消抖
k_temp=p1;
if(k==k_temp) //确实有键按下
{
k=0xfe;
do //循环扫描每一行
{
p1=k;
if(k!=p1)
{
switch(P1) //判断按键 并返回键值
{
//第1行
case 0x7e:{return 0; break;}
case 0xbe:{return 1; break;}
case 0xde:{return 2; break;}
case 0xee:{return 3; break;}
//第2行
case 0x7d:{return 4; break;}
case 0xbd:{return 5; break;}
case 0xdd:{return 6; break;}
case 0xed:{return 7; break;}
//第3行
case 0x7b:{return 8; break;}
case 0xbb:{return 9; break;}
case 0xdb:{return 10;break;}
case 0xeb:{return 11;break;}
//第4行
case 0x77:{return 12;break;}
case 0xb7:{return 13;break;}
case 0xd7:{return 14;break;}
case 0xe7:{return 15;break;}
}
}
k=_crol_(k,1); //移位 进入下一行扫描
}
while(k!=0xef); //超过列范围 退出扫描
}
}
}
////////////////////////////////////////////////////////////////////////////////
//线反转法 :只需2步便可获得按键位置,最常用
unsigned int keyboar()/*线反转法 */
{
static unsigned int a=0;
unsigned char a1=0,b1=0;
/*行线为输入线,列线为输出线 */
v1=v2=v3=v4=0;
h1=h2=h3=h4=1;
if(P2<0xf0)/*检查行是否有按键按下 */
{
delayms(10);
if(P2<0xf0)
{
/*行线为输入线,列线为输出线 */
v1=v2=v3=v4=0;
h1=h2=h3=h4=1;
a1=P2;
/*行线为输出线,列线为输入线 */
h1=h2=h3=h4=0;
v1=v2=v3=v4=1;
b1=P2;

a=a1|b1;
}
}
if (a==0xe7) { return 7; }
else if(a==0xeb) { return 8; }
else if(a==0xed) { return 9; }
else if(a==0xee) { return 13;}

else if(a==0xd7) {return 4; }
else if(a==0xdb) {return 5; }
else if(a==0xdd) {return 6; }
else if(a==0xde) {return 12;}

else if(a==0xb7) {return 1; }
else if(a==0xbb) {return 2; }
else if(a==0xbd) {return 3; }
else if(a==0xbe) {return 11;}

else if(a==0x77) {return 0; }
else if(a==0x7b) {return 15;}
else if(a==0x7d) {return 16;}
else if(a==0x7e) {return 10;}

else return 17;
}

/*******************************************
流水灯写法1
while(1)
{
a=0x01; //赋初值00000001
for(i=0;i<8;i++) //循环8次
{
P0=a;
delay(500);
a=a<<1; //左移1位
}
}

流水灯写法2:
a=0x01; //赋初值00000001
while(1)
{
P0=a; //先点亮第1个led
delay(500);
a=_crol_(a,1); //将a循环左移1位后再赋给a
}

流水灯写法3:
while(1)
{
a=0x01; //赋初值00000001
for(i=0;i<7;i++)
{
P0=a;
delay(500);
a=a<<1; //左移
}
for(i=0;i<7;i++)
{
P0=a;
delay(500);
a=a>>1; //右移
}
}

写法3:
void t0() interrupt 1 //中断服务函数
{
TH0=(65536-50000)/256; //计数寄存器高8位重新载入
TL0=(65536-50000)%256; //计数寄存器低8位重新载入
num++;
if(num>=10) //500ms 调整流水速度
{
num=0;
P0=1<<i; //进入位移操作,熄灭相对应位的LED P0=1然后P0右移i位
i++;
if(i>7) i=0;
}
}

阅读全文

与基于扫描法的键盘led显示接口程序相关的资料

热点内容
cad文件转化eps 浏览:528
凯立德升级替换哪些文件 浏览:75
pdf打印文件变大 浏览:31
无线配置文件格式 浏览:289
英雄杀最老的版本下载地址 浏览:953
无法打开pdf结尾文件 浏览:809
魔法现金贷款app 浏览:74
足球必发数据哪里有 浏览:107
民生银行的全民生活app是什么 浏览:671
加工中心侧铣头铣腰槽怎么编程 浏览:38
java获取http请求头 浏览:822
qq邮箱登陆不上 浏览:292
女装有哪些购买的app 浏览:855
新基建的大数据带来了哪些新需求 浏览:296
js传递参数给servlet 浏览:587
跨网跨域交换数据什么意思 浏览:244
计算机中文件的名称由哪些构成 浏览:270
基于扫描法的键盘led显示接口程序 浏览:153
网络金融安全吗 浏览:332
u盘文件拷贝过程中丢了 浏览:32

友情链接