1、第第7章章 键盘与键盘与LCD显示显示51单片机实战指南本章内容:独立式键盘检测原理及实现独立式键盘检测原理及实现1矩阵式键盘检测原理及实现矩阵式键盘检测原理及实现2LCD1602显示原理及实现显示原理及实现3按键检测原理按键的一端接地,另一端经上拉电阻接单片机的I/O口,当按键松开时,I/O口读到的状态为高电平,否则为低电平。图7-1 按键检测原理7.1 7.1 独立式键盘检测原理及实现独立式键盘检测原理及实现 7.1.1 独立式键盘检测原理与编程实现 1.检测原理 独立式按键比较简单,它们各自独立地与单片机的I/O口连接,如图7-2所示。4个按键分别接到单片机的口线上,当按键KEY0弹起时
2、,P3.2引脚经单片机P3口内部的上拉电阻与+5V电源相接,在P3.2上呈现高电平,按下时,则与地形成一条通路,P3.2引脚电位呈现出低电平,这样可以通过读取P3.2引脚的电平状态来判断按键是否按下。7.1 7.1 独立式键盘检测原理及实现独立式键盘检测原理及实现 7.1.1 独立式键盘检测原理与编程实现 1.检测原理在读引脚状态之前,必须要进行写1(对整个端口写FFH)的操作。7.1 7.1 独立式键盘检测原理及实现独立式键盘检测原理及实现 2.独立式键盘编程【例7-1】将P3口接的4个独立按键的状态通过P0口的LED灯反映出来。7.1 7.1 独立式键盘检测原理及实现独立式键盘检测原理及实
3、现 main.c文件 从原理图也可以看出,每个按键按下时,对应I/O口线输入是低电平,而P0口所接的LED也是低电平驱动,逻辑状态一致,可以直接输出,若LED是高电平驱动的话,就需要把按键的状态取反后再输出。上面的代码是分别对I/O口线操作,也可以直接对整个端口操作,代码更简洁。main.c文件7.1.2 7.1.2 键盘消抖键盘消抖图7-4 键抖动软件消抖:检测到有按键闭合时,延时一小段时间之后再次检测,如果仍然检测到按键闭合,则认为按键真正闭合。7.1.2 7.1.2 键盘消抖键盘消抖【例7-2】在数码管最低位显示按键KEY2按下次数。图7-5 原理图7.1.2 7.1.2 键盘消抖键盘消
4、抖【例7-2】在数码管最低位显示按键KEY2按下次数。图7-5 原理图程序代码7.1.2 7.1.2 键盘消抖键盘消抖延时消抖的延时时间一般在10毫秒左右。在上面例子的主程序中,通过while(1)循环一直在判断按键的状态,除此之外并没有做其它的工作,这仅仅是为了理解和学习对按键的操作。在实际的项目中,主程序中可能包含有各种各样的工作,比如对温湿度及其它物理量的测量、控制和数据处理等,如果在延时10ms消抖的过程中,某一事件发生了,那么该事件可能就检测不到,因此要尽量缩短延时时间,并能可靠消抖。常用的方法有以下两种。7.1.2 7.1.2 键盘消抖键盘消抖1)中断方式,启用一个定时器中断,每2
5、ms 进一次中断,扫描一次按键状态并且存储起来,连续扫描 8 次后,看看这连续 8 次的按键状态是否是一致的。8 次按键的时间大概是 16ms,这 16ms 内如果按键状态一直保持一致,那就可以确定现在按键处于稳定的阶段,而非处于抖动的阶段。2)查询方式,方法原理与第一种方法类似,只是不采用定时器中断,在主程序中,每隔一段时间t就检测一次按键状态,然后将每次检测到的按键状态以位变量的形式由低位到高位移位的方式存储到事先定义好的一个无符号字符型变量中,然后判断该字符型变量是否为“00”或“FF”,如果是,则表示按键处于稳定状态。7.1.2 7.1.2 键盘消抖键盘消抖【例7-3】将例7-2中的延
6、时消抖方式改为查询和中断方式。程序代码查询方式在主程序中,用延时2ms模拟一段运行时间约为2ms的程序段,每隔2ms就进行一次键扫描Scankey。定义了一个字符型变量keybuf=0 xFF,每次扫描按键时,都把按键的状态移入变量keybuf的最低位,然后判断keybuf是否等于0 x00或0 xFF,只有当8次扫描值都为0或1时,keybuf才等于0 x00或0 xFF,那么按键就处于稳定按下或稳定弹起的状态。7.1.2 7.1.2 键盘消抖键盘消抖【例7-3】将例7-2中的延时消抖方式改为查询和中断方式。程序代码中断方式采用中断方式和查询方式的扫描原理相同,只是采用了2ms的定时器中断,
7、在中断程序中进行键扫描,并把当前按键值左移入keybuf的最低位,然后判断keybuf是否等于0 x00或0 xFF来确定按键处于哪种状态。7.2 7.2 矩阵式键盘检测原理及实现矩阵式键盘检测原理及实现7.2.1 矩阵式键盘接口电路与检测原理1.接口电路图7-6 矩阵式键盘接口电路7.2 7.2 矩阵式键盘检测原理及实现矩阵式键盘检测原理及实现.7.2.1 矩阵式键盘接口电路与检测原理2.矩阵式键盘扫描原理 P2.0P2.3为行,P2.4P2.7为列,我们可以令行为输出,然后读列的值,也可以令列为输出,读行的值。把输出定义为KeyOut1KeyOut4,输入定义为KeyIn1 KeyIn4。
8、每次让矩阵按键的一个KeyOut 输出低电平,其它三个输出高电平,判断当前所有 KeyIn 的状态,下次中断时再让下一个 KeyOut 输出低电平,其它三个输出高电平,再次判断所有的KeyIn,通过快速的中断不停的循环进行判断,就可以最终确定哪个按键按下了。采用1ms中断判断4次采样值,消抖时间是16ms(1*4*4)。7.2.2 7.2.2 矩阵式键盘编程矩阵式键盘编程.【例7-4】在图7-6所示的独立式键盘电路中,按下相应的数字键时,在数码管最低位显示相应的键号,按键消抖采用定时器中断方式。程序代码:key.h文件硬件接口定义及函数声明key.c文件函数定义主程序main.c主程序中启用了
9、定时器T0定时1ms,在定时器中断中进行键扫描,键扫描时以变量keyout作为行索引,一次扫描一行上所有按键,并把各个按键的状态分别移入各键的keybuf的低位进行消抖,这个消抖的原理与独立式按键相同。每一行扫描完成后,行索引值keyout加一,对下一行进行扫描,整个扫描过程就是逐行扫描。7.3 LCD16027.3 LCD1602显示原理及实现显示原理及实现LCD1602液晶的控制器是采用日立公司的HD44780集成电路,HD44780内置了DDRAM、CGROM和CGRAM。1.DDRAM(Display Data RAM)DDRAM就是显示数据RAM或称显存,用来存放待显示的字符代码,H
10、D44780内部共有80(402)个字节。LCD1602的显示屏幕只有162,只取前16列。7.3 LCD16027.3 LCD1602显示原理及实现显示原理及实现 要在 LCD1602 屏幕的第一行第一列显示字符“A”,只要向 DDRAM的00H 地址写入“A”字的代码。也就是说,只要向DDRAM的显示地址中写入待显字符的代码,字符就会在液晶显示器对应的位置上显示。如在第二行显示,第二行的地址要在第一行地址上加40H。7.3 LCD16027.3 LCD1602显示原理及实现显示原理及实现2.CGROM和CGRAM CGROM(Character Generator ROM)和CGRAM(C
11、haracter Generator RAM)都为字符产生器,用于存放显示字符。CGROM中存放了HD44780已定义的192个常用字符。CGRAM则用于存放用户自定义的字符,共8个。7.3 LCD16027.3 LCD1602显示原理及实现显示原理及实现CGROM字符表第一行第一列显示字符“A”,通过查找CGROM表格,字符“A”的高4位为0100,低4位为0001,均为二进制,合并得到01000001,即41H,恰好是字符“A”的ASCII码。7.3.2 LCD16027.3.2 LCD1602硬件接口硬件接口1602型LCD分有背光(16个引脚)和无背光(14个引脚)两种。16脚1602
12、型LCD引脚共分成三类,如图7-7所示。1.电源引脚引脚1和引脚2 分别是电源地(GND)和电源(VCC)。2.数据引脚引脚7到引脚14共8个引脚是双向数据总线的第0位到第8位。由于单片机的P0口无上拉电阻,因此如果需要接到P0口,则必须接上拉电阻。而接到其他并口,可不接上拉电阻。7.3.2 LCD16027.3.2 LCD1602硬件接口硬件接口图7-7 LCD1602引脚及实物图 7.3.2 LCD16027.3.2 LCD1602硬件接口硬件接口3.控制引脚引脚3:VO为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,一般使用时可以通过10K的电位器调整对比度,避免产
13、生“鬼影”。引脚4:RS为寄存器选择,高电平“1”时为数据寄存器,低电平“0”为指令寄存器。引脚5:RW为读写信号线,高电平“1”时进行读操作,低电平“0”时进行写操作。引脚6:E(或EN)端为使能(enable)端,高电平“1”时读取信息,负跳变时执行指令。引脚1516:背光电源。7.3.3 LCD7.3.3 LCD指令指令1.显示模式设置在LCD1602显示某一内容之前,首先要设置显示方式,这个过程成为初始化或驱动,在初始化中需要进行的主要工作如下。1)每次显示刷新之前或之后需要进行清屏操作。清屏指令码为01H。功能:(1)清除液晶显示器,将DDRAM的所有地址填入“空白”的ASCII码2
14、0H;(2)光标归位,光标回到显示器左上方;(3)地址计数器(AC)的值设置为0。7.3.3 LCD7.3.3 LCD指令指令2)根据LCD1602与单片机在硬件电路,确定接口方式。LCD1602与单片机有2种接口方式,4位和8位数据接口。此外在显示时,可根据显示内容选择57 点阵和510点阵显示,57 点阵可显示2行,而510 点阵只能显示1行。功能:随书开发板采用的是8位数据总线,如果采用2行显示,只能采用57 点阵。因此DL=1,N=1,F=0,则该指令为38H。7.3.3 LCD7.3.3 LCD指令指令3)显示时,是否需要光标,光标是否闪烁,新的显示内容显示后,光标向哪个方向移动,这
15、些需要以下2条指令设置。(1)显示开关控制指令功能:设控制显示器开/关、光标显示/关闭以及光标是否闪烁例如,要显示光标闪烁,需设置D=1,C=1,B=0。指令为0EH。7.3.3 LCD7.3.3 LCD指令指令(2)进入模式设置指令功能:设定每次输入1位数据后光标的移位方向,并且设定每次写入的一个字符是否移动。一般情况下,显示新内容后仅仅光标右移,故I/D=1,S=0。指令为06H。7.3.3 LCD7.3.3 LCD指令指令2.数据显示初始化完成后,接下来就是把待显示的内容写入到LCD1602的DDRAM中进行显示了。1)读LCD1602。在写显示内容之前,包括上一步初始化时的写命令之前,
16、都先要进行读操作,这是因为LCD1602是一个慢速器件,在对其进行操作时,必须要确定其是否处于空闲状态,如果空闲的话,就可以向其写命令或数据了。最高位DB7为BF(Busy Flag)忙碌标记。BF=1 表示液晶显示器忙,暂时无法接收单片机送来的数据或指令;当 BF=0 时,液晶显示器可以接收单片机送来的数据或指令。这条指令还可以读取地址计数器AC(Address Counter)的值,即DB6DB0位。7.3.3 LCD7.3.3 LCD指令指令2)写显示数据。显示过程是通过设定DDRAM指令完成,即把显示代码写入到DDRAM中。LCD1602中DDRAM最大地址为4FH,即01001111
17、B,最高位为0,而本指令中最高位为1,因此指令码是将相应的地址码的最高位置为1,即指令码=地址码+80H。7.3.4 LCD7.3.4 LCD操作时序及编程实现操作时序及编程实现1.LCD1602的基本操作时序在对LCD1602操作时,对RS、R/W、E三个引脚的操作至关重要,将LCD1602进行读写操作时,RS=0时,读写指令;当RS=1时,读写数据;当R/W=0时,写数据或指令,当R/W=1时,读数据或指令;使能端E高电平,读操作;使能端E负跳变,写操作。7.3.4 LCD7.3.4 LCD操作时序及编程实现操作时序及编程实现1.LCD1602的基本操作时序7.3.4 LCD7.3.4 L
18、CD操作时序及编程实现操作时序及编程实现1.LCD1602的基本操作时序tC:使能引脚E从本次上升沿到下次上升沿的最短时间是400ns。tPW:使能引脚E高电平的持续时间最短是150ns。tR,tF:是使能引脚 E 的上升沿时间和下降沿时间,不超过 25ns。tSP1:是RS和R/W引脚使能后至少保持30ns,使能引脚E才可以变成高电平。tHD1:使能引脚E变成低电平后,至少保持10ns之后,RS和R/W才能进行变化。tD:使能引脚E变成高电平后,最多100ns后,1602送数据,正常读取状态或者数据。tHD2:使能引脚E变成低电平后,至少保持20ns,DB总线数据才可以变化。tSP2:指的是
19、DB数据总线准备好后,至少保持40ns,使能引脚E才可以拉高。tHD2:写操作过程时,引脚E变成低电平后,至少保持10ns,DB总线数据才可变化。从时序参数表可看出最长的时间E信号周期不过400ns,而51单片机执行一条指令最少也要1us,时间条件自然满足要求。7.3.4 LCD7.3.4 LCD操作时序及编程实现操作时序及编程实现2.LCD1602的时序图及其读写操作的编程1)读操作时序7.3.4 LCD7.3.4 LCD操作时序及编程实现操作时序及编程实现2.LCD1602的时序图及其读写操作的编程1)读操作时序void LcdWaitReady()unsigned char sta;P0
20、=0 xFF;/保证读准确LCD1602_RS=0;LCD1602_RW=1;do LCD1602_E=1;sta=P0;/读取状态字LCD1602_E=0;while(sta&0 x80);/bit7 等于1表示液晶正忙,重复检测直到等于07.3.4 LCD7.3.4 LCD操作时序及编程实现操作时序及编程实现2.LCD1602的时序图及其读写操作的编程2)写操作时序7.3.4 LCD7.3.4 LCD操作时序及编程实现操作时序及编程实现2.LCD1602的时序图及其读写操作的编程2)写操作时序void LcdWriteCom(unsigned char com)/com命令LcdWaitR
21、eady();LCD1602_E=0;/使能LCD1602_RS=0;/选择发送命令LCD1602_RW=0;/选择写入P0=com;/放入命令LCD1602_E=1;/写入时序LCD1602_E=0;7.3.7.3.5 5 LCD1602 LCD1602显示实战显示实战【例7-5】在LCD1602的第一行居中显示“HELLO WORLD!”,第二行显示字符“0”“F”。程序代码:lcd1602.h文件 lcd1602.c 主程序main.c文件7.3.7.3.5 5 LCD1602 LCD1602显示实战显示实战【程序解析】在LCD1602显示过程中,最主要的两个函数是写命令LcdWrite
22、Com函数和写数据LcdWriteData函数。通过写命令函数对LCD1602进行初始化和设定显示位置,通过写数据函数,可以显示单个字符或字符串。此外在写操作之前需要测忙。需要注意的是,主程序中Display1和Display2中存放的是这两个字符串的ASCII码,在对LCD1602的DDRAM写数据以进行显示时,写的内容就是每个字符的ASCII码,这些字符的ASCII码是内置的。7.3.7.3.5 5 LCD1602 LCD1602显示实战显示实战指针的应用 要访问一个变量,有两种方式:一种是通过变量名来访问,另一种是通过变量的地址来访问。在C语言中,地址就等同于指针,变量的地址就是变量的指针。要把地址送到“地址输入框”内,这个“地址输入框”相当于一个特殊的变量保存地址的变量,称之为指针变量,简称为指针,通常说的指针就是指指针变量。7.3.7.3.5 5 LCD1602 LCD1602显示实战显示实战指针的应用指针是访问一个地址连续的数据块的有效方法。以上面Disp2这个字符串为例,假设编译器给这个字符串在内部ROM中分配的地址从0010H单元开始,并且由于该字符串数组的类型为char型,即每个字符占用一个存储单元。