80C51按键的应用_第1页
80C51按键的应用_第2页
80C51按键的应用_第3页
80C51按键的应用_第4页
80C51按键的应用_第5页
已阅读5页,还剩23页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、第六节按键的应用6.1按键简介同学们!现在你们已经能熟练的使用数码管了,那么,我们就可以用数码管干些事情了,先设计个表吧。调表需要用按键,0K,让我们来练习使用按键 八_ 。按键分为编码按键和非编码按键。如果按键的识别由专门的按键编码器识别并输出特定 的键值或编码,这种按键称为编码按键, 比如我们计算机的键盘, 它内部有一个单片机专门 识别按键并输出对应的编码。如果按键的识别依靠单片机本身来识别,则称为非编码按键。 比如下面这些按键。A_A9 图6-1图6-1是单片机常用的几种按键。其中弹性小按键一按下,开关就闭合,一松手,开关 就会自动断开。自锁式按键按下时就会闭合并且自动锁定在闭合状态,再

2、次按下时才会弹起断开,这种按键通常当做电源开关。6.2独立按键检测的原理一般情况下,按键与单片机的连接如下面这图6-2所示。FO TAJPC rs_i R:i 2-TJJD2 iRj 寸I o . 5®I - A 閃!PUD Pt i H J pi a Is!Pr £ H Pi 7-1ECT-p; w. p: 11*1 K! n.wii F3.JA11 P3_Wk1PlowTrfjmtciPlTfij-JJJJ.亠图6-2图中上拉电阻R1、R2值一般在4.7k10k之间(对于内部端口有上拉电阻的单片机则 可省略此电阻,比如 51的P1、P2、P3 口),单片机对于按键的按下

3、与否的检测,则是通过 检测相应引脚上的电平来实现的。对于图6-2而言,当单片机检测(读取)到 P1.2和P1.3引脚上面的电平为低时,则表示按键已经按下,反之,则表明按键没有按下。我们在程序中只要反复的检测 P1.2和P1.3引脚上面的电平,一旦检测到为低了,就可以判断按键按下。P1.2呵呵,简单吧。等会,您先别乐呵,话还没说完呢。下面我们来看看,当按键按下时,引脚上面的波形是怎么变化的。逹出Mr:图6-3图6-3上图是一个理想波形图,当按键按下时,P1.2引脚的电平马上被拉低到0V 了。但是实际上,当按键闭合时,由于按键的机械特性并不能马上保持良好的接触,而是来回弹跳。因此,实际的 P1.2

4、引脚的波形图是图 6-3的下图所示。尽管抖动的时间很短,我们的 手根本感觉不出来。但是对于一秒钟执行百万条指令的单片机而言,这个时间是相当的长了。那么在这段抖动的时间内,单片机可能读到多次高低电平的变化。如果不加任何处理的话, 就会认为已经按下,或者松开很多次了。而事实上,我们的手一直按在按键上,并没有重复按动很多次。要想能够正确的判断按键是否按下就要避开这段抖动的时间。根据一般按键的机械特点,以及按键的新旧程度等而言,这段抖动的时间一般在5ms20ms之间。而一旦按键按下,稳定闭合的时间一般最短是20ms (手最快的人按下到放开的时间)。因此,我们通常需要使用如下的防抖措施:1当P1.2检测

5、到按键按下(即 P1.2引脚读到低电平)。2延时 1020ms。3再次检测P1.2按键是否仍被按下(即P1.2引脚依旧读到低电平),如果此时P1.2引脚仍然能读到低电平,说明按键确实已经稳定的按下了。4等待按键被放开。上述伪代码写成C51代码就应该是这个样子:sbit BtnAdd=P1A2; / 将 P1.2 引脚重新命名为 BtnAddif(BtnAdd=O)/当P1.2检测到按键按下(即 P1.2引脚读到低电平)Delay(20); / 延时 20ms。if(BtnAdd=O)再次检测P1.2按键是否仍被按下,如果此时P1.2引脚仍然能读到低电平,说明按键确实已经稳定的按下了while(

6、!BtnAdd);/等待按键被放开(按键没放开时BtnAdd为低电平(逻辑 0),/取反后为高电平(逻辑 1),此时while循环条件为真,/则继续执行该句,直到按键放开,后面的代码才能被执行)6.3独立按键的使用请实现:一位数码管显示从 09的数字,使用两个按键“ Add”和“ Sub”,按一下Add, 显示数字加一,按一下 Sub,显示数字减一,如显示数字小于 0或大于9,显示字符“ E”, 即“ ERROR的简写。6.3.1硬件的选择与仿真电路的设计1. 打开Proteus,选择“ File/NewDesign ”菜单选项,新建一个“设计项目”。并将项目保存为“ PushButton_1

7、 ”。2. 选择“ P”按钮或菜单“ Library/Pick Divice/Symbol P ”菜单,从“元件库”中选取 元件。依次添加其他元件。其名称和位置见下表。Itllu亠MqfFIh£H 1暫4-11,"-*-r-l;F-r2l'i元件名称CategorySub-CategoryResults单片机Microprocessor ICs8051 FamilyAT89C52一位7段数码管Optoelectro nics7-Segme nt Displays7SEG-MPX1-CA按钮Switches & RelaysSwitchesBUTTON电阻Re

8、sistorsGen ericRES依次从备选元件库中摆放器件,连线,画出仿真电路图,如图6-4所示。图6-4电路的说明:在仿真电路中,由于我们使用的是P1 口,它内部已经有上拉电阻了,因此我们可以不再添加上拉电阻了。但是,如果您使用的是P0 口(内部没有上拉电阻),大家必须添加上拉电阻,以确保单片机可以准确的检测到按键按下的动作。632程序的设计1. 新建一个keil项目,并命名为"PushButt on _1”并添加一个名为"ma in .c ”的源代码文 件,然后键入如下代码。如代码6.1所示。/代码6.1#in elude <reg52.h>#in el

9、ude "function .h"#i nclude "com mon .h"#define Seg7Port P2/数码管连接在 P2 口上/用一个数组来定义字符09共阳极数码管编码uchar code seg7ca=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;#define E 0x86 II用一个字符E来代替字符E'的共阳极数码管编码(0x86是其编码)sbit BtnAdd= P1A2; II将 P1.2 引脚重新命名为 BtnAdd (加 1 按键) sbit BtnSub=P1A

10、3; 将P1.3引脚重新命名为 BtnSub (减1按键)uchar count; II定义一个变量来存储当前数码管显示的值void mai n()count=0;数码管将从0开始显示while(1)Btn Add=1;BtnSub=1; II在读I/O 口之前,先要将其置为高电平 /如果加1按键按下,则count加1if(BtnAdd=0)/当P1.2检测到按键按下(即 P1.2引脚读到低电平) Delay(20); II 延时 20ms if(BtnAdd=0)再次检测P1.2按键是否仍被按下,如果此时P1.2引脚仍然能读到低电平,说明按键确实已经稳定的按下了while(!BtnAdd);

11、等待按键被放开(按键没放开时BtnAdd为低电平(逻辑0),取反后为高电平(逻辑1),此时while循环条件为真,则继续执行该句,直到按键放开,后面的代码才能被执行)count+; II加 1 键被按下,count 加 1else if(BtnSub=0)/如果减1按键按下则count减1 (过程与加1键检测相同) Delay(20);if(Btn Sub=O)while(!Bt nSub);count-; /减1键被按下,count减1if(count>=0 && count<=9) /如果count在09之间,则显示对应的数字Seg7Port=seg7caco

12、un t;else /否则显示字符E '表示错误Seg7Port=E;知识点:I/O 口做输入口当我们要用51单片机的I/O 口做输入口(即检测I/O 口当前的状态)时,为了正确的读取I/O 口的输入值,我们一般需要先将I/O 口置为高电平,如:Btn Add=1;BtnSub=1; /在读I/O 口之前,先要将其置为高电平知识点:if elseif else结构的语义if elseif else判断语句时C常用的判断语句,其语义如下:if()如果else if() /或者(再如果)else 否则这三个分支只有一个能发生(即 3选1)。如果你使用if()if()那么,这两个分支有可能同

13、时发生(多选)。请大家注意它们在语义上的区别,在本例中,我们设计时,是不考虑两个按键同时被按下的情形的,因此,实际是二选一的情况,因此,我们使用了if elseif else判断语句。6.4多位数码管的显示请实现:两位数码管显示从0059的数字,使用两个按键Add和Sub,按一下Add,数字加一,按一下 Sub,数字减一,如此反复。641硬件的选择与仿真电路的设计1. 打开Proteus,选择"File/NewDesign ”菜单选项,新建一个"设计项目”。并将项目保存为"PushButton_2 ”。2. 选择“ P”按钮或菜单“ Library/Pick Di

14、vice/Symbol P ”菜单,从“元件库”中选取元件。依次添加其他元件。其名称和位置见下表。元件名称CategorySub-CategoryResults51单片机Microprocessor ICs8051 FamilyAT89C52两位7段共阳数码管Optoelectro nics7-Segme nt Displays7SEG-MPX2-CA按钮Switches & RelaysSwitchesBUTTON电阻ResistorsGen ericRES依次从备选元件库中摆放器件,连线,画出仿真电路图,如图6-5所示。Ul丄A.园0呻 m <1从尉 nAW 峠Jim刼 ro

15、aw*4 H>SMi4 RtfMK A|7M|iT幷(MBaF14Plfl PI K血0 man 旧也码 KrSAii r-eai-in bl哺Pilrt"«Eiraj Mi 町urn raiffii FHfc图6-5电路说明因为我们使用了两位共阳数码管,由于51的驱动能力不足以直接驱动数码管,因此,我们通过两个PNP三极管作为电子开关来驱动数码管位选线,当P3.0输出低电平时,PNP三极管导通,Vcc通过三极管Q1加在数码管的个位,从而使数码管的个位发光(P3.1控制数码管十位发光的原理相同)。电阻R3和R4为限流电阻,通常取值为 1K左右。电阻R5和R6 为下拉电

16、阻,保证 PNP三极管可靠地截止,通常取值为 10K左右。642实现原理分析1. 我们使用一个变量 count表示当前数值,让 count从0开始,每按 Add键加1,当count 增加到59时,让它回到0,每按Sub键减1,当count减少到0时,让它回到59重新开始。 这样,count就在059之间反复变化。2. 我们让数码管的个位显示count的个位,数码管的十位显示count的十位。6.4.3程序的设计1.新建一个keil项目,并命名为"PushButt on _2”并添加一个名为"ma in .c ”的源代码文 件,然后键入如下代码。如代码6.2所示。代码6.2#

17、in clude <reg52.h>#in clude "function .h"#i nclude "com mon .h"#define Seg7Port P2/数码管连接在 P2 口上/用一个数组来定义字符09共阳极数码管编码uchar code seg7ca=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;sbit BtnAdd= P1A2; /将P1.2引脚重新命名为 BtnAdd (加1按键)sbit BtnSub=P"3;将P1.3引脚重新命名为 BtnSub (减1

18、按键)sbit GeWei=P3A0;定义数码管个位的位选线sbit ShiWei=P3A1; /定义数码管十位的位选线uchar count; 定义一个变量来存储当前数码管显示的值/关闭所有的数码管显示void CloseAIISeg()GeWei=1; /关闭个位位选线ShiWei=1;/关闭十位位选线在数码管上显示 count值void Display()uchar tmp;CIoseAIISeg(); /关闭所有的数码管显示先显示个位tmp=count%10; 提取 count 的个位数GeWei=0;/先显示个位,将十位关闭Seg7Port=seg7catmp; /将count

19、9;个位的编码送出Delay(1);CIoseAIISeg(); /关闭所有的数码管显示;消隐,防止闪烁/再显示十位tmp = count/10;/提取十位数ShiWei=0; /先显示十位,将个位关闭Seg7Port=seg7catmp; 将count '十位的编码送出 DeIay(1);CIoseAIISeg();/消隐,防止闪烁 void mai n()coun t=0;while(1) Btn Add=1;BtnSub=1; /在读I/O 口之前,先要将其置为高电平if(Bt nAdd=0) Delay(20);if(BtnAdd=0)再次检测P1.2按键是否仍被按下,如果此时

20、P1.2引脚仍然能读到低电平,说明按键确实已经稳定的按下了while(!BtnAdd);/等待按键被放开(按键没放开时BtnAdd为低电平(逻辑0), 取反后为高电平(逻辑1),此时while循环条件为真,则继续执行该句,直到按键放开,后面的代码才能被执行)if(count<59) / 如果 countv 59,每按 Add 键 count 加 1,否则 count 回 0 coun t+;elsecoun t=0;else if(BtnSub=0)/如果减1按键按下则count减1 (过程与加1键检测相同) Delay(20);if(Bt nSub=0) while(!Bt nSub)

21、;if(count>0)/ 如果 count>0,每按 Sub 键 count 减 1,否则 count 回 59 coun t-;elsecoun t=59;Display。;/在数码管上显示 count值程序代码说明1程序结构说明在本例中,我们的程序设计思路是这样的在main函数的大循环中,不断的检测BtnAdd和BtnSub是否被按下,如果被按下,则根据按下的按键修改count值,然后再将count的个位和十位分别显示在数码管上即可。2个数循环变化的技巧if(count<59)/如果 count v 59,每按 Add 键 count 加 1,否则 count 回 0c

22、oun t+;elsecoun t=0;以及下面的代码:if(count>0)/如果 count>0,每按 Sub 键 count 减 1,否则 count 回 59coun t-;elsecoun t=59;在让一个数循环变化时,这是一种常用的技巧,后面时钟项目中,我们会使用到这种技巧(调整时分秒,年月日等等)。3.Display()函数的使用因为在main函数的大循环中,我们要不断的将count的个位和十位显示在数码管上,这个显示操作可以写为一个函数,即Display()函数,这是一种常用的代码复用的技巧。6.5 4X4键盘的使用当我们的应用中要使用比较多的按键时,如果使用独立

23、按键的话, 将会占用很多I/O 口,那么,为了节约I/O 口线,我们需要使用另一类按键,其中比较常用的是4X4键盘。让我们实现如下功能:让1位数码管依次显示 4X4键盘的编码(数字键显示对应的数字,功能键显示对应的 AF字符)。6.5.1 4X4键盘实现按键检测的原理分析一般情况下,4X4键盘与单片机的连接如下面这图6-6所示。38-R BMMI mg -nWH WU旳恤口FiWWiPS TiUJffEmwfl 野沁地 哙匹ii #?4A13' WH; 悴昨Kl*f&WlW.M±tfT常鲜厂科SO皤 ti?r rj f.i-.S3r£芒r£C图6-

24、64X4键盘通常有4行4列共16个按钮,分别跨接在4根交叉的行线和列线上,我们通常把4根行线和4根列线连接在单片机的一个I/O 口上,比如像图 6-6那样,4根行线连接在P2.0P2.3上,4根列线连接在 P2.4P2.7上。当我们要检测键盘上那个按键被按下,我们通常采用如下方法:1我们先拉低P2.02依次检测 P2.4P2.7,如果没有检测到任何低电平,说明没有按键被按下。检测到有低电 平,比如P2.5为低电平,说明 P2.0和P2.5交叉的那个按键被按下了。3我们再拉低P2.14依次检测P2.4P2.7o (同步骤2)5我们再拉低P2.26依次检测P2.4P2.7o (同步骤2)7我们再拉

25、低P2.38. 依次检测P2.4P2.7o (同步骤2)9. 重复步骤18o上述伪代码写成C51代码就应该是这个样子。sbit Line_A=P2P; /将4X4键盘的4根行线连接在 P2.0P2.3 sbit Lin e_B=P2A1;sbit Lin e_C=P2A2;sbit Lin e_D=P2A3;sbit Line_仁卩2人4;/将4X4键盘的4根列线连接在 P2.4P2.7sbit Lin e_2=P2A5;sbit Lin e_3=P2A6;sbit Lin e_4=P2A7;Line_A=O; / 先拉低 P2.0if(Line 1=0)/检测每根列线是否被拉低。如果没有检测

26、到任何低电平,说明没有按键被按下Delay(10); / 消抖if(L ine_仁=0)result=7; 检测到有低电平,说明 P2.0和P2.4交叉的那个按键被按下了,则输出对应的按键的编码(编码自己定)else if(Line_2=0)/检测每根列线是否被拉低。如果没有检测到任何低电平,说明没有按键被按下Delay(10); / 消抖if(L in e_2=0)result=8; 检测到有低电平,说明 P2.0和P2.5交叉的那个按键被按下了,则输出/对应的按键的编码else if(Line_3=0)/检测每根列线是否被拉低。如果没有检测到任何低电平,说明没有按键被按下Delay(10)

27、; / 消抖if(L in e_3=0)result=9; 检测到有低电平,说明 P2.o和P2.6交叉的那个按键被按下了,则输出/对应的按键的编码else if(Line_4=0)/检测每根列线是否被拉低。如果没有检测到任何低电平,说明没有按键被按下Delay(10); / 消抖if(Li ne_4=0)result=10; /检测到有低电平,说明P2.0和P2.7交叉的那个按键被按下了,则输出 对应的按键的编码再依次检测 P2.1,P2.2,P2.36.5.2硬件电路的设计1. 打开Proteus,选择"File/NewDesign ”菜单选项,新建一个"设计项目” 。

28、并将项目保 存为“ 4X4KeyPad'。2. 选择“ P”按钮或菜单“ Library/Pick Divice/Symbol P ”菜单,从“元件库”中选取 元件。依次添加其他元件。其名称和位置见下表。元件名称CategorySub-CategoryResults51单片机Microprocessor ICs8051 FamilyAT89C521位7段共阳数码管Optoelectr on ics7-Segme nt Displays7SEG-MPX1-CA4X4键盘Switches & RelaysKeyPadsKEYPAD-SMALLCA1电阻ResistorsGen er

29、icRESHETP-D【舸DOFD.HW二 科和沖 FD "JgPD B/AH'.1 山T2 LfS坐SA科财帕*1 *waRSuEflno1畤罰丹ri.*W刊他P17依次从备选元件库中摆放器件,连线,画出仿真电路图,如图6-7所示。OdlFIHOEnnfll图6-7电路说明我们使用P2 口来驱动一位共阳极数码管,同时使用P3 口来检测4X4按键,其中,P3.0P3.3引脚连接到行线 ABCD上,P3.4P3.7连接到列线1234上。6.5.3程序的设计1.新建一个keil项目,并命名为"4X4Key”并添加一个名为"main.c ”的源代码文件,然 后键

30、入如下代码。如代码 6.3所示。代码6.3#in clude <reg52.h>#in clude "function .h"#in clude "com mon.h"#define Seg7Port P2 / 数码管连接在 P2 口上#define KeyPad P3 / 键盘连接在 P3 口上sbit Line_A=P3P; /将4X4键盘的4根行线连接在 P3.0P3.3sbit Lin e_B=P3A1;sbit Li ne_C=P3A2;sbit Lin e_D=P3A3;sbit Line_仁卩3人4; /将4X4键盘的4根列线连

31、接在 P3.4P3.7sbit Lin e_2=P3A5;sbit Lin e_3=P3A6;sbit Lin e_4=P3A7;用一个数组来定义字符0F共阳极数码管编码uchar code seg7ca=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e;uchar count; 定义一个变量来存储当前数码管显示的值/键盘扫描程序uchar Scan Keypad。uchar result='N:/定义函数输出结果KeyPad=Oxff;全部置高电平,为检测输入做准备Line_

32、A=0; / 先拉低 P3.0if(Line_1=0) /检测每根列线是否被拉低。如果没有检测到任何低电平,说明没有按键被按下。Delay(10); / 消抖if(L ine_仁=0)result=7; 检测到有低电平,说明 P3.0和P3.4交叉的那个按键被按下了,则输出对应的按键/的编码(编码自己定,本例中P3.0和P3.4交叉为数字7按键,所以我们输出7)else if(Line_2=0) /检测每根列线是否被拉低。如果没有检测到任何低电平,说明没有按键被按下。Delay(10);if(L in e_2=0)result=8; 检测到有低电平,说明 P3.0和P3.5交叉的那个按键被按下了,则输出对应的按键的编码else if(Line_3=0) 检测每根列线是否被拉低。如果没有检测到任何低电平,说明没有按键被按下。Delay(10);/ 消抖if(L in e_3=0)result=9;检测到有低电平,说明P3.o和P3.6交叉的那个按键被按

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论