80C51按键的应用.docx
- 文档编号:26028100
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:27
- 大小:321.76KB
80C51按键的应用.docx
《80C51按键的应用.docx》由会员分享,可在线阅读,更多相关《80C51按键的应用.docx(27页珍藏版)》请在冰豆网上搜索。
80C51按键的应用
第六节按键的应用
6.1按键简介
同学们!
现在你们已经能熟练的使用数码管了,那么,我们就可以用数码管干些事情了,
先设计个表吧。
调表需要用按键,0K,让我们来练习使用按键…八_。
按键分为编码按键和非编码按键。
如果按键的识别由专门的按键编码器识别并输出特定的键值或编码,这种按键称为编码按键,比如我们计算机的键盘,它内部有一个单片机专门识别按键并输出对应的编码。
如果按键的识别依靠单片机本身来识别,则称为非编码按键。
比如下面这些按键。
A_A
・9
《・•■
图6-1
图6-1是单片机常用的几种按键。
其中弹性小按键一按下,开关就闭合,一松手,开关就会自动断开。
自锁式按键按下时就会闭合并且自动锁定在闭合状态,再次按下时才会弹起
断开,这种按键通常当做电源开关。
6.2独立按键检测的原理
一般情况下,按键与单片机的连接如下面这图6-2所示。
FOTAJPCrs_i■
R:
i2-TJJD2iRj寸
Io.5®
I-A閃
图6-2
图中上拉电阻R1、R2值一般在4.7k~10k之间(对于内部端口有上拉电阻的单片机则可省略此电阻,比如51的P1、P2、P3口),单片机对于按键的按下与否的检测,则是通过检测相应引脚上的电平来实现的。
对于图6-2而言,当单片机检测(读取)到P1.2和P1.3
引脚上面的电平为低时,则表示按键已经按下,反之,则表明按键没有按下。
我们在程序中
只要反复的检测P1.2和P1.3引脚上面的电平,一旦检测到为低了,就可以判断按键按下。
P1.2
呵呵,简单吧。
等会,您先别乐呵,话还没说完呢。
下面我们来看看,当按键按下时,
引脚上面的波形是怎么变化的。
图6-3
图6-3上图是一个理想波形图,当按键按下时,P1.2引脚的电平马上被拉低到0V了。
但是实际上,当按键闭合时,由于按键的机械特性并不能马上保持良好的接触,而是来回弹
跳。
因此,实际的P1.2引脚的波形图是图6-3的下图所示。
尽管抖动的时间很短,我们的手根本感觉不出来。
但是对于一秒钟执行百万条指令的单片机而言,这个时间是相当的长了。
那么在这段抖动的时间内,单片机可能读到多次高低电平的变化。
如果不加任何处理的话,就会认为已经按下,或者松开很多次了。
而事实上,我们的手一直按在按键上,并没有重复
按动很多次。
要想能够正确的判断按键是否按下就要避开这段抖动的时间。
根据一般按键的
机械特点,以及按键的新旧程度等而言,这段抖动的时间一般在5ms~20ms之间。
而一旦按
键按下,稳定闭合的时间一般最短是20ms(手最快的人按下到放开的时间)。
因此,我们通
常需要使用如下的防抖措施:
1•当P1.2检测到按键按下(即P1.2引脚读到低电平)。
2•延时10~20ms。
3•再次检测P1.2按键是否仍被按下(即P1.2引脚依旧读到低电平),如果此时P1.2引
脚仍然能读到低电平,说明按键确实已经稳定的按下了。
4•等待按键被放开。
上述伪代码写成C51代码就应该是这个样子:
sbitBtnAdd=P1A2;//将P1.2引脚重新命名为BtnAdd
if(BtnAdd==O)//当P1.2检测到按键按下(即P1.2引脚读到低电平)
{
Delay(20);//延时20ms。
if(BtnAdd==O)〃再次检测P1.2按键是否仍被按下,如果此时P1.2引脚
〃仍然能读到低电平,说明按键确实已经稳定的按下了
{
while(!
BtnAdd);//等待按键被放开(按键没放开时BtnAdd为低电平(逻辑0),
//取反后为高电平(逻辑1),此时while循环条件为真,
//则继续执行该句,直到按键放开,后面的代码才能被执行)
6.3独立按键的使用
请实现:
一位数码管显示从0~9的数字,使用两个按键“Add”和“Sub”,按一下Add,显示数字加一,按一下Sub,显示数字减一,如显示数字小于0或大于9,显示字符“E”,即“ERROR的简写。
6.3.1硬件的选择与仿真电路的设计
1.打开Proteus,选择“File/NewDesign”菜单选项,新建一个“设计项目”。
并将项目保
存为“PushButton_1”。
2.选择“P”按钮或菜单“Library/PickDivice/Symbol…P”菜单,从“元件库”中选取元件。
依次添加其他元件。
其名称和位置见下表。
元件名称
Category
Sub-Category
Results
单片机
MicroprocessorICs
8051Family
AT89C52
一位7段数码管
Optoelectronics
7-SegmentDisplays
7SEG-MPX1-CA
按钮
Switches&Relays
Switches
BUTTON
电阻
Resistors
Generic
RES
依次从备选元件库中摆放器件,连线,画出仿真电路图,如图6-4所示。
图6-4
电路的说明:
在仿真电路中,由于我们使用的是P1口,它内部已经有上拉电阻了,因此我们可以不再添
加上拉电阻了。
但是,如果您使用的是P0口(内部没有上拉电阻),大家必须添加上拉电
阻,以确保单片机可以准确的检测到按键按下的动作。
632程序的设计
1.新建一个keil项目,并命名为"PushButton_1”并添加一个名为"main.c”的源代码文件,然后键入如下代码。
如代码6.1所示。
//代码6.1
#inelude
#inelude"function.h"
#include"common.h"
#defineSeg7PortP2//数码管连接在P2口上
//用一个数组来定义字符0~9共阳极数码管编码
ucharcodeseg7ca[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
#defineE0x86II用一个字符E来代替字符’E'的共阳极数码管编码(0x86是其编码)
sbitBtnAdd=P1A2;II将P1.2引脚重新命名为BtnAdd(加1按键)sbitBtnSub=P1A3;〃将P1.3引脚重新命名为BtnSub(减1按键)
ucharcount;II定义一个变量来存储当前数码管显示的值
voidmain()
{
count=0;〃数码管将从0开始显示
while
(1)
{
BtnAdd=1;
BtnSub=1;II在读I/O口之前,先要将其置为高电平//如果加1按键按下,则count加1
if(BtnAdd==0)//当P1.2检测到按键按下(即P1.2引脚读到低电平){
Delay(20);II延时20msif(BtnAdd==0)〃再次检测P1.2按键是否仍被按下,如果此时P1.2引脚
〃仍然能读到低电平,说明按键确实已经稳定的按下了
{
while(!
BtnAdd);〃等待按键被放开(按键没放开时BtnAdd为低电平(逻辑0),
〃取反后为高电平(逻辑1),此时while循环条件为真,
〃则继续执行该句,直到按键放开,后面的代码才能被执行)
count++;II加1键被按下,count加1
}
}
elseif(BtnSub==0)//如果减1按键按下则count减1(过程与加1键检测相同){
Delay(20);
if(BtnSub==O)
{
while(!
BtnSub);
count--;//减1键被按下,count减1
}
}
if(count>=0&&count<=9)//如果count在0~9之间,则显示对应的数字
{
Seg7Port=seg7ca[count];
}
else//否则显示字符’E'表示错误
{
Seg7Port=E;
}
}
}
知识点:
I/O口做输入口
当我们要用51单片机的I/O口做输入口(即检测I/O口当前的状态)时,为了正确的读取
I/O口的输入值,我们一般需要先将I/O口置为高电平,如:
BtnAdd=1;
BtnSub=1;//在读I/O口之前,先要将其置为高电平
知识点:
ifelseifelse结构的语义
ifelseifelse判断语句时C常用的判断语句,其语义如下:
if()〃如果
{
}
elseif()//或者(再如果)
{
}
else〃否则
{
}
这三个分支只有一个能发生(即3选1)。
如果你使用
if()
{
}
if()
{
}
那么,这两个分支有可能同时发生(多选)。
请大家注意它们在语义上的区别,在本例中,我们设计时,是不考虑两个按键同时被按下的
情形的,因此,实际是二选一的情况,因此,我们使用了ifelseifelse判断语句。
6.4多位数码管的显示
请实现:
两位数码管显示从00~59的数字,使用两个按键Add和Sub,按一下Add,数
字加一,按一下Sub,数字减一,如此反复。
641硬件的选择与仿真电路的设计
1.打开Proteus,选择"File/NewDesign”菜单选项,新建一个"设计项目”。
并将项目保
存为"PushButton_2”。
2.选择“P”按钮或菜单“Library/PickDivice/Symbol…P”菜单,从“元件库”中选取
元件。
依次添加其他元件。
其名称和位置见下表。
元件名称
Category
Sub-Category
Results
51单片机
MicroprocessorICs
8051Family
AT89C52
两位7段共阳数码管
Optoelectronics
7-SegmentDisplays
7SEG-MPX2-CA
按钮
Switches&Relays
Switches
BUTTON
电阻
Resistors
Generic
RES
依次从备选元件库中摆放器件,连线,画出仿真电路图,如图
6-5所示。
Ul
园0呻m<1从尉n^AW峠Jim刼roaw*4H>SMi4RtfMKA|7M|iT
幷(M
Ba
A.
丄
PlflPI■
F14
K血・0man旧也码KrSAiir-eai-i
nbl•哺
Pilrt"«Ei
rajMi町urnraiffiiFHfc^
图6-5
电路说明
因为我们使用了两位共阳数码管,由于51的驱动能力不足以直接驱动数码管,因此,我们
通过两个PNP三极管作为电子开关来驱动数码管位选线,当P3.0输出低电平时,PNP三极
管导通,Vcc通过三极管Q1加在数码管的个位,从而使数码管的个位发光(P3.1控制数码
管十位发光的原理相同)。
电阻R3和R4为限流电阻,通常取值为1K左右。
电阻R5和R6为下拉电阻,保证PNP三极管可靠地截止,通常取值为10K左右。
642实现原理分析
1.我们使用一个变量count表示当前数值,让count从0开始,每按Add键加1,当count增加到59时,让它回到0,每按Sub键减1,当count减少到0时,让它回到59重新开始。
这样,count就在0~59之间反复变化。
2.我们让数码管的个位显示count的个位,数码管的十位显示count的十位。
6.4.3程序的设计
1.新建一个keil项目,并命名为"PushButton_2”并添加一个名为"main.c”的源代码文件,然后键入如下代码。
如代码6.2所示。
代码6.2
#include
#include"function.h"
#include"common.h"
#defineSeg7PortP2//数码管连接在P2口上
//用一个数组来定义字符0~9共阳极数码管编码
ucharcodeseg7ca[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
sbitBtnAdd=P1A2;//将P1.2引脚重新命名为BtnAdd(加1按键)
sbitBtnSub=P"3;〃将P1.3引脚重新命名为BtnSub(减1按键)
sbitGeWei=P3A0;〃定义数码管个位的位选线
sbitShiWei=P3A1;//定义数码管十位的位选线
ucharcount;〃定义一个变量来存储当前数码管显示的值
//关闭所有的数码管显示
voidCloseAIISeg()
{
GeWei=1;//关闭个位位选线
ShiWei=1;//关闭十位位选线
}
〃在数码管上显示count值
voidDisplay()
{
uchartmp;
CIoseAIISeg();//关闭所有的数码管显示
〃先显示个位
tmp=count%10;〃提取count的个位数
GeWei=0;//先显示个位,将十位关闭
Seg7Port=seg7ca[tmp];//将’count'个位的编码送出
Delay
(1);
CIoseAIISeg();//关闭所有的数码管显示;消隐,防止闪烁
//再显示十位
tmp=count/10;//提取十位数
ShiWei=0;//先显示十位,将个位关闭
Seg7Port=seg7ca[tmp];〃将’count'十位的编码送出DeIay
(1);
CIoseAIISeg();//消隐,防止闪烁
}voidmain()
{
count=0;
while
(1){
BtnAdd=1;
BtnSub=1;//在读I/O口之前,先要将其置为高电平
if(BtnAdd==0){
Delay(20);
if(BtnAdd==0)〃再次检测P1.2按键是否仍被按下,如果此时P1.2引脚
〃仍然能读到低电平,说明按键确实已经稳定的按下了
{
while(!
BtnAdd);//等待按键被放开(按键没放开时BtnAdd为低电平(逻辑0),〃取反后为高电平(逻辑1),此时while循环条件为真,
〃则继续执行该句,直到按键放开,后面的代码才能被执行)
if(count<59)//如果countv59,每按Add键count加1,否则count回0{
count++;
}
else
{
count=0;
}
}
}
elseif(BtnSub==0)//如果减1按键按下则count减1(过程与加1键检测相同){
Delay(20);
if(BtnSub==0){
while(!
BtnSub);
if(count>0)//如果count>0,每按Sub键count减1,否则count回59{
count--;
}
else
{
count=59;
}
}
Display。
;////在数码管上显示count值
}
}
程序代码说明
1•程序结构说明
在本例中,我们的程序设计思路是这样的
在main函数的大循环中,不断的检测BtnAdd和BtnSub是否被按下,如果被按下,则根据
按下的按键修改count值,然后再将count的个位和十位分别显示在数码管上即可。
2•—个数循环变化的技巧
if(count<59)//如果countv59,每按Add键count加1,否则count回0
count++;
else
count=0;
以及下面的代码:
if(count>0)//如果count>0,每按Sub键count减1,否则count回59
count--;
else
count=59;
在让一个数循环变化时,这是一种常用的技巧,后面时钟项目中,我们会使用到这种技
巧(调整时分秒,年月日等等)。
3.Display()函数的使用
因为在main函数的大循环中,我们要不断的将count的个位和十位显示在数码管上,这个
显示操作可以写为一个函数,即Display()函数,这是一种常用的代码复用的技巧。
6.54X4键盘的使用
当我们的应用中要使用比较多的按键时,如果使用独立按键的话,将会占用很多I/O口,
那么,为了节约I/O口线,我们需要使用另一类按键,其中比较常用的是4X4键盘。
让我们实现如下功能:
让1位数码管依次显示4X4键盘的编码(数字键显示对应的数
字,功能键显示对应的A~F字符)。
6.5.14X4键盘实现按键检测的原理分析
一般情况下,4X4键盘与单片机的连接如下面这图6-6所示。
-RBMMImg-nW
HWU
旳恤口
FiWWi
PSTiUJff
Emwfl野沁地哙匹ii#?
4A13'WH;悴昨■
■Kl*f□&
Wl^W.
M±tfT
常鲜■厂
科SO
皤ti?
rrjf.i^-
.S3
r£芒r£C
图6-6
4X4键盘通常有4行4列共16个按钮,分别跨接在4根交叉的行线和列线上,我们通
常把4根行线和4根列线连接在单片机的一个I/O口上,比如像图6-6那样,4根行线连接
在P2.0~P2.3上,4根列线连接在P2.4~P2.7上。
当我们要检测键盘上那个按键被按下,我们通常采用如下方法:
1•我们先拉低P2.0
2•依次检测P2.4~P2.7,如果没有检测到任何低电平,说明没有按键被按下。
检测到有低电平,比如P2.5为低电平,说明P2.0和P2.5交叉的那个按键被按下了。
3•我们再拉低P2.1
4依次检测P2.4~P2.7o(同步骤2)
5•我们再拉低P2.2
6依次检测P2.4~P2.7o(同步骤2)
7•我们再拉低P2.3
8.依次检测P2.4~P2.7o(同步骤2)
9.重复步骤1~8o
上述伪代码写成C51代码就应该是这个样子。
sbitLine_A=P2P;//将4X4键盘的4根行线连接在P2.0~P2.3sbitLine_B=P2A1;
sbitLine_C=P2A2;
sbitLine_D=P2A3;
sbitLine_仁卩2人4;//将4X4键盘的4根列线连接在P2.4~P2.7
sbitLine_2=P2A5;
sbitLine_3=P2A6;
sbitLine_4=P2A7;
Line_A=O;//先拉低P2.0
if(Line1==0)//检测每根列线是否被拉低。
如果没有检测到任何低电平,说明没有按键被按下
{
Delay(10);//消抖
if(Line_仁=0)
{
result=7;〃检测到有低电平,说明P2.0和P2.4交叉的那个按键被按下了,则输出
〃对应的按键的编码(编码自己定)
}
}
elseif(Line_2==0)//检测每根列线是否被拉低。
如果没有检测到任何低电平,说明没有按键被按下
{
Delay(10);//消抖
if(Line_2==0)
{
result=8;〃检测到有低电平,说明P2.0和P2.5交叉的那个按键被按下了,则输出//对应的按键的编码
}
}
elseif(Line_3==0)//检测每根列线是否被拉低。
如果没有检测到任何低电平,说明没有按键被按下
{
Delay(10);//消抖
if(Line_3==0)
{
result=9;〃检测到有低电平,说明P2.o和P2.6交叉的那个按键被按下了,则输出//对应的按键的编码
}
}
elseif(Line_4==0)//检测每根列线是否被拉低。
如果没有检测到任何低电平,说明没有按键被按下
{
Delay(10);//消抖
if(Line_4==0)
{
result=10;//检测到有低电平,说明P2.0和P2.7交叉的那个按键被按下了,则输出〃对应的按键的编码
}
}
〃再依次检测P2.1,P2.2,P2.3
6.5.2硬件电路的设计
1.打开Proteus,选择"File/NewDesign”菜单选项,新建一个"设计项目”。
并将项目保存为“4X4KeyPad'。
2.选择“P”按钮或菜单“Library/PickDivice/Symbol…P”菜单,从“元件库”中选取元件。
依次添加其他元件。
其名称和位置见下表。
元件名称
Category
Sub-Category
Results
51单片机
MicroprocessorICs
8051Family
AT89C52
1位7段共阳数码管
Optoelectronics
7-SegmentDisplays
7SEG-MPX1-CA
4X4键盘
Switches&Relays
KeyPads
KEYPAD-SMALLCA1
电阻
Resistors
Generic
RES
依次从备选元件库中摆放器件,连线,画出仿真电路图,如图6-7所示。
OdlFIH
OEnn
•■•・fll■
图6-7
电路说明
我们使用P2口来驱动一位共阳极数码管,同时使用P3口来检测4X4按键,其中,P3.0~P3.3
引脚连接到行线ABCD上,P3.4~P3.7连接到列线1234上。
6.5.3程序的设计
1.新建一个keil项目,并命名为"4X4Key”并添加一个名为"main.c”的源代码文件,然后键入如下代码。
如代码6.3所示。
〃代码6.3
#include
#include"function.h"
#include"common.h"
#defineSeg7PortP2//数码管连接在P2口上
#defineKeyPadP3//键盘连接在P3口上
sbitLine_A=P3P;//将4X4键盘的4根行线连接在P3.0~P3.3
sbitLine_B=P3A1;
sbitLine_C=P3A2;
sbitLine_D=P3A3;
sbitLine_仁卩3人4;//将4X4键盘的4根列线连接在P3.4~P3.7
sbitLine_2=P3A5;
sbitLine_3=P3A6;
sbitLine_4=P3A7;
〃用一个数组来定义字符0~F共阳极数码管编码
ucharcodeseg7ca[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
ucharcount;〃定义一个变量来存储当前数码管显示的值
//键盘扫描程序
ucharScanKeypad
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 80 C51 按键 应用