1、1LCD 1602简介LCD1602可显示两行,每行16个字符,不能显示汉字。16脚的 LCD 1602带背光,14脚的不带背光。2LCD1602 端口引脚不一一记录手册上面是咋个描述 LCD 1602的了。记录一下操作过程,下图是 LCD 1602在51单片机上面的连线。图1 LCD 与单片机接线图D0-D7引脚连接在单片机的 P0端口。plain view plaincopyprint?LCD_RS = P10;LCD_RW = P11;LCD_EN = P25;查看 LCD 1602手册,得到 LCD 引脚组合的含义如下:表格1:LCD 操作模式模式 输入 输出读状态RS=0,RW=H,
2、EN 为高变低脉冲 输出:D0D7个状态值读数据RS=1,RW=1,EN 为高变低脉冲 输出:无写指令RS=0,RW=0,D0-D7=数据,EN 由高脉冲变为低脉冲 输出 D0-D7状态值写数据RS=1, RW=0, D0-D7=数据,EN 由高脉冲变为低脉冲输出 D0-D7状态值可以参照图1的接线图对这些模式和输入输出做出相应的理解。模式、输入都是跟单片机 I/O 端口相连的端口。输出是使 LCD 显示的内容。在编写程序时,可以先设置 LCD 显示内容的格式(初始化 LCD),然后再对 LCD 进行读写操作。这些过程由 LCD 跟单片机相连的 I/O 端口来完成。3LCD 1602的操作时序
3、查看 LCD 1602手册,以 LCD 写操作时序为例记录在对 LCD 操作的过程中需要注意到的延迟语句的编写,否则可能导致对 LCD 的操作失败。图2 LCD 的写操作时序根据表一 LCD 的操作时序可知,在 RS,RW,E(N),DB7.0(D0-D7)满足一定时序的高低电平条件时就可以对 LCD 进行写操作。变化都不是瞬间的,在对 RS 等置高置低时,RS 等变高变低有一个下划的过度时间,如果这种过渡的时间超过单片机内一条或几条指令的执行时间,则这种时序就有可能会被错开。如现在对LCD 进行写操作,将 RS 置高,RW 置低,准备好 DB7.0数据,E 由高变低等操作由以下代码完成:pl
4、ain view plaincopyprint?LCD_RS = 1;LCD_RW = 0;DB7_0 = A;LCD_EN = 1;LCD_EN = 0;RS 在高电平时选择数据寄存器,在低电平时选择指令寄存器。RW 在高电平时进行读操作,在低电平时进行写操作。E(N)为使能端,当 E(N)端由高电平跳变为低电平时,LCD 模块执行命令。DB7.0为8位双向数据。其中 LCD_RS 等都是单片机控制 LCD RS 等端口的引脚,如果(-)只有 RS 端彻底变为1的时间超过以上的所有代码执行时间,则在 E 低脉冲到来之时,RS 还是低电平,所以由于 RS 的电平不满足条件对 LCD 的写操作将
5、会失败。当然,传说 LCD 的电平变化时间比指令执行时间快,但是为了可靠稳定,在程序中肯定需要等待对应的端口彻底变为需要电平时再写其它端口的值。就这么等待太长时间肯定是会为程序的执行结果带来影响,只需要等待端口的电平能完全变化的时间即可。手册中有说明的:图3 LCD 初始化图虽然需要等待的时间对于人类来说实在是可以忽略不计,但在 LCD 类中来说却是必须的。如果没有这些等待,那么就有可能遇不到 LCD 与你写入内容的邂逅或者出现偶尔成功偶尔失败的场景。在每次读/写指令后都应该等待一段时间来等待 LCD 端口电平的彻底变化,可用 keil 软件模拟一段时间,用5ms(等待时间小于5ms 者)等时
6、间代替需要等待的时间都是可以的。4 LCD1602的指令集 相关LCD 指令集笔记在 LCD 1602指令集中,对 LCD 来说有四种意思:(1) RS 和 RW 都为0时表示对 LCD 写指令操作,包括写入 LCD 的显示模式和设定 LCD 地址的指令。.显示模式包括清屏、地址归为、显示状态、进入点设定、功能设定、游标显示模式操作;关于地址的操作包括设定 CGRAM 地址、设定 DDRAM 地址。(2) 当 RS=0,RW=1时,表示读 LCD 状态,此时可以读取 LCD 忙信号,同时可以读取地址计数器的值。忙信号的状态用来确定 LCD 内部动作是否完成,若在 LCD 内部出于忙状态时对 L
7、CD 进行读写操作将会失败。(3)当 RS=1时,若 RW=0表示写数据操作,若 RW=1表示读数据操作。CGRAMCGRAM 为 LCD 模块内部的字符发生存储器,里面存了不同的点阵字符图形,包括阿拉伯数字,英文大小写字符等。每个字符都有一个固定的代码,如A的代码是01000001,(41H),需要显示A时只需要将地址为41H 中的点阵图形显示出来就可以看见A了。具体字符点阵图查看手册为全宜。LCD1602显示屏内部显示地址表输入显示字符地址,也就是告诉 LCD 在哪里显示字符。LCD 供两行,第一行可立即显示字符的地址为00H0FH,第二行可立即显示字符的地址为40H67H,如果在其它地址
8、中显示字符,需要通过移屏指令00011000:整屏左移光标跟着移动; 00011100:整屏右移光标跟着移动将它们移入可显示区域方可正确显示。当要在00H 处显示字符时,写入的地址应为00H + 80H(因为置 LCD 显示位置时要求 D7位始终为1,手册中置数据存储器地址指令)5 LCD 1602程序编写LCD 初始化plain view plaincopyprint?/- -/写命令,初始化端口设置 LCD 显示模式/- - -void LCD_mode_init()LCD_EN = L;/等待 LCD 电路完全接通delay_ms( DELAY_TIME_FOR_INIT );/P0=
9、00111000设置16x2显示,5x7点库,8位数据端口write_command( 0x38 );delay_ms( DELAY_TIME );/LCD 开显示,显示光标,光标闪烁write_command( 0x0f );/读写字符后地址指针、光标加1,整屏显示不移动write_command( 0x06 );/清显示,便对 LCD 写入write_command( 0x01 );根据图3,当 LCD 电路接通之时,需要用约15ms 的时间来让 LCD VDD 电压达4.5V,虽然在开启单片机电源的时候程序还未执行到初始化程序就已经过了15ms 让 LCD VDD 电源达4.5V。但也有
10、可能程序中只包含了LCD 程序,初始化被放在了最前面,15ms 的时间足以让单片机运行很多指令了(可以由单片机的机器周期和一条指令执行的机器周期数比较一下),为了防止在 LCDVDD 电源未达4.5V 时单片机程序已经执行到设置 LCD 显示模式的指令,就在进入 LCD 初始化程序时等待15ms 的时间,让 LCD 电源初始化完毕。写指令plain view plaincopyprint?/- -/写命令/- -void write_command( uchar command )while( lcd_busy() );LCD_RS = L;LCD_RW = L;delay_ms(DELAY_
11、TIME);P0 = command;/等待数据稳定delay_ms(DELAY_TIME);LCD_EN = H;/让使能位保持到一,负脉冲跳变delay_ms( DELAY_TIME );LCD_EN = L;delay_ms( DELAY_TIME );写指令前首先要检查 LCD 内部操作是否已经完成,LCD 的 BF 位(D7)为高电平表示忙,为低电平表示空闲。同理,在对每一个端口设置高低电平后,同样需要一段时间来等待电平的彻底变化。写数据plain view plaincopyprint?/-/写数据,写 LCD 显示内容/-void write_data( uchar wdata
12、)while( lcd_busy() );LCD_RS = H;LCD_RW = L;LCD_EN = L;P0 = wdata;/等待 DB0-DB7数据稳定delay_ms( DELAY_TIME );LCD_EN = H;/让使能位充分达到1delay_ms( DELAY_TIME );LCD_EN = L;delay_ms( DELAY_TIME );检测 LCD 忙信号plain view plaincopyprint?/-/检测 LCD 的忙信号/-bit lcd_busy()bit result;LCD_RS = 0;LCD_RW = 1;LCD_EN = 1;delay_ms(
13、 DELAY_TIME );result = (bit)(P0LCD_EN = 0;return result;在检测 LCD 忙信号的同时,还可以设置一下原本该低或该高的位的状态。P0端口是连接到 D0D6端口的I/O 引脚,0x80就是用来检测 D7位状态的数据。延迟函数plain view plaincopyprint?/- -/延迟函数/- -void delay_ms( uint ms )uint i, j;for(i = ms; i 0; i-)for(j = 110; j 0; j-);根据单片机的晶振和 keil 执行指令的时间计算,以上延迟函数约延迟 ms 毫秒的时间。DEL
14、AY_TIME 的宏值为5,表示延迟5毫秒的时间。LCD 有的端口不需要延迟这么长的时间,这个可以调试到适合相应端口最适合的延迟时间即可。借助手册和枚举调试法。运行结果将初始化函数放置在 main 函数中后,将 LCD 的显示地址设置在第一行第一列(此指令在写指令集中,可调用 write_command( 0x80)来完成),然后写字符到 LCD 第一行中。再将显示地址跳到第二行,地址后移需要显示字符传长度个单位,写入显示的字符传,对整个屏幕移位(由写指令集中指令完成,移字符传长度那么多位,移完一个停留的时间需要长点,如200ms 左右的时间)。然后让程序等待,只为 LCD 操作演示-。程序的效果为:首先在第一行显示了指定的字符串。当移入第二行字符串时,由于是整个屏幕的移动,所以第一行字符串也随之移入了屏幕的左边。现将两行的字符串显示在 LCD 屏幕之上,不采取移动的操作。6 总结电平变化时不是瞬间的,需要用延迟函数来等待相应位彻底的编程预期的电平。这是跟写其它程序的一个区别。每逢遇到对硬件引脚电平的置位时,都需要结合手册看看对应引脚的灵敏度,若高出指令执行时间徐许多数量级就不用延迟语句,否则应当考虑用延迟语句来等待。应该走进硬件的操作时序世界中去才能编写好它们的程序。非常好用的电子器件 datasheet 搜索: