lcd1602程序流程图
- 格式:docx
- 大小:37.11 KB
- 文档页数:4
LCD1602的电路图和程序————————————————————————————————作者:————————————————————————————————日期:MS基于1602字符型液晶显示器的显示系统姓名:杨越班级:电子11-1学号:110400104一、实习目的(1)了解飞思卡尔单片机的基本原理,掌握其基本的工作流程。
(2)了解LCD1602的基本原理及用法。
(3)能够熟练使用CodeWarrior软件编写C语言程序,使用BDM仿真器下载程序。
(4)能够熟练焊接电路板。
二、实验设备与器件CodeWarrior软件,BDM仿真器,万用电路板,飞思卡尔单片机,LCD1602液晶显示器,三、实验内容内容:利用飞思卡尔单片机制作基于1602字符液晶显示器的显示系统要求:用四个按键控制,按下第一个按键显示1,按下第二个按键显示2,以此类推。
(1)LCD1602液晶显示器的原理:1602共16个管脚,但是编程用到的主要管脚不过三个,分别为:RS(数据命令选择端),R/W(读写选择端),E(使能信号);以后编程便主要围绕这三个管脚展开进行初始化,写命令,写数据。
以下具体阐述这三个管脚:RS为寄存器选择,高电平选择数据寄存器,低电平选择指令寄存器。
R/W为读写选择,高电平进行读操作,低电平进行写操作。
E端为使能端,后面和时序联系在一起。
除此外,D0~D7分别为8位双向数据线。
操作时序:RS R/W 操作说明0 0 写入指令码D0~D70 1 读取输出的D0~D7状态字1 0 写入数据D0~D71 1 从D0~D7读取数据注:关于E=H脉冲——开始时初始化E为0,然后置E为1,再清0.读取状态字时,注意D7位,D7=1,禁止读写操作;D7=0,允许读写操作;所以对控制器每次进行读写操作前,必须进行读写检测。
(即后面的读忙子程序)指令集:LCD_1602 初始化指令小结:0x38 设置16*2显示,5*7点阵,8位数据接口0x01 清屏0x0F 开显示,显示光标,光标闪烁0x08 只开显示0x0e 开显示,显示光标,光标不闪烁0x0c 开显示,不显示光标0x06 地址加1,当写入数据的时候光标右移0x02 地址计数器AC=0;(此时地址为0x80)光标归原点,但是DDRAM 中断内容不变0x18 光标和显示一起向左移动(2)飞思卡尔单片机的功能及特点:MC9S12XS128是 16 位单片机,由 16 位中央处理单元(CPU12X)、128KB 程序、Flash(P-lash)、8KB RAM、8KB 数据 Flash(D-lash)组成片内存储器。
LCD1602程序代码及显示流程图LCD1602显示程序代码DB P0//--P0=DB0~DB7位LCD_RS=P2;//--P2.0=RS位LCD UrW=P2;//--P2.1=RW位LCD_Ue=P2;//-P2.2=E//--/--/----定义函数ා define uchar unsigned charා define uint unsigned int///—定义子例程函数void LCD_Uiinit(void);//-初始化LCD1602函数void LCD_2;write_uchar命令(uchar命令);//-写入命令功能无效LCD到LCD1602_Char数据(uchar DAT);//-将无效的LCD数据写入LCD1602_Uxset_XY(uchar x,uchar y);//设置LCD1602 void LCD_uchar(uchar x,uchar y,uchar DAT)的显示位置x(0-16),y(1-2);//-在LCD1602中,显示包含无效字符的LCD;uchar x,uchar y,uchar*s);在LCD1602上显示一个字符串//void LCD_ucheck_uBusy(void);//检查Busy函数。
我没有使用这个功能,因为通过率很低。
LCD_u2;delay_10us(uint n);//-10微秒延迟子程序void LCD_udelay_50uS(uint n);/-延迟子程序50微秒初始化(无效){LCD_udelay_10us(20);LCD_uwrite_10us(0x38);//-设置8位格式,2行,5x7 LCD_2;delay_10us(5);LCD_uwrite_u命令(0x0c);//-整体显示,关闭光标,不闪烁LCD 不闪烁LCD_延时延时10us(5);LCD_写写写命令(0x06);///-设置输入模式,增量增量不移位LCD_延时延时10us 10us(5);LCD_写写写命令(0x01);///-清除LCD_延时延时50uS在屏幕上的显示屏(40);}//将无效的LCD命令写入lcd602_写写写的命令(uchar dat){LCD_u写写写的命令(uchar dat){LCD_延迟延迟_10us(5;5);LCD液晶显示无Rs=0;//命令LCD液晶显示u 10us(5);LCD_Rs=0;//命令LCD_LCD_ _在LCD_Udb=dat;LCD_uDelay_10us(5);LCD_ue=1;//允许LCD_delay_10us(5);LCD_ue=0;}/-将无效的LCD写入LCD1602_写数据(uchar dat){LCD_u延时_10us(5);LCD_urs=1;//数据液晶显示液晶显示u RW=0;//数据液晶显示显示uu RW=0;//向LCD写入液晶显示的DB=dat;LCD_延迟延时10us 10us(5;5);LCD_E=E=1;//将无效的LCD写入LCD_延迟_延迟_(u (5);LCD液晶显示LCD_u延迟10us(5);LCD_E=0;}/-设置显示位置无效LCD_uxy(uchar (x,uchary y){uchar地址;如果(y==1){address=0x80+x;/-第一行位置}其他{地址=0xc0+x;///第二行位置}液晶显示器延时延时延时10us(5);LCD液晶显示写写命令(地址);}/-显示字符功能功能voidlcd xdisp char(ucharx,uchary y,uchardat的uchar dat)//--液晶显示器显示器的disp char(0,1,0x38 0x38);//-显示8{LCD显示液晶显示器xxxxx0,1,0x38);//-显示8{LCD[液晶显示设设设设设设设设设设设设设设设设设(x,y);液晶显示器延迟_10us(5);LCD_write_u2;Data(DAT);}/-显示字符串函数void LCD_uP_u3;string (uchar x,uchar y,uchar*s){LCD_uxset_xy(x,y);LCD_uuDelay_10us(5);while(*s!='\0'){LCD_2;write_uData(*s);s++;}//∠s++;}/∠s++/>check_Busy()///实践证明,在我的LCD1602上,check Busy命令的通过率很低,LCD正常使用。
1、关于1602液晶的电气参数一般市场上的1602液晶使用的驱动器为HD44780U或HD44780S,市场上大部分液晶用的是后者。
HD44780S的供电电压为5V±10%,而HD44780U的供电电压为2.7V~5.5V。
也就是说,绝大部分1602液晶只能工作在5V电压下,其供电电压必须为5V。
经过试验发现,1602液晶的供电虽然必须为5V,但其控制总线和数据总线可以用3.3V电平(因为对于TTL电平,一般大于2.5V以上都算高电平,不过最可靠的是大于3.6V),只不过在3.3V电平下,数据的通信速度会大大降低,这一点需要在写驱动时注意。
需要时,可以将MCU的IO配置为漏极开路方式,用上拉电阻拉到5V电平;实在不能配置为漏极开路方式时,请查阅MCU的电气参数,在允许的条件下,直接使用电阻弱上拉也可以。
2、硬件连接1602液晶可以使用4位或8位通信模式,通信可以是双向的或单向的,双向通信主要是为了读取LCD忙标志和AC地址寄存器和DDRAM和CGRAM中的值,一般用处不大,因为1602不支持点阵绘图功能。
在连接时,注意4位通信方式下,LCD只使用DB7~DB4,一般情况下会使用MCU 某端口的高4位或低4位与之连接,注意写驱动时在必要的情况下对端口的其它几位要保护,防止破坏其数据;当然如果没有使用其它4位时则不必要保护(奇怪,不使用其它4位干嘛用4位通信方式嘛?)。
还要注意的是,如果需要双向通信,则必须选择既能做输入又能做输出的IO口,特别是对于RS、RW和E这三条控制线,若能选择支持位寻址的IO口则可以方便编程。
3、底层驱动问题通用1602液晶的时序如图:(1)、写时序(2)、读时序总的说来,按照这个时序图来编写驱动程序是不会出什么问题的,只是要深刻理解时序图中各参数的涵义。
编程中要特别关注E这根控制线。
写操作的时序应该是:①、RS=0(写指令寄存器)或RS=1(写数据寄存器);②、RW=0(写操作);③、将数据写到数据线上;④、E=1;⑤、E=0 。
实用标准文档文案大全MS基于1602字符型液晶显示器的显示系统姓名:杨越班级:电子11-1学号:110400104一、实习目的(1)了解飞思卡尔单片机的基本原理,掌握其基本的工作流程。
(2)了解LCD1602的基本原理及用法。
(3)能够熟练使用CodeWarrior软件编写C语言程序,使用BDM仿真器下载程序。
(4)能够熟练焊接电路板。
二、实验设备与器件CodeWarrior软件,BDM仿真器,万用电路板,飞思卡尔单片机,LCD1602液晶显示器,三、实验内容内容:利用飞思卡尔单片机制作基于1602字符液晶显示器的显示系统要求:用四个按键控制,按下第一个按键显示1,按下第二个按键显示2,以此类推。
(1)LCD1602液晶显示器的原理:1602共16个管脚,但是编程用到的主要管脚不过三个,分别为:RS(数据命令选择端),R/W(读写选择端),E(使能信号);以后编程便主要围绕这三个管脚展开进行初始化,写命令,写数据。
以下具体阐述这三个管脚:RS为寄存器选择,高电平选择数据寄存器,低电平选择指令寄存器。
R/W为读写选择,高电平进行读操作,低电平进行写操作。
E端为使能端,后面和时序联系在一起。
除此外,D0~D7分别为8位双向数据线。
操作时序:注:关于E=H脉冲——开始时初始化E为0,然后置E为1,再清0.读取状态字时,注意D7位,D7=1,禁止读写操作;D7=0,允许读写操作;所以对控制器每次进行读写操作前,必须进行读写检测。
(即后面的读忙子程序)指令集:LCD_1602 初始化指令小结:0x38设置16*2显示,5*7点阵,8位数据接口0x01清屏0x0F开显示,显示光标,光标闪烁0x08只开显示0x0e开显示,显示光标,光标不闪烁0x0c开显示,不显示光标0x06地址加1,当写入数据的时候光标右移0x02地址计数器AC=0;(此时地址为0x80)光标归原点,但是DDRAM中断内容不变0x18光标和显示一起向左移动(2)飞思卡尔单片机的功能及特点:MC9S12XS128是 16 位单片机,由 16 位中央处理单元(CPU12X)、128KB 程序、Flash(P-lash)、8KB RAM、8KB 数据Flash(D-lash)组成片内存储器。
前面总算走完了对AVR MEGA16这块单片机的一些基本的应用方式了,这时候大家对AVR的一些内部资源比如定时器,ADC,最主要的IO口的使用方式应该有了一个虽比较粗浅但是却比较形象的认识了。
这节我们来看使用单片机的另外一大主题,就是用单片机来实现芯片控制。
在前面的数码管显示一文中,就已经涉及到了用单片机来控制芯片为我们工作,CEPARK AVR开发板,为了达到增强驱动能力和节省IO口的作用,运用了移位寄存器74HC595来驱动两个四位八段数码管,是一个十分有创意的设计。
但是前面的内容重心还是集中于对AVR的IO口的控制,所以,我们从这节开始要正式逐渐深入的接触各种芯片了。
先做个引子。
单片机是一种微控制器,本身内部集成了数种资源比如CPU、内存、内部和外部总线系统,目前大部分还会具有外存。
他的主要任务是利用各种资源实现电平控制,可以以此控制与它相连的下级系统,广泛用于工业自动控制领域。
我们就从这句话出发,首先单片机用来做控制用的,而且是利用的是本身的内部资源。
但是,它的功能再强大,资源再丰富也总有一个上限,总有枯竭的一天。
所以我们常常利用单片机外接芯片来弥补或者增强单片机的功能来完成我们所需功能的电路。
比如程序存储器不足,可以外接外部存储器,比如单片机内部中断级不足,可以外接中断控制器等等。
大家可以从这个角度来理解芯片控制的意义罢。
今天我们用AVR单片机来实现对LCD1602液晶显示芯片的控制。
首先从这个名字讲起,LCD:英文全称为Liquid Crystal Display,即为液态晶体显示,也就是我们常说的液晶显示了。
(平时老说LCDLCD,可能大家也都不怎么注意过这个全称吧,呵呵,当增加词汇量了)1602则是表示这个液晶一共能显示2行数据,每一行显示16个字符。
这个就是LCD1602的全部来由。
液晶显示的使用有多广泛我就不多说了,LCD1602好像10元左右就可以拿到了的,不算贵。
我们来看看现在市面都有哪些样子的1602,下面从网上搜罗了几个(我手上的这个是蓝色背光白色字体的):其实显而易,见也就是背光和字体的颜色不一样罢,不过老实说,蓝色背光的1602看上去显得确实比较亮,也许是人眼视觉的关系。
LCD1602帮助手册正面图背面图正面图为第一图,管脚应排列在左上方,左边第一脚为管脚1,向右依次为2,3,4………15,16。
背面一般也有标注,并且附带了管脚对应的作用。
其中第三脚VO为对比度调节脚,一般外接滑动变阻器,调节输入的电压,来调节明暗度(可以直接接地,不过直接接地,需要斜着屏幕,才能看见LCD是否显示字符,正面看都是黑黑的一格一格的)。
15,16角一般为背光LED灯源,一个接VCC(一般为15脚),一个接GND(一般为16脚),最好接入限流电阻,不接也可使用,不过会缩短寿命,这两角可以不接,如果不接,在黑暗的室内,显示效果欠佳。
管脚编号如下图所示:管脚对应符号对LCD的操作,有四种操作,分别为:读状态,读数据,写指令和写数据,一般常用的为读状态,写指令和写数据。
操作图如下:当RS端为低电平,RW端为高电平,E为高电平是,对LCD1602的操作为读状态操作,这时,可以对LCD的状态进行读取,读取通过D0~D7的端口读取。
其他操作相似,对照图,即可完成,但是有个读写时序的要求,时序图见下图:读操作时序对LCD进行读操作时,先将RS置为低电平(0V),然后将RW样置为高电平(+5V),然后有个tsp1的延迟(但是一般这个延迟为ns级,一个单片机的指令周期通常都为us级,一般不需要特别延迟,如果程序有一定错误的时候,可以稍微延迟一下),然后再将E置为1,然后延迟td时间(td一般也为ns级,可以适当延迟一点点),然后读取D0~D7的数据。
写操作也是类似的,将RS,RW,E端口进行相应操作即可完成,写数据和写命令的操作,延迟的时间都很短,程序不稳定的话,可以延迟个1us,一般就可以了。
LCD1602的指令有11条,如下图:(指令表)从之前的操作来看,对照此表,不难看出,指令表的前8条都是命令指令,RS,RW都为0,所以操作时,都是写命令操作,D7~D0的数值的不同,代表了操作的不同,比如D0~D7为0x01时,对LCD的操作命令就为清屏显示,第二条指令为光标返回指令,在D0处有个※标记,这表示,不论此位的数据为1还是为0,对此命令都无效,即D0~D7端口写入0x20为光标返回指令,D0~D7端口写入0x03,此命令也为光标返回指令。
控制接口说明:1、基本操作时序:1.1读状态:输入:RS=L,RW=H,E=H 输出:D0—D7=状态字1.2写指令:输入:RS=L,RW=L,D0—D7=指令码,E=高脉冲输出:无1.3读数据:输入:RS=H,RW=H,E=H 输出:D0—D7=数据1.4写数据:输入:RS=L,RW=L,D0—D7=数据,E=高脉冲输出:无2、状态字说明3、RAM地址映射图控制器内部带有80×8位(80字节)的RAM缓冲区,对应的关系如下图所示:4、指令说明4.1初始化设置显示模式设置控制器内部设有一个数据地址指针,可通过它们来访问内部的全部80字节RAM。
数据指针设置:延时15ms写指令38H(不检测忙信号)延时5ms写指令38H(不检测忙信号)延时5ms写指令38H(不检测忙信号)(以后每次写指令、读/写数据操作之前均需检测忙信号)写指令38H:显示模式设置写指令08H:显示关闭写指令01H:显示清屏写指令06H:显示光标移动设置写指令0CH:显示开及光标设置原文出自:/47okey/blog/item/809c7cfc8dd6541c08244d60.html程序分析:、程序清单:RS BIT P3.7 ;RS1602液晶的数据命令控制端,高电平为数据,低电平为指令;这3位是液晶屏的控制信号,连接方式由具体硬件而定RW BIT P3.6;RW1602液晶的读写控制端,高电平为读,低电平为写E BIT P3.5;E1602的使能端ORG 0000H;程序开始LJMP MAIN;跳转到MAIN处执行程序ORG 0100H;数据存放地址MAIN:LCALL DISPLAY;调用液晶显示子程序LCALL D1S;延时1秒LJMP MAIN;返回到MAIN处;-------液晶显示的子程序(显示前先格式转换)---------------------------------------DISPLAY:LCALL INITIAL;调用初始化子程序MOV A, #10000000B ; LINE1: DB 'This is a TEST',00H,设置第一行的显示地址LCALL WRITE_INSTRUCTION;调用写液晶命令子程序MOV DPTR, #LINE1;将表格1送到DPTR中LCALL PR_STRING;调用写字符子程序LCALL WRITE_LCDDATA;调用写液晶数据子程序MOV A, #11000000B ; LINE2: DB'Design by 47okey',00H,设置第二行的显示地址LCALL WRITE_INSTRUCTION;调用写液晶命令子程序MOV DPTR, #LINE2;将表格2送到DPTR中LCALL PR_STRING;调用写字符子程序RET;---液晶屏初始化,具体请参考资料-------------------------------------------------initial: MOV A, #01H;01H这个指令是设置1602的清屏操作LCALL WRITE_INSTRUCTION;调用液晶命令写入子程序MOV A, #38H;38H这个指令是设置1602的显示模式,2行,16个字符/行LCALL WRITE_instruction;调用液晶命令写入子程序MOV A, #0FH;0FH这个指令是设置1602的显示、显示光标、光标闪烁LCALL WRITE_instruction;调用液晶命令写入子程序MOV A, #06H;06H这个指令是设置1602的输入方式,增量不移位LCALL WRITE_instruction;调用液晶命令写入子程序RET;----写液晶指令的子程序------------------------------------------WRITE_instruction: MOV P1, A;将累加器A中的命令送到P0口做输出数据CLR RS ;写入控制命令,RS低电平为命令CLR RW;读写控制端,RW,低电平为写,就是写命令CLR E;使能端,E发生电平跳变就开始写入命令LCALL DELAY;调用延时子程序,也就是下面写的判断液晶模块是否处于忙状态SETB E;使能端,E发生电平跳变完成,写入命令完成RET;----写液晶数据的子程序---------------------------------------------write_lcddata: MOV P1, A;将累加器A中的数据送到P0口做输出数据SETB RS ;写入显示数据,RS高电平为数据CLR RW;读写控制端,RW低电平为写数据CLR E;使能端E,低电平LCALL DELAY ;判断液晶模块是否忙?SETB E;使能端,E发生电平跳变完成,写入数据完成RET;-----写行字符的子程序---------------------------------------------------------------PR_STRING: CLR A;将累加器A中的内容做清零操作MOVC A, @A+DPTR;查表,将查到的数据送到累加器A中去JZ END_PR;JZ为累加器A判0转移指令,若A 中不为0则往下执行程序,为0则跳转到END_PR处LCALL WRITE_LCDDATA;调用写液晶数据的的子程序INC DPTR;DPTR地址加一LJMP PR_STRING;跳转到PR_STRING处执行程序END_PR: RET;----查看液晶忙碌信号的子程序---------------------------------------------------------DELAY: MOV P1,#0FFH ;判断液晶显示器是否忙的子程序 CLR RS;RS低电平,写命令SETB RW;RW高电平,读液晶内部的数据CLR E;使能端低电平NOP;延时一个机器周期SETB E;使能端高电平JB P1.7,DELAY ;如果P1.7为高电平表示忙就循环等待,JB判bit转移,bit为1则跳转,否则顺序执行程序 RET;---1mS延时(按12MHZ算)-----------------------------------------------------------------D1mS: MOV R7,#250LOOP0: NOPNOPDJNZ R7,LOOP0RET;----1S延时(按12MHZ算)-----------------------------------------------------------------D1S: Mov R6,#4LOOP2: mov R5,#250LOOP1: LCALL D1mSDJNZ R5,LOOP1DJNZ R6,LOOP2RET;--------------------------------------------------------------------------------------LINE1: DB 'This is a TEST !',00HLINE2: DB 'Design by 47okey',00HEND。
LCD1602液晶显示实验1.实验原理1.1 基本原理1.1.1 1602字符型LCD简介字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块。
1.1.2 1602LCD的基本参数及引脚功能1602LCD分为带背光和不带背光两种,基控制器大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别,两者尺寸差别如下图1-2所示:图1-2 1602LCD尺寸图1.1602LCD主要技术参数:显示容量: 16×2个字符芯片工作电压: 4.5~5.5V工作电流: 2.0mA(5.0V)模块最佳工作电压: 5.0V字符尺寸: 2.95×4.35(W×H)mm2.引脚功能说明:1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表:表1-3引脚接口说明表编符号引脚说明编号符号引脚说明号1 VSS 电源地9 D2 数据2 VDD 电源正极10 D3 数据3 VL 液晶显示偏压11 D4 数据4 RS 数据/命令选择12 D5 数据5 R/W 读/写选择13 D6 数据6 E 使能信号14 D7 数据7 D0 数据15 BLA 背光源正极8 D1 数据16 BLK 背光源负极1.1.3 1602LCD的指令说明及时序1602液晶模块内部的控制器共有11条控制指令,如表1-4所示:表1-4 控制命令表序号指令RS R/W D7 D6 D5 D4 D3 D2 D1 D01 清显示0 0 0 0 0 0 0 0 0 12 光标返回0 0 0 0 0 0 0 0 1 *3 置输入模式0 0 0 0 0 0 0 1 I/D S4 显示开/关控制0 0 0 0 0 0 1 D C B5 光标或字符移位0 0 0 0 0 1 S/C R/L * *6 置功能0 0 0 0 1 DL N F * *7 置字符发生存贮器地址0 0 0 1 字符发生存贮器地址8 置数据存贮器地址0 0 1 显示数据存贮器地址9 读忙标志或地址0 1 BF 计数器地址10 写数到CGRAM或DDRAM)1 0 要写的数据内容11 从CGRAM或DDRAM读数1 1 读出的数据内容1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。
HD44780内置了DDRAM、CGROM和CGRAM。
CGROM和CGRAM就是内置192个常用字符产生器,用户自定义的字符产生器RAM DDRAM就是显示数据RAM,用来寄存待显示的字符代码。
共80个字节,其地址和屏幕的对应关系如下表:显示位置: 1 2 3 4 5 6 7 8 (40)第一行: 00H 01H 02H 03H 04H 05H 06H 07H ..... 27H第二行: 40H 41H 42H 43H 44H 45H 46H 47H ..... 67H*/1602LCD的RAM地址映射液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。
要显示字符时要先输入显示字符地址,也就是告诉模块在,哪里显示字符,图是1602的内部显示地址。
也就是说想要在LCD1602屏幕的第一行第一列显示一个"A"字,就要向DDRAM的00H地址写入“A”字的代码就行了。
但具体的写入是要按LCD模块的指令格式来进行的,后面我会说到的。
那么一行可有40个地址呀?是的,在1602中我们就用前16个就行了。
第二行也一样用前16个地址。
对应如下:DDRAM地址与显示位置的对应关系图五:LCD1602内部显示地址例如第二行第一个字符的地址是40H,那么是否直接写入40H就可以将光标定位在第二行第一个字符的位置呢?这样不行,因为写入显示地址时要求最高位D7恒定为高电平1,所以实际写入的数据应该是01000000B(40H)+10000000B(80H)=11000000B(C0H)。
/*1602液晶模块内部的控制器共有11条控制指令,如下表序号指令RS R/W D7 D6 D5 D4 D3 D2 D1 D01 清显示0 0 0 0 0 0 0 0 0 12 光标返回0 0 0 0 0 0 0 0 1 *3 置输入模式0 0 0 0 0 0 0 1 I/D S4 显示开/关控制0 0 0 0 0 0 1 D C B5 光标或字符移位0 0 0 0 0 1 S/C R/L * *D3=1移字符D3=0移光标D2=1右移D2=0左移6 功能设置0 0 0 0 1 DL N F * *DL=1总线8位DL=0总线4位N=0显单行N=1显双行F=0 5X7点阵F=1 5X10点阵7 置字符发生器地址0 0 0 1 -字符发生存贮器地址(6位)-8 置数据存贮器地址0 0 1 --显示数据存贮器地址(7位)---9 读忙标志或地址0 1 BF ----计数器地址(7位)---------10 写CGRAM或DDRAM 1 0 --------要写的数据内容(8位------11 读CGRAM或DDRAM 1 1 --------读出的数据内容(8位)-----*/// 51单片机对lcd1602一些基础程序/* 基本操作时序:写指令输入:RS=0,RW=0,E=下降沿脉冲,DB0~DB7=指令码输出:无写数据输入:RS=1,RW=0,E=下降沿脉冲,DB0~DB7=数据输出:无读状态输入:RS=0,RW=1,E=1 输出:DB0~DB7=状态字读数据输入:RS=1,RW=1,E=1 输出:DB0~DB7=数据/*//*lcd_1602指令:指令位D7 D6 D5 D4 D3 D2 D1 D0功能设置0 0 1 DL N F * *DL=1总线8位DL=0总线4位N=0显单行N=1显双行F=0 5X7点阵F=1 5X10点阵lcd_1602指令汇总0x28 设置16*2显示,5*7点阵,4位数据接口0x38 设置16*2显示,5*7点阵,8位数据接口0x01 清屏,光标复位到地址00H位置0x02 光标归原点,DDRAM中内容不变,地址计数器AC=0;(此时地址为0x80)0x0F 开显示,显示光标,光标闪烁0x0e 开显示,显示光标,光标不闪烁0x0c 开显示,不显示光标0x08 只开显示0x06 地址加一,当写入数据的时候光标右移设定显示屏或光标移动方向指令0x18 字符全部左移一格,但光标不动0x1c 字符全部右移一格,但光标不动0x10 光标左移1格,且AC值减10x14 光标右移1格,且AC值加1*/#include <intrins.h>#define dataport P1sbit RS=P2^ 6;sbit RW=P2^5;sbit EN=P2^4;void waitfor() //检测忙信号函数{dataport=0xff;RS=0;RW=1; //选择指令寄存器读操作RS=0指令RS=1数据; RW=0写RW=1读EN=1; //使能操作while(dataport&0x80); //如果最高位是1 表示1602正忙原地踏步忙完后芯片会将高位拉低EN=0;}void writedata(unsigned char dataw) //写数据到LCD1602{waitfor(); //测忙RS=1;RW=0; //选择数据寄存器写操作RS=0指令RS=1数据; RW=0写RW=1读dataport=dataw; //将数据送到数据口EN=1;EN=0; //使能下降沿脉冲}void writecmd(unsigned char cmd) //写命令到LCD1602{waitfor(); //测忙RS=0;RW=0; //选择指令寄存器写操作dataport=cmd; //将数据送到数据口EN=1;EN=0; //使能下降沿脉冲}void init(void) // 初始化函数{writecmd(0x38); //功能设定8位数据传输双行显示设置工作方式:0x28=4位总线字符两行显示,0x38=8位总线字符两行显示writecmd(0x0c); //显示器开关writecmd(0x01); //清屏writecmd(0x06); //字符进入模式每进入一个字符光标向右移动一格原有字符不动}void location(unsigned char x,unsigned char y) //坐标函数{unsigned char temp;temp=x&0x0f; //只要x数据的后四位if(y){temp=temp|0x40;} //第一行为0 第二行为1 如果y=1则地址加0x40temp|=0x80; //DDRAM地址的命令DB7为一writecmd(temp);}void DisplayOneChar(unsigned char x,unsigned char y,unsigned char dataw) //显示一个字符函数{location(x,y);writedata(dataw);}void displaylistchar(unsigned char x,unsigned char y,unsigned char *p) //显示字符串{while(*p) //当一个字符型数组读完时*P指的为零{displayonechar(x,y,*(p++));x++;}}void WriteCgram(unsigned char address,unsigned char *p) //写CGRAM的数据{unsigned char i=8;writecmd(address); //CGRAM里的地址初始值0x40 每次加0x80while(i--){writedata(*p);p++;}}void DisplayOneChar(unsigned char x,unsigned char y,unsigned char address,unsigned char *p) //显示一个自定义字符{unsigned char i=8;writecmd(address); //CGRAM里的地址初始值0x40 每次加0x08while(i--){writedata(*p);p++;}location(x,y); //设定要显示的位置writedata((address&=0x3f)/0x08); //要从CGRAM中读出数据在1602上显示搞了半天发现CGRAM里的地址} //和DDRAM里的地址有上面的转换关系void displynumber(unsigned char x,unsigned char y,unsigned long num) //显示一个整数{unsigned int number[8];int k,gh;for(k=0;;k++){*(number+k)=(unsigned int)(num%10);//强制类型转换num=num/10;if(num==0)break;}for(gh=k;gh>=0;gh--){displyonechar(x,y,(*(number+gh)+48));x++;}}//字型码uchar code nian[]={0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02};// "年"uchar code yue[]={0x0f,0x09,0x0f,0x09,0x0f,0x09,0x0b,0x11};// "月"uchar code ri[]={0x1f,0x11,0x11,0x1f,0x11,0x11,0x11,0x1f};// "日"//显示汉字displyonecharacter(0,0,0x40,nian);displyonecharacter(1,0,0x80,yue);displyonecharacter(1,0,0xc0,ri);。
lcd1602程序流程图lcd1602程序流程图1、引脚3(对⽐调整电压)接正电源时对⽐度最低,接地时对⽐度最⾼,通常通过⼀个10k的电位器相连后接地,上电后需要对电位器进⾏调整以显⽰出相应的字符(就像调节电视的对⽐度使图像清晰,这⾥是使字符清晰)2、D0~D7为8为数据总线,⽤于与单⽚机之间的数据传送了解了引脚功能后,我们再来看其内置芯⽚关于HD44780HD44780内部含有DDRAM,CGROM,CGRAM下⾯我来简单介绍⼀下这三个存储器DDRAM是⽤于寄存待显⽰字符代码的,其内部带有80字节的RAM 缓冲区,与LCD屏幕的位置⼀⼀对应。
通常我们只使⽤前16个地址(两⾏32个),这样⼀来,我们便可以将这32个地址当作是我们的坐标,⽐如要在DDRAM的02H 地址(对应的是屏幕第⼀⾏第三个)显⽰字符“A”,我们就可以分两步⾛,⾸先⽤程序先找到“坐标点”,也就是将地址转到02H(具体如何不做详细说明),然后在这个位置写⼊“A”,写⼊地址和数据都是通过D0~D7实现的,详细的程序在⽂章的后⾯举例说明。
CGROM与CGRAM是LCD内部固化的字模存储器,这相当于芯⽚内部划出的⼀块区域,CGROM⾥⾯存放着我们⽇常所使⽤的⼀些字符(192个),⽽CGRAM则允许⽤户⾃定义⼀些字符(8个)。
具体对应关系如下,0x00~0x0F就是⽤户⾃定义的CGRAM区。
再回到之前的问题,在DDRAM的02H地址显⽰字符“A”,⾸先通过程序找到地址02H,然后在该地址写⼊41H,从图中也可看出该位置对应的字符就是“A”。
我们再来理⼀理这个过程,有关字符显⽰,⾸先便是找到DDRAM 中我们所要显⽰位置对应的地址,接着便是在这个地址写⼊⼀个地址(单⽚机中的间接寻址),LCD根据这个地址在CGROM中找到对应的字符,然后在02H这个位置显⽰出来,这个过程也到此结束。
由于CGROM中的字符代码与PC中的字符代码基本⼀致,通常我们也直接在02H地址直接写⼊“A”,简化了程序设计。
LCD1602学习——Proteus仿真(显⽰操作)学习关键:先看懂液晶操作时序图(写操作:写命令、写数据)读状态输⼊RS=L,R/W=H,E=H输出D0—D7=状态字写指令输⼊RS=L,R/W=L,D0—D7=指令输出⽆码,E=⾼脉冲读数据输⼊RS=H,R/W=H,E=H输出D0—D7=数据写数据输⼊RS=H,R/W=L,D0—D7=数据,E=输出⽆⾼脉冲由时序图可知,写操作时(包括写指令、写数据),RS=0;RW=0;再进⾏I/O⼝写操作,然后使能端⼝完成⼀次⾼脉冲(——⾼——低),这是液晶就会执⾏写操作的内容;1602液晶模块内部的控制器共有11条控制指令,如表10-14所⽰:序号指令RS R/W D7D6D5D4D3D2D1D01清显⽰00000000012光标返回000000001*3置输⼊模式00000001I/D S4显⽰开/关控制0000001D C B5光标或字符移位000001S/C R/L**6置功能00001DL N F**7置字符发⽣存贮器地址0001字符发⽣存贮器地址8置数据存贮器地址001显⽰数据存贮器地址9读忙标志或地址01BF计数器地址10要写的数据内容10写数到CGRAM或DDRAM)11读出的数据内容11从CGRAM或DDRAM读数思路:1、控制液晶显⽰输出,需要对其进⾏写数据(写数据前,同样需要先告诉液晶你下⼀步要在哪⾥写,因此写数据前,要写命令先设定数据指针)程序设计⽅式:write_com();//写命令函数,write_date();//写数据函数2、由于要先进⾏初始化,(初始化实际就是对液晶写指令,告诉其⼯作⽅式等)因此初始化函数⾥⾯⾃然就需要调⽤写命令函数write_com();程序结构如下:int init(){ EN = 0; write_com(0X38);//设置16*2显⽰,5*7点阵,8位数据接⼝ write_com(0X0C);//设置开显⽰,不显⽰光标 write_com(0X06);//写⼀个字符时,整屏右移 write_com(0X01);//显⽰清零 return 0;} 主函数部分程序结构:int main(){ init();//调⽤初始化函数 write_com(0x80);//调⽤写指令函数,设置写数据开始指针(第⼀⾏) for(x=0;x<6;x++)//数据写⼊循环程序 { write_date(table[x]); delay(150); } write_com(0x80+0x40); ;//调⽤写指令函数,设置写数据开始指针(第⼆⾏) for(x=0;x<17;x++)//数据写⼊循环程序 { write_date(table1[x]); delay(150); } while(1);return 0;}完整程序如下:1 #include<reg52.h>2int init(); //声明初始化函数3int write_com(unsigned char);//声明写命令函数4int write_date(unsigned char);//声明写数据函数5int delay(unsigned char);//声明延迟函数6 unsigned char x;7 sbit RS = P1^0;8 sbit RW = P1^1;9 sbit EN = P1^2;10 unsigned char code table[]="HELLO!";11 unsigned char code table1[]="MY name is Terry!";1213int main(void)//主函数14 {15 init();16 write_com(0x80);17for(x=0;x<6;x++)18 {19 write_date(table[x]);20 delay(150);21 }22 write_com(0x80+0x40);23for(x=0;x<17;x++)24 {25 write_date(table1[x]);26 delay(150);27 }28while(1);29return0;30 }3132int init()//初始化函数体33 {34 EN = 0;35 write_com(0X38);//设置16*2显⽰,5*7点阵,8位数据接⼝36 write_com(0X0C);//设置开显⽰,不显⽰光标37 write_com(0X06);//写⼀个字符时,整屏右移38 write_com(0X01);//显⽰清零39return0;40 }4142int write_com(unsigned char com)//写命令的函数体43 {44 RS = 0;45 RW = 0;46 P0 = com;47 delay(5);48 EN = 1;49 delay(5);50 EN = 0;51return0;52 }5354int write_date(unsigned char date)//写数据的函数体55 {56 RS = 1;57 RW = 0;58 P0 = date;59 delay(5);60 EN = 1;61 delay(5);62 EN = 0;63return0;64 }6566int delay(unsigned char xms)67 {68 unsigned char x,y;69for(x=xms;x>0;x--)70for(y=110;y>0;y--);71return0;72 }显⽰输出如下:。
在日常生活中,我们对液晶显示器并不陌生。
液晶显示模块已作为很多电子产品的通过器件,如在计算器、万用表、电子表及很多家用电子产品中都可以看到,显示的主要是数字、专用符号和图形.在单片机的人机交流界面中,一般的输出方式有以下几种:发光管、LED数码管、液晶显示器.发光管和LED数码管比较常用,软硬件都比较简单,在前面章节已经介绍过,在此不作介绍,本章重点介绍字符型液晶显示器的应用。
在单片机系统中应用晶液显示器作为输出器件有以下几个优点:显示质量高由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器(CRT)那样需要不断刷新新亮点.因此,液晶显示器画质高且不会闪烁.数字式接口液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便.体积小、重量轻液晶显示器通过显示屏上的电极控制液晶分子状态来达到显示的目的,在重量上比相同显示面积的传统显示器要轻得多.功耗低相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多.10.8.1 液晶显示简介①液晶显示原理液晶显示的原理是利用液晶的物理特性,通过电压对其显示区域进行控制,有电就有显示,这样即可以显示出图形。
液晶显示器具有厚度薄、适用于大规模集成电路直接驱动、易于实现全彩色显示的特点,目前已经被广泛应用在便携式电脑、数字摄像机、PDA移动通信工具等众多领域.②液晶显示器的分类液晶显示的分类方法有很多种,通常可按其显示方式分为段式、字符式、点阵式等。
除了黑白显示外,液晶显示器还有多灰度有彩色显示等。
如果根据驱动方式来分,可以分为静态驱动(Static)、单纯矩阵驱动(Simple Matrix)和主动矩阵驱动(Active Matrix)三种。
③液晶显示器各种图形的显示原理:线段的显示点阵图形式液晶由M×N个显示单元组成,假设LCD显示屏有64行,每行有128列,每8列对应1字节的8位,即每行由16字节,共16×8=128个点组成,屏上64×16个显示单元与显示RAM区1024字节相对应,每一字节的内容和显示屏上相应位置的亮暗对应。
LCD1602快速显示源程序(附真实序列图)/*********************************************************************** 文件名称: LCD1602.c* 当前版本: 1.0* 功能: LCD1602字符液晶的驱动实现* 作者:杜运福* 完成时间: 2013-01-04* 原始版本: 1.0* 修改人员、时间、版本及修改内容:* 其他说明:**********************************************************************/#ifndef LCD1602_H#define LCD1602_H/* 公共类型定义 */typedef unsigned char uint8;typedef signed char sint8;typedef unsigned short uint16;typedef signed short sint16;typedef unsigned long uint32;typedef signed long sint32;/** 函数名称:LCD_WriteCMD* 功能描述:写单个命令* 输入参数:CMD 命令字节,低7位有效* 输出参数:无* 返回值:0 执行成功,-1 执行失败* 其它说明:* 修改日期修改人修改内容* -----------------------------------------------* XXXX-XX-XX XXXX XXXX*/sint8 LCD_WriteCMD(uint8 CMD);/** 函数名称:LCD_SetPos* 功能描述:设置显示位置* 输入参数:XPos 行位置1,2;YPos 列位置,1~16* 输出参数:无* 返回值:0 执行成功,-1 执行失败* 其它说明:* 0x00----------------0x0f 0x10-------0x27 第一行(一次显示16个字符)* 0x40----------------0x4f 0x50-------0x67 第二行* 修改日期修改人修改内容* -----------------------------------------------* XXXX-XX-XX XXXX XXXX*/sint8 LCD_SetPos(uint8 XPos, uint8 YPos);/** 函数名称:LCD_WriteByte* 功能描述:写入单个字节显示数据* 输入参数:Byte 待写入字节数据* 输出参数:无* 返回值:0 执行成功,-1 执行失败* 其它说明:* 修改日期修改人修改内容* -----------------------------------------------* XXXX-XX-XX XXXX XXXX*/sint8 LCD_WriteByte(uint8 Byte);/** 函数名称:LCD_DispChar* 功能描述:指定位置显示单个字符* 输入参数:XPos 行位置1,2;YPos 列位置,1~16* ch 待显示字符* 输出参数:无* 返回值:0 执行成功,<0 执行失败* 其它说明:当行或列位置不合法时,不设置显示位置,直接在当前光标处显示 * 修改日期修改人修改内容* -----------------------------------------------* XXXX-XX-XX XXXX XXXX*/sint8 LCD_DispChar(uint8 XPos, uint8 YPos, char ch);/** 函数名称:LCD_DispString* 功能描述:指定位置显示字符串* 输入参数:XPos 行位置1,2;YPos 列位置,1~16* pStr 待显示字符串首地址* 输出参数:无* 返回值:0 执行成功,<0 执行失败* 其它说明:当行或列位置不合法时,不设置显示位置,直接在当前光标处显示 * 修改日期修改人修改内容* -----------------------------------------------* XXXX-XX-XX XXXX XXXX*/sint8 LCD_DispString(uint8 XPos, uint8 YPos, const char *pStr);/** 函数名称:LCD_Init* 功能描述:初始化LCD1602* 输入参数:无* 输出参数:无* 返回值:0 执行成功,-1 执行失败* 其它说明:8位数据总线模式、5*7点阵字符、AC自增、屏不移动、光标不显示、不闪烁 * 常用命令:0x38:16*2显示,5*7点阵显示字符,8位数据;指令执行时间40us* 0x0C:开显示,关光标 40us* 0x08:关显示,关光标 40us* 0x06:写完数据自动右移光标,普通情形,从左向右显示 40us* 0x04:写完数据自动左移光标,可以从右向左显示 40us* 0x01:清除显示内容,即清屏 1.64ms* 0x02:使光标还回起始位置 1.64ms* 0x18:屏幕上所有字符同时左移一格,适合滚动显示 40us* 0x1C:屏幕上所有字符同时右移一格,适合滚动显示 40us* 修改日期修改人修改内容* -----------------------------------------------* XXXX-XX-XX XXXX XXXX*/sint8 LCD_Init(void);#endif /* end LCD1602_H *//*********************************************************************** 文件名称: LCD1602.c* 当前版本: 1.0* 功能: LCD1602字符液晶的驱动实现* 作者:杜运福* 完成时间: 2013-01-04* 原始版本: 1.0* 修改人员、时间、版本及修改内容:* 其他说明:**********************************************************************/#include <reg52.h>#include <intrins.h>#include "LCD1602.h"/* LCD1602引脚定义 */#define LCD_CTRL P2 /* LCD控制口 */#define EN 0x80 /* P2.7 */#define RS 0x40 /* P2.6 */#define RW 0x20 /* P2.5 */#define LCD_DATA P0 /* LCD数据口 */#define LCD_DATAIN_SET LCD_DATA=0xFF /* 数据口输入设置宏 *//* 控制线置位与复位带参宏定义 */#define SET(X) LCD_CTRL |= (X)#define RESET(X) LCD_CTRL &= ~(X)/* 读取LCD忙状态 BF bit7 */#define LCD_STATE LCD_DATA & 0x80/* 延时1us宏定义 */#define NOP() _nop_()/** 延时N毫秒*/static void DelayNms(int N){int i = 0;while (N--){for (i = 0; i < 75; i++){}}}/* 等待LCD空闲,BF=0 */static void LCD_WaitIdle(void){uint8 State = 0;/* 读BF时序建立 */RESET(RS);SET(RW);SET(EN);/* 设置BF对应引脚为输入 */LCD_DATAIN_SET;/* 等待BF=0,LCD空闲 */while ((State = LCD_STATE)!=0);/* 拉低LCD使能 */RESET(EN);}/* 写一个字节命令 */sint8 LCD_WriteCMD(uint8 CMD){/* 若为无效命令,则直接返回 */if ((CMD & 0x3F)== 0){return -1;}LCD_DATA = CMD;RESET(RS);RESET(RW);SET(EN);RESET(EN); /* 产生下降沿,启动写入操作 */LCD_WaitIdle(); /* 等待LCD空闲 */return 0;}/* 设置显示位置 */sint8 LCD_SetPos(uint8 XPos, uint8 YPos){uint8 Pos = 0;if ((XPos != 1) && (XPos != 2)) /* 判断行坐标是否合法 */ {return -1;}if (YPos > 40) /* 每行有40个地址 */{return -1;}if (XPos == 1) /* 第一行 */{Pos = 0x00 + YPos -1;}else /* 第二行*/{Pos = 0x40 + YPos -1;}LCD_DATA = Pos | 0x80;RESET(RS);RESET(RW);SET(EN);RESET(EN); /* 产生下降沿 */LCD_WaitIdle(); /* 等待LCD空闲 */return 0;}/* 写入一个字节数据 */sint8 LCD_WriteByte(uint8 Byte){if (Byte == 0){return -1;}LCD_DATA = Byte;SET(RS);RESET(RW);SET(EN);RESET(EN); /* 产生下降沿 */LCD_WaitIdle(); /* 等待LCD空闲 */return 0;}/* 指定位置显示一个字符 */sint8 LCD_DispChar(uint8 XPos, uint8 YPos, char ch){sint8 ret = 0;ret += LCD_SetPos(XPos, YPos);ret += LCD_WriteByte((uint8)ch);return ret;}/* 指定位置显示一个字符串 */sint8 LCD_DispString(uint8 XPos, uint8 YPos, const char *pStr) {sint8 ret = 0;sint8 Cnt = 0;ret += LCD_SetPos(XPos, YPos);/* 逐个显示字符,最多可以显示41-YPos个字符(含超出一屏的内容)例:YPos=1,则Cnt范围为0~39 */while ((pStr[Cnt] != '\0') && (Cnt <= 40-YPos)){ret += LCD_WriteByte((uint8)pStr[Cnt]);Cnt++;}if (Cnt + YPos > 40) /* 字符串过长!! */{ret = -1;}return ret;}/* LCD1602初始化 */sint8 LCD_Init(void){/* 上电等待LCD硬件自动复位完成,不少于10ms */DelayNms(10);/* 关显示 */LCD_WriteCMD(0x08);/* 功能设置,两行显示、5*7点阵字体、8位数据总线 */LCD_WriteCMD(0x38);/* 设置输入模式,AC自动加1,显示不移位,光标自动移位 */ LCD_WriteCMD(0x06);/* 开显示,关光标,关闪烁 */LCD_WriteCMD(0x0C);/* 清显示,清除DDRAM,光标归位 */LCD_WriteCMD(0x01);return 0;}/** 文件名称: main.c* LCD1602模块测试程序*/#include <reg52.h>#include <intrins.h>#include "LCD1602.h"/* 延时N个10us */static void DelayN10us(uint16 N){while (N--);}int main(){LCD_Init();while(1){LCD_DispString(2,2,"Welcome!!"); DelayN10us(65535);DelayN10us(65535);LCD_WriteCMD(0x01);LCD_DispString(2,2,"Hello!!"); DelayN10us(65535);DelayN10us(65535);LCD_WriteCMD(0x01);//DelayN10us(65535);}return 0;}写清屏命令0x01序列图:写模式设置命令0x38序列图:写显示地址序列图:写一字节数据序列图:注:以上序列图为本人亲测!!。
2.4.4 液晶显示器1602介绍(1)1602LCD主要技术参数显示容量:16×2个字符芯片工作电压:4.5—5.5V工作电流:2.0mA(5.0V)模块最佳工作电压:5.0V字符尺寸:2.95×4.35(W×H)mm(2)引脚功能说明1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表2-1所示:编号符号引脚说明编号符号引脚说明1 VSS 电源地9 D2 数据2 VDD 电源正极10 D3 数据3 VL 液晶显示偏压11 D4 数据4 RS 数据/命令选择12 D5 数据5 R/W 读/写选择13 D6 数据6 E 使能信号14 D7 数据7 D0 数据15 BLA 背光源正极8 D1 数据16 BLK 背光源负极表2-1:引脚接口说明表第1脚:VSS为地电源。
第2脚:VDD接5V正电源。
第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。
第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。
第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。
当RS 和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。
第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。
第7~14脚:D0~D7为8位双向数据线。
第15脚:背光源正极。
第16脚:背光源负极。
(3)1602LCD的指令说明及时序1602液晶模块内部的控制器共有11条控制指令,如表2-2所示:序号指令RSR/WD7 D6 D5 D4 D3 D2 D1 D01 清显示0 0 0 0 0 0 0 0 0 12 光标返回0 0 0 0 0 0 0 0 1 *3 置输入模式0 0 0 0 0 0 0 1I/DS4 显示开/关控制0 0 0 0 0 0 1 D C B5 光标或字符移位0 0 0 0 0 1S/CR/L* *6 置功能0 0 0 0 1 DL N F * *7 置字符发生存贮器地址0 0 0 1字符发生存贮器地址8 置数据存贮器地址0 0 1 显示数据存贮器地址9 读忙标志或地址0 1 BF 计数器地址10 写数到CGRAM或DDRAM)1 0要写的数据内容11 从CGRAM或DDRAM读数1 1读出的数据内容表2-2:控制命令表1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。
LCD1602程序代码和显示流程图LCD1602显示程序代码_ DB P0 //---P0 = DB0〜DB7位LCD_ RS = P2; //--p2.0 = RS 位LCD_ RW = P2; //--p2.1 = RW 位LCD_ E = P2; //-p2.2 = E / /---/--/--定义函数ා 定义uchar unsigned char ා 定义uint unsigned int // //-定义子程序函数void LCD_ Init (void ); //-初始化LCD1602函数void LCD_ write_ Command (uchar command ); //-写指令功能无效LCD 到LCD1602_ write_数据(uchar DAT ); //-将无效的LCD 数据写入LCD1602_ set_ XY (uchar x ,uchar y ); //设置LCD1602的显示位置x (0-16)
,
y(1-2)void LCD_ disp_ Char(uchar x,uchar y,uchar DAT); //-在LCD1602_ disp_ String (uchar x,uchar y,uchar * s)上显示字符无效的LCD;//-在LCD1602上显示字符串// void LCD_ check_ Busy(void); //检查忙功能。
我没有使用此功能,因为通过率非常低。
LCD_ delay_ 10us(uint n); //-一个10微秒的延迟子程序void LCD_ delay_ 50uS(uint n); /-延迟子程序50微秒_ init(无效){LCD_ delay_ 10us(20); LCD_ write_命令(0x38); //-设置8位格式,2行,5x7 LCD_ delay_ 10us(5);LCD_ write_命令(0x0c); //-整体显示,关闭光标,不闪烁LCD_ delay_ 10us(5);LCD_ write_命令(0x06); //-设置输入模式,增量不移位LCD_ delay_ 10us(5);LCD_ write_命令(0x01); // /-清除屏幕上的LCD_ delay_ 50uS(40);} //将无效的LCD指令写入LCD1602_ write_命令(uchar dat){LCD_ delay_ 10us (5);LCD_ Rs = 0; //命令LCD_RW = 0;//写入LCD_ DB = dat; LCD_ delay_ 10us(5); LCD_ E = 1; //允许LCD_delay_10us(5);LCD_ E = 0;} /-将数据无效LCD写入LCD1602_ write_ data(uchar dat){LCD_ delay_ 10us(5);LCD_ Rs = 1; //数据LCD_RW = 0;//写入LCD_ DB = dat; LCD_ delay_ 10us(5); LCD_ E = 1; //允许LCD_delay_10us(5);LCD_ E = 0;} /-
设置显示位置无效LCD_ set_ XY(uchar x,uchar y){uchar地址;如果(y = = 1){地址= 0x80 + X; /-第一行位置} else {地址= 0xc0 + X; //第二行位置} LCD_ delay_ 10us(5); LCD_ write_命令(地址);} /-显示字符函数void LCD_ disp_ char(uchar x,uchar y,uchar dat)//--LCD_ disp_ Char(0,1,0x38); /-显示8 {LCD_ set_ xy(x,y); LCD_ delay_ 10us(5); LCD_ write_ Data(DAT);} /-显示字符串函数void LCD_ disp_ string(uchar x,uchar y,uchar * s){LCD_ set_ xy(x,y); LCD_ delay_ 10us(5); while(* s!='\ 0'){LCD_ write_ Data(* s); s + +;} / /≡S + +;} /≡S + _ check_ Busy()// /实践证明,在我的LCD1602上,检查忙指令的通过率非常低,并且{/ /液晶正常使用。
因此,我不再检查繁忙的功能。
使用do / /时,延迟方法非常易于使用。
我尝试了,用LCD_如果e = 0; // for循环被延迟,普通指令只能完成一次。
清除屏幕指令LCD_ Rs = 0; //需要200个周期才能完成。
LCD_ RW = 1; LCD_ DB = 0xff; LCD_ E = 1; }同时(LCD_ DB == 1);}****************************** / void LCD_ delay_ 10us(uint n)/-10微秒延迟子程序{uint I ,J; for(I = n; I} 0; I-)for(J = 2; J〉0; J-);} void LCD_ delay_ 50uS(uint n)/-50微秒延迟子程序{uint I,J ;对于(I = n; I``0; I-)for(J =
22; J``0; J-); } LCD1602显示程序流程图和句子说明,让LCD1602在输入字符地址之前先显示字符,这是每个字符地址添加一个的原因,在下面的代码中您将了解如何设置地址,如何使地址自动添加一个,如何清除屏幕,如何显示字符,希望您能理解_ E = P2; // LCD1602控制设置位LCD_ RW = P2; // LCD1602控制位sbit LCD_ RS = P2; // lcd1。