1、1602总结LCD1602总结济南职业学院 电子工程系 朱志强1、LCD1602介绍2、LCD1602常用指令3、LCD操作直通车4、LCD大提速2010年7月28日1、LCD1602介绍LCD1602已很普遍了,具体介绍我就不多说了,市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的。图1 LCD1602 16脚图2 LCD1602字符集2、LCD1602常用指令(1) 功能设定和字符格式指令功能:设定数据总线位数、显示的行数及字型。 位名 设置DL 0=数据总线为4位 1=数据总线为8位N 0=显示1行 1=显示2行F 0=57点阵/每字符 1=510点阵/每字符我
2、一般就用0X38,57的就够用了啊(2)显示开关控制指令 功能:控制显示器开/关、光标显示/关闭以及光标是否闪烁。位名 设置D 0=显示功能关 1=显示功能开C 0=无光标 1=有光标B 0=光标闪烁 1=光标不闪烁我一般就用0x0c,整体显示,无光标,不闪烁。(3)输入方式设置 功能:设定每次定入1位数据后光标的移位方向,并且设定每次写入的一个字符是否移动。位名 设置I/D 0=写入新数据后光标左移 1=写入新数据后光标右移S 0=写入新数据后显示屏不移动 1=写入新数据后显示屏整体右移1个字符 我一般都是使用的0X06,屏幕不用移动。 (4)清屏指令功能: 清除液晶显示器,即将DDRAM
3、的内容全部填入空白的ASCII码20H; 光标归位,即将光标撤回液晶显示屏的左上方; 将地址计数器(AC)的值设为0。 我们这个就不用争了,这个没什么选的了,用的都是0X01了。3、LCD操作直通车由图1我们可以知道,RS=0写入的是指令,RS=1写入的是数据。RW=0是写入,我们对LCD进行一般的操作,就是让她显示,这个步骤一般用不到忙检测,所以在上面的指令中我们也没有提到。那我们所用的也只是RW=0。E是使能信号,也有人喜欢用EN,不过都是一样的啦。从图表中可以看出是下降沿有效。通过对LCD指令的观察,我们可以知道,一般的指令执行的时间都是40us,这个是一个重点哦!指令(4)清屏指令的执
4、行时间是1.64ms,我一般都是当做2ms来处理。在这里我要说一下我一般常用的延时函数。(1) 延时ms级函数void delayms(unsigned char ms) unsigned int i; while(ms-) for(i=0;i125;i+) ; (2) 延时us级函数void delayus(unsigned int us) while(us-);/执行时间t=us2毫秒下面是对操作的讲解了:首先我们要能够给1602写入指令。写指令之前要知道LCD1602的连接。如图3所示。图3 LCD1602接线图/*给LCD1602写函数变量:data1 :0为指令 1为数据 data2
5、 是要写入的数据。*/void LCD_WByte(unsigned char data1,unsigned char data2) P0=data2; RS=data1; RW=0; E=1; E=0;/下降沿有效 delayus(20);/延时40us有了这个函数我们就可以对LCD进行初始化了。下面是她的初始化函数。里面用到的一些数据,我们上面都提到了。初始化使用的都是指令,所以写函数的第一变量都是0!/*LCD初始化函数无变量*/void LCD_chushihua() LCD_WByte(0,0x38); LCD_WByte(0,0x0c); LCD_WByte(0,0x06); LC
6、D_WByte(0,0x01);/清屏 delayms(2);/等待2毫秒到清屏结束LCD初始化完毕之后我们就可以让她显示我们要显示的数据了。但是,我的LCD还是有一个大家需要注意的地方。我的LCD后面的型号是HS1602A V1.0,她有个小问题,就是写函数的时候必须是RS在RW的前面,否则就不能工作了。我反过来后添加延时也不行。网上的资料也没有提到这个问题,希望大家注意这个地方!下面我们就要让她显示字符了,显示一个字符是最简单的了。我们可以给她ASCII码,也可以直接写字符。我个人比较喜欢直接写字符,多方便啊网上有一个比较不错的在LCD任意位置写一个字符A的函数,抄下来分享一下了。/*在任
7、意位置显示字符的函数变量:X横坐标(在0和15直间的数据)Y竖坐标(1或2,表示行号) data3为要显示的数据*/void LCD_disp(unsigned char x,unsigned int data2,unsigned data3) unsigned char add; if(y=1) add=0x80+x;else add=0xc0+x; LCD_WByte(0,add);/先写地址 LCD_WByte(1,data3);/在写要显示的数据我们随便写一个主函数就完成了对LCD的基本显示操作了。顺便把主函数也写出来吧。void main() LCD_chushihua(); LCD
8、_disp(2,1,A);/2说明是第三个位置哦 while(1);4、LCD大提速只显示一个字符时不可取的,那不能从根本上解决LCD的应用问题,我们主要是显示字符串,可是一个一个的显示显然不可取啊。我们就需要直接让她显示一个字符串。显示字符串需要到指针,指针我认为方便啊。我们需要回过头去复习一下了,LCD初始化后,使用了清屏指令0x01,清屏之后,光标归位,地址计数器AC为零。此时光标的位置也就是第一行第0个位置了。在LCD初始化之后,我们可以直接使用下面的函数显示字符串,但是显示的位置是第一行第0个位置开始的。void LCD_disps(unsigned char *dat4) unsi
9、gned char *p; p=dat4; /LCD_WByte(0,0X86); while(*p!=0) LCD_WByte(1,*p+); 使用的方法就是 LCD_disps(LCD1602); 这句添加到主函数里面。这个的显示起点是固定的,我们可以考虑怎样让它可以在任意的位置上显示。指定位置的办法就是先写入需要显示的首地址。第一行的首地址是0x80,第二行的首地址是0xc0。在这里,这个同单个字符显示的地址。将上面函数中注释掉的那句话恢复就可以了。字符型LCD的优点还有一个就是给我们留下了8个自己设置字符的空间。这使得我们可以在LCD上显示出我们自己想要的字符。与这个相关的指令就是CG
10、RAM指令。功能:设定下一个要存入数据的CGRAM的地址。DB5 DB4 DB3 为字符号,也就是你将来要显示该字符时要用到的字符地址。(000111) (能定义八个字符)DB2 DB1 DB0 为行号。(000111) (八行)我们可以看出DB5DB3是我们要自定义的字符的地址。若是设我们的地址是unsigned char add,那么我需要做的是:add=add3;(在C中移位就补零)最后的三位就是我们每一个自定义字符的8位码。一行是一个,是一个85的字符。字符的定义方法如下:一一0x04 一一一一一一0x0e、0x1f0x00、0x1f、0x0e、0x040x00(最后一行我们选择留空,
11、你也可以加上的)最后我们得到的表格如下:unsigned char table= 0x04,0x0e,0x1f,0x00,0x1f,0x0e,0x04,0x00;我们就通过下面这个函数实现存储自定义的字符:/*实现存储及显示自定义字符变量:add 自定义字符地址(07之间) *p是我们上面定义好的表格的首地址*/void LCD_zidingyi(unsigned char add,unsigned char *p) unsigned int i; add=add3; for(i=0;i8;i+) LCD_WByte(0,0x40|add+i); LCD_WByte(1,*p+); 在主函数中
12、使用的方法如下:LCD_zidingyi(7,table);/7是自定义字符的地址LCD_disp(14,1,7);/7是上面我们自定义的字符的地址 下面是显示的效果:最后是我们还一直没有提到的一个LCD的指令设定显示屏或光标移动方向指令功能:使光标移位或使整个显示屏幕移位。参数设定的情况如下:S/C R/L 设定情况0 0 光标左移1格,且AC值减10 1 光标右移1格,且AC值加11 0 显示器上字符全部左移一格,但光标不动1 1 显示器上字符全部右移一格,但光标不动 对于这个指令的用法,当然是用在主函数里了。假如是右移的话,那么指令为:LCD_WByte(0,0X1F); 最后两位是,这
13、个可以不用考虑。每调用一次这个指令,LCD显示屏的所有显示都会右移一位。我只是做了一下测试,感觉这个占用了太多的CPU,实用性不是很强。如果能够把等待的时间用于处理别的函数上,这样就解放CPU,这样的话还是比较可取的。#include #define uint unsigned int#define uchar unsigned char/ uchar table= / 0123456789/ ;unsigned char table= 0x04,0x0e,0x1f,0x00,0x1f,0x0e,0x04,0x00; sbit RS=P27;sbit RW=P26;sbit EN=P25;vo
14、id delayms(uchar ms) uint i; while(ms-) for(i=0;i125;i+) ; void delayus(uint us) while(us-) ;/*lcd 写字节子函数data0 =0 写指令 data=1 写数据 不读取数据*/void LCD_wirtebyte(uchar data0,uchar data1) RS=data0; RW=0; P0=data1; EN=1; delayus(2); EN=0;void LCD_chushihua() LCD_wirtebyte(0,0x38);/57 字符 两行 LCD_wirtebyte(0,0x
15、0c);/显示数据 无光标 不闪烁 LCD_wirtebyte(0,0x06);/光标右移 LCD_wirtebyte(0,0x01);/清屏指令 delayms(2);/延时两毫秒,等待清屏结束。/*lcd 写数据子函数data2 行号 (必须为1 或者2!) data3 位置data4 是数据*/void LCD_write(uchar data2,uchar data3,uchar data4) uchar add; if(data2=1) add=0x80+data3; else if(data2=2) add=0xc0+data3; LCD_wirtebyte(0,add); LCD
16、_wirtebyte(1,data4);void LCD_wstr(uchar data5,uchar data6,uchar *data7) uchar add; if(data5=1) add=0x80+data6; else if(data5=2) add=0xc0+data6; LCD_wirtebyte(0,add); while(*data7!=0) LCD_wirtebyte(1,*data7+);/*实现存储及显示自定义字符变量:add 自定义字符地址(07之间) *p是我们上面定义好的表格的首地址*/void LCD_zidingyi(unsigned char add,unsigned char *p) unsigned int i; add=add3; for(i=0;i8;i+) LCD_wirtebyte(0,0x40|add+i); LCD_wirtebyte(1,*p+); void main() LCD_chushihua(); LCD_zidingyi(0,table); while(1) LCD_wstr(1,1,ilove si jinli!); LCD_write(1,0,0);
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1