1602动态显示
- 格式:wps
- 大小:22.00 KB
- 文档页数:4
动态显示(dynamic display)One, about LCD1602:Before writing the LCD1602 program, understand some of the very important information in the manual. If the information is not clear enough, the program may experience more or less problems.1. pin:1602 a total of 16 pins, but the main pin programming used only three, respectively: RS (data terminal, R/W (selected) to read and write E (select end), enable signal); programming focuses on the three pin expansion initialization, write command, write data.The following three specific description of the pin:RS is the register selection, the high level selects the data register, and the low level selects the instruction register.R/W read and write select, high level read operation, low-level write operation.The E terminal is the enable terminal, and the latter is connected with the timing.In addition, the D0~D7 are 8 bit bidirectional data lines.2. operation sequence:Read and write timing: 1602 in the timing diagram. Timingdiagrams are important. Programming is setting up registers according to the sequence diagram to allow the LCD to work.Two write timing:When we want to write the instruction word and set the working mode of LCD1602: we need to set the RS to low level, RW to low level, then send the data to the data port D0~D7, and finally a high pulse of E pin writes the data.When we want to write data words, on the 1602 to achieve the display: RS needs to be set to high, RW to low, and then send data to the data port D0~D7, and finally the E pin, a high pulse to write data.The difference between writing instructions and writing data is simply that the level of the RS is different. The following is the timing diagram of the LCD1602:RS R/W operation instructions00 write instruction code D0~D701 read and output the D0~D7 status word10 write data D0~D711 read data from D0~D7Note: about E=H pulse - at the start, initialize E to 0, and then set E to 1, and then clear 0.When you read the status word, note that the D7 bit, D7=1, prohibits read-write operations; D7=0 allows read and write operations;Therefore, the read and write test must be carried out before each read and write operation of the controller. (after the read busy subroutine), before executing each instruction, make sure that the busy sign of the module is low, indicating that it is not busy, otherwise the command is invalid.Do{P0=0xff;RS=0;RW=1;EN=1;}while (P0&0x80);3. instruction set: LCD_1602 initialization instructions:0x38 settings, 16*2 display, 5*7 dot matrix, 8 bit data interface0x01 screen, the cursor is reset to the address location 00H0x0F displays, displays the cursor, and blinks the cursor0x08 only displays0x0e displays, displays the cursor, and the cursor does notblink0x0c open display without cursor display0x06 address plus 1, when the data is written, the cursor moves rightThe 0x02 address counter AC=0; (at this time the address is 0x80) the cursor goes to the origin, but the DDRAM interrupt remains unchangedThe 0x18 cursor moves left together with the displayTwo 、 LCD1602 programming flow:The LCD1602 can be written after the above information is understood. Here we divide the program into the following steps:1. defines the LCD1602 pins, including RS, R/W, and E. Here the definition refers to these pins are connected to the microcontroller which I/O port.Examples are as follows:Sbit EN=P2^2;Sbit RW=P2^1;Sbit RS=P2^0;2. display initialization, in this step to initialize and set the display mode and other operations, including the following steps:Set display modedelayedClear display cacheSet display modeThe recommended initialization process is as follows:Delayed 15msWrite instruction 38HDelayed 5msWrite instruction 38HDelayed 5msWrite instruction 38HDelayed 5msNote: the 38H instruction described above can be omitted. 1~2 steps are omittedWrite instruction 38HWrite instruction 08H to close the displayWrite instructions for 01H display screenWrite instruction 06H cursor movement settingsWrite instruction 0cH displays open and cursor settings3. sets the display address (where the characters are displayed).4. write data to display characters.Three, LCD1602 subroutine modules and the main program written:According to the flow of the program written above, an example of each subroutine module and the main program is given.1. header files, macro definitions, definitions, pins, etc.:#include<reg52.h>#include <string.h>#define uchar unsigned char#define uint unsigned intSbit EN=P2^2;Sbit RW=P2^1;Sbit RS=P2^0;2.LCD1602 basic initialization subroutine:Void, LCD1602 (){EN=0;RS=1;RW=1;P0=0xff; / / where P0 is connected with LCD D0~D7 I/O }3. read busy subroutine:Void, read_busy (){P0=0xff;RS=0;EN=1;While (P0&0x80); //P0 and 10000000 phases and D7 bits, if not 0, stop hereEN=0;/ / if 0 jump into the next step; this statement is the role of detection of D7If the busy wait} / / read out, not busy busy reading and writing instruction execution subroutine4. write instructions and write data subroutines:Void lcd_write (uchar, I, bit, J){Read_busy ();P0=i; / / i=0, i=1, and write data write instructions;RS=j;RW=0;EN=1;}5. time delay subroutine:Void delayms (uint C) / / other functions are to provide initialization subroutine delay in 1xc MS{Uint, a, b;For (a=0; a<c; a++)For (b=0; b<120; b++);}6.LCD1602 initialization subroutine:Void (init) / / fully in accordance with the requirements of the initialization process, omitted a step write command 38H{Delay (15);Write (0x38,0);Delay (5);Write (0x38,0);Write (0x08,0);Write (0x01,0);Write (0x06,0);Write (0x0c, 0);}7. main program:In addition to the main program in the initialization procedure is written by themselves according to the display subroutine, you need not write function can display subroutine of various types, not detail here, as the following example shows a character string display and display subroutine.Void, main (){LCD1602 ();Init ();Lcd_write (0xc1,0); / / display a characterLcd_write (0x41,1); / / display a characterWhile (1);}Task 1: the program that displays the letter "A" at the first character of the second line of the LCD module:Task 2: dynamic display of a string of characters#include "reg51.h""#include "Intrins.h""#include "string.h""#define uchar unsigned charSbit rs = P2^0; / / determine the connection of hardwareSbit RW = P2^1;Sbit e = P2^2;Void, LCD_write ();Void, busy_wait ();Void delayms (uchar MS);"Uchar str[] = {" abc//defghijklm "}; Void, main (){Uchar i=0;P0 = 0x01;LCD_write ();P0 = 0x38;LCD_write ();P0 = 0x0f;LCD_write ();P0 = 0x06;LCD_write ();Do{For (I = 0; i<strlen (STR); i++) {P0 = 0xc0+i;LCD_write ();P0 = str[i];Rs = 1;RW = 0;E = 0;Busy_wait ();E = 1;Delayms (200); / / delayP0 = 0x01; / / screenLCD_write ();}}while (1);Return;}Write control command function * / / * Void, LCD_write () {Rs = 0;RW = 0;E = 0;Busy_wait ();E = 1;Return;}To determine whether the LCD / * * / busy subroutine Void, busy_wait () {Do{P0 = 0xff;Rs = 0;RW = 1;E = 0;_nop_ ();E = 1;} while ((P0&0x80) = = 0);/ / E = 0;Return;}Void Delayms (uchar MS){Uchar i;While (ms--) for (i=0; i<120; i++);}Task 3 (omitted): display two lines of characters on the LCD, the first behavior is "", second "GO:0", and the value in the second line will be added./ * LCD1602.h*/ header file#ifndef LCD_CHAR_1602_2011_4_9#define LCD_CHAR_1602_2011_4_9#include "REG51.H""#include <intrins.h>*********************************************************//PortDefinitionsSbit LcdRs = P2^0;Sbit LcdRw = P2^1;Sbit LcdEn = P2^2;SFR DBPort = 0x80; //P0=0x80, P1=0x90, P2=0xA0, P3=0xB0. data ports*********************************************************** ****Internal / / wait functionUnsigned char LCD_Wait (void){LcdRs=0;LcdRw=1;_nop_ ();LcdEn=1;_nop_ ();而(dbport & 0x80);lcden = 0;返回dbport;}*********************************************************** */ /向液晶写入命令或数据#定义lcd_command 0 / /命令#定义lcd_data 1 / /数据#定义lcd_clear_screen 0x01 /清屏#定义lcd_homing 0x02 /光标返回原点无效lcd_write(点式、无符号字符输入){lcden = 0;lcdrs =风格;lcdrw = 0;_nop_();dbport =输入;_nop_();/ /注意顺序lcden = 1;//注意顺序_nop_();lcden = 0;_nop_();lcd_wait();}*********************************************************** */ /设置显示模式#定义lcd_show寄存器/显示开#定义lcd_hide 0x00 /显示关#定义lcd_cursor 0x02 /显示光标#定义lcd_no_cursor 0x00 /无光标#定义lcd_flash 0x01 /光标闪动#定义lcd_no_flash 0x00 /光标不闪动无效lcd_setdisplay(无符号字符显示模式){lcd_write(lcd_command,0x08 |显示模式);}*********************************************************** */ /设置输入模式#定义lcd_ac_up 0x02#定义lcd_ac_down 0x00 /默认#定义lcd_move 0x01 /画面可平移#定义lcd_no_move 0x00 /默认无效lcd_setinput(unsigned char InputMode){lcd_write(lcd_command,0x04 | InputMode);}*****************************************************/ /初始化液晶无效lcd_initial(){lcden = 0;lcd_write(lcd_command,0X38);/ / 8位数据端口,2行显示,5×7点阵lcd_write(lcd_command,0X38);lcd_setdisplay(lcd_show | lcd_no_cursor);/ /开启显示,无光标lcd_write(lcd_command,lcd_clear_screen);/ /清屏lcd_setinput(lcd_ac_up | lcd_no_move);/ /交流递增,画面不动}/ / ******************************************************无效gotoxy(unsigned char unsigned char X,Y){如果(y=0)lcd_write(lcd_command,0x80 | X);如果(y=1)lcd_write(lcd_command,0x80 |(x-0x40));}空白打印(无符号字符){当(*)!=“0”){lcd_write(lcd_data,* STR);STR;}}/ /********************************************************* # endif/ * * / C源文件LCD1602。
实验九 LCM1602液晶显示实验一、实验目的1.掌握keil C51软件与protues软件联合仿真调试的方法;2.掌握LCM1602液晶模块显示西文的原理及使用方法;3.掌握用8位数据模式驱动LCM1602液晶的C语言编程方法;二、实验内容1.用protues设计一LCM1602液晶显示接口电路。
要求利用P0接LCM1602液晶的数据端,P2.0~P2.2做LCM1602液晶的控制信号输入端。
P3.0~P3.4口扩展4个功能键K1~K4,电路如下2.编写程序,实现字符的静态和动态显示,字符为第一行“姓名全拼”第二行“专业全拼+学号”。
液晶的初始化,字符显示程序可参考官网的程序文件。
3.编写程序,利用功能键实现字符的纵向滚动和横向滚动等效果显示,主程序静态显示“My Informatiom”,显示字符如下:1.姓名全拼2.专业全拼+学号3.MCS-51 EXP84.LCD DISPLAY ”三.实验步骤1.用Protues设计1602液晶显示接口电路;2.在Keil51中编写液晶显示控制程序,编译通过后,与Protues联合调试;3.按功能键,观察字符及效果是否正确显示;四.实验电路2五.实验程序1静态#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code table[]="1.wanglin"; uchar code table1[]="2.tongxin 517"; sbit lcden=P2^2;sbit lcdrs=P2^0;uchar num;void delay(uint z){ uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(uchar com){ lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar date) { lcdrs=1;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void init(){ lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80+0x1);}void main(){ init();while(1){write_com(0x80);for(num=0;num<10;num++){write_data(table[num]);delay(300);}write_com(2);write_com(0x80+0x40);for(num=0;num<13;num++){write_data(table1[num]);delay(300);}}}1动态#include<reg51.h>#define uchar unsigned char#define uint unsigned intuchar code table[]="1.wanglin"; uchar code table1[]="2.tongxin 517"; sbit lcden=P2^2;sbit lcdrs=P2^0;uchar num;void delay(uint z){ uint x,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}void write_com(uchar com){ lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_data(uchar date){ lcdrs=1;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void init(){ lcden=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80+0x1);}void main(){ init();while(1){write_com(0x80);for(num=0;num<10;num++){write_data(table[num]);delay(300);}write_com(2);write_com(0x80+0x40);for(num=0;num<13;num++){write_data(table1[num]);delay(300);}write_com(1);}}2#include<reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit lcden=P2^2;sbit lcdrs=P2^0;sbit lcdrw=P2^1;sbit busy=P0^7;sbit K1=P3^0;sbit K2=P3^1;bit flag1,flag2,flag3,flag4;uchar num,i;uchar code tab[]="My information!"; uchar code tab1[]="1.wanglin";uchar code tab2[]="2.tongxin 517"; uchar code tab3[]="3.MCS-51 EXP8"; uchar code tab4[]="4.LCD DISPLAY";void LCD_check_busy() {while(1){lcden=0;lcdrs=0;lcdrw=1;P0=0xff;lcden=1;if(busy==0) break;}lcden=0;}void delay(uint x){while(x--);}void delay_ms(uint x){int a,b;for(a=x;a>0;a--)for(b=110;b>0;b--);}void write_com(uchar com) {LCD_check_busy();lcdrs=0;lcden=0;lcdrw=0;P0=com;lcden=1;lcden=0;}void write_dat(uchar dat) {LCD_check_busy();lcdrs=1;P0=dat;delay(5); lcdrw=0;lcden=1;lcden=0;}void lcd_init(){lcden=0;write_com(0x38);write_com(0x0f);write_com(0x06);}void write_str(uchar *str){while(*str!='\0'){while(flag3);if(flag4){ write_com(0x01); break; } write_dat(*str) ;str++;delay_ms(50);}}void main(){uchar *ptr=tab;uchar*p=tab1,*q=tab2,*m=tab3,*n=tab4;TMOD=0x00;TH0=(65536-20000)/256;TL0=(65536-20000)%256;TR0=1;ET0=1;EX0=1;EX1=1;IT0=IT1=1;EA=1;PX1=1;lcd_init();while(1){write_com(01);write_com(0x80+0x00);for(i=0;i<15;i++){if(flag1|flag2) break;write_dat(tab[i]);delay_ms(100);}while(flag1==1){write_com(0x01);write_com(0x80+0x00);write_str(p);if(flag4){ flag4=0; break;}write_com(0xc0+0x00);write_str(q);if(flag4){ flag4=0; break;}delay_ms(800);write_com(0x01);write_com(0x80+0x00);write_str(q);if(flag4){ flag4=0; break;}write_com(0xc0+0x00);write_str(m);if(flag4){ flag4=0; break;}delay_ms(800);write_com(0x01);write_com(0x80+0x00);write_str(m);if(flag4){flag4=0; break;}write_com(0xc0+0x00);write_str(n);if(flag4){flag4=0; break;}delay_ms(800);write_com(0x01);write_com(0x80+0x00);write_str(n);if(flag4){ flag4=0; break;}write_com(0xc0+0x00);write_str(p);if(flag4){ flag4=0; break;}delay_ms(800);}while(flag2==1){write_com(0x01); write_com(0x80+0x00);write_str(p);if(flag4){ flag4=0; break;} write_com(0x80+0x15);write_str(q);if(flag4){ flag4=0; break;} write_com(0xc0+0x00);write_str(m);if(flag4){ flag4=0; break;} write_com(0xc0+0x15);write_str(n);if(flag4){ flag4=0; break;}while(flag2==1){write_com(0x1c);delay_ms(300);while(flag3);}}}}void key12() interrupt 1{TH0=(65536-20000)/256;TL0=(65536-20000)%256;if(K1==0)delay_ms(5);if(K1==0&&flag2==0){TR0=0;flag1=1;}if(K2==0)delay_ms(5);if(K2==0&&flag1==0){TR0=0;flag2=1;}}void key3() interrupt 0{EX1=0; delay_ms(5); EX1=1;if(flag1|flag2==1)flag3=~flag3;}void key4() interrupt 2{EX1=0; delay_ms(5); EX1=1;flag4=1;if(flag1==1|flag2==1){flag1=flag2=flag3=0;TR0=1;}}六、实验总结1. 1602动态显示的原理即先写入要显示的字符,然后写入滚动的命令,从而实现不同的动态效果。
1602详细资料和实例1602字符液晶在实际的产品中运用的也比较多了,前几天留意了一下,发现宿舍门前的自动售水机就是采用的1602液晶进行显示的。
而且对于单片机的学习而言,掌握1602的用法是每一个学习者必然要经历的过程。
在此,我将使用1602过程中遇到的问题以及感受记录下来,希望能够给初学者带来一点指导,少走一点弯路。
所谓1602是指显示的内容为16*2,即可以显示两行,每行16个字符。
目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
1602液晶的正面(绿色背光,黑色字体)1602液晶背面(绿色背光,黑色字体)另一种1602液晶模块,显示屏是蓝色背光白色字体字符型LCD1602通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样,引脚定义如下表所示:HD44780内置了DDRAM、CGROM和CGRAM。
DDRAM就是显示数据RAM,用来寄存待显示的字符代码。
共80个字节,其地址和屏幕的对应关系如下表:也就是说想要在LCD1602屏幕的第一行第一列显示一个"A"字,就要向DDRAM的00H地址写入“A”字的代码(指A的字模代码,0x20~0x7F为标准的ASCII码,通过这个代码,在CGROM中查找到相应的字符显示)就行了。
但具体的写入是要按LCD模块的指令格式来进行的,后面我会说到的。
那么一行可有40个地址呀?是的,在1602中我们就用前16个就行了。
第二行也一样用前16个地址。
对应如下:DDRAM地址与显示位置的对应关系。
(事实上我们往DDRAM里的00H地址处送一个数据,譬如0x31(数字1的代码,见字模关系对照表)并不能显示1出来。
这是一个令初学者很容易出错的地方,原因就是如果你要想在DDRAM的00H地址处显示数据,则必须将00H加上80H,即80H,若要在DDRAM的01H处显示数据,则必须将01H加上80H即81H。
1602液晶1602液晶是一种常用的液晶显示模块,它是基于蓝色背光的字符型液晶显示器。
该显示模块由一块16列2行的液晶和一个控制芯片组成,能够显示32个字符。
它广泛应用于各种电子设备,如数字电子秤、温湿度计、计时器等。
1602液晶具有显示效果清晰、功耗低、驱动方式简单等特点。
它采用了反射式的LCD技术,配合背光源进行光学调节,能够在不同的环境光照条件下显示清晰。
同时,1602液晶还具有较低的功耗,适用于需要长时间显示文字内容的应用。
它的驱动方式也相对简单,只需通过控制芯片发送指令和数据即可实现文字的显示。
在1602液晶的控制芯片中,有一个上升沿触发的自动读写功能,可以简化控制电路,减少外接元件。
另外,该芯片还具备多种显示模式和字符设置的功能,可以满足不同需求。
1602液晶模块的引脚布局合理,使用起来比较方便。
一般来说,其中的15个数字引脚分别是:VSS、VDD、VO、RS、R/W、E、D0~D7。
通过这些引脚,可以与单片机等设备进行连接,并实现对液晶的控制。
为了方便使用,一些供应商还会在1602液晶模块中加入一个IIC 接口转换电路,使得其可以通过IIC总线与其他设备通信。
这样一来,就不需要繁琐的接线,只需通过串行通信即可实现与其他设备的数据交互。
这样的设计更加灵活,适用于一些对数据传输速度要求较高的场景。
然而,需要注意的是,1602液晶模块本身不具备自动换行和滚屏的功能,因此在使用时需要通过程序控制来实现。
另外,虽然1602液晶模块可以显示字符,但对于图形等更复杂的显示内容则无能为力。
因此,在一些需要显示更丰富信息的应用中,可能需要其他类型的显示模块来替代。
总之,1602液晶是一种常见的液晶显示模块,具备显示效果清晰、功耗低、驱动方式简单等优点。
它能够满足一些基本的显示需求,适用于各种电子设备。
但需要注意的是,它在一些功能方面还存在一定的限制。
随着技术的不断发展,未来可能会出现更先进、功能更完善的显示模块。
LCD1602液晶显示完全资料0x18 光标和显示一起向左移动4.显示地址:LCD1602内部RAM显示缓冲区地址的映射图,00~0F、40~4F分别对应LCD1602的上下两行的每一个字符,只要往对应的RAM地址写入要显示字符的ASCII代码,就可以显示出来。
5.读写时序:时序图1602手册中有,这里不引用了。
时序图很重要,编程就是根据时序图设置寄存器,让LCD工作。
二、LCD1602程序编写流程:LCD1602在了解完以上信息后便可以编写,这里我们把程序分为以下几步:1.定义LCD1602管脚,包括RS,R/W,E。
这里定义是指这些管脚分别接在单片机哪些I/O口上。
现举例如下:sbit EN=P3^4;sbit RS=P3^5;sbit RW=P3^6;2.显示初始化,在这一步进行初始化及设置显示模式等操作,包括以下步骤:设置显示方式延时清理显示缓存设置显示模式通常推荐的初始化过程如下:延时15ms写指令38H延时5ms写指令38H延时5ms写指令38H延时5ms注:以上写38H指令可以看情况省略1~2步(以上都不检测忙信号)(以下都要检测忙信号)写指令38H写指令08H 关闭显示写指令01H 显示清屏写指令06H 光标移动设置写指令0cH 显示开及光标设置3.设置显示地址(写显示字符的位置)。
4.写显示字符的数据。
三、LCD1602各子程序模块及主程序编写:现在按照上面编写程序的流程,给出各子程序模块及主程序的例子。
1.头文件,宏定义,定义管脚等:#include<reg52.h>#include <string.h>#define uchar unsigned char#define uint unsigned intsbit EN=P3^4;sbit RS=P3^5;sbit RW=P3^6;uchar code table0[]={"QQ:545699636"}; //此条语句为显示字符串时定义的字符串数组2.LCD1602基本初始化子程序:void LCD1602(){EN=0;RS=1;RW=1;P0=0xff; //这里P0为与LCD D0~D7相连的I/O口}3.读忙子程序:void read_busy(){P0=0xff;RS=0;RW=1;EN=1;while(P0&0x80); //P0和10000000相与,D7位若不为0,停在此处EN=0; //若为0跳出进入下一步;这条语句的作用就是检测D7位} //若忙在此等待,不忙跳出读忙子程序执行读写指令4.写指令写数据子程序:void write(uchar i,bit j){read_busy();P0=i; //其中i=0,写指令;i=1,写数据;RS=j;RW=0;EN=1;EN=0;}5.延时子程序:void delay(uint c) //功能为提供初始化等其他子程序中的延时1xc MS{uint a,b;for(a=0;a<c;a++)for(b=0;b<120;b++);}6.LCD1602初始化子程序:void init() //完全按照要求初始化流程来,中间省略了一步写指令38H{delay(15);write(0x38,0);delay(5);write(0x38,0);write(0x08,0);write(0x01,0);write(0x06,0);write(0x0c,0);}7.显示单个字符子程序:void display_lcd_byte(uchar y,uchar x,uchar z) //Y=0,1(起始行)X=0~15(起始列)Z=想写字符的ASCII码{if(y) //是否显示在第二行(若在第一行Y=0,不进入IF语句,若在第二行,进入IF语句{x+=0x40; //第二行起始地址加上列数为字符显示地址}x+=0x80; //设置数据指针位置write(x,0);write(z,1); //写入数据}8.显示字符串子程序:void display_lcd_text(uchar y,uchar x,uchartable[]) //Y,X同上字符显示,table[]字符串数组{uchar z=0;uchar t;t=strlen(table)+x; // 求得字符串长度加上起始列位置 while(x<t) //功能为LCD显示到字符串最后一个字符,防止字符串{ //没有16个字符,从而不够位产生乱码; display_lcd_byte(y,x,table[z]); //逐位显示数组内字符x++;z++;}}9.主程序:主程序里除了放入初始化程序外就是加入自己编写的显示子程序,根据你所要的不用功能可以编写各种类型的显示子程序,这里不做详细介绍,以下举例为显示一个字符和显示字符串的显示子程序。
一、关于LCD1602:在编写LCD1602程序前,我们必须了解其手册上一些非常重要的信息,如果这些信息不能理解透彻,编程可能会遇到或多或少的问题,在此先大致归纳几点。
1.管脚:1602共16个管脚,但是编程用到的主要管脚不过三个,分别为:RS(数据命令选择端),R/W(读写选择端),E(使能信号);以后编程便主要围绕这三个管脚展开进行初始化,写命令,写数据。
以下具体阐述这三个管脚:RS为寄存器选择,高电平选择数据寄存器,低电平选择指令寄存器。
R/W为读写选择,高电平进行读操作,低电平进行写操作。
E端为使能端,后面和时序联系在一起。
除此外,D0~D7分别为8位双向数据线。
2.操作时序:信号真值表RS R/W EN 操作说明0 0 1→0 写入指令D0~D70 1 1 读出的D0~D7状态字1 0 1→0 写入D0~D7数据1 1 1 读出D0~D7数据注:关于E=H脉冲——开始时初始化E为0,然后置E为1,再清0.读取状态字时,注意D7位,D7=1,禁止读写操作;D7=0,允许读写操作;所以对控制器每次进行读写操作前,必须进行读写检测。
(即后面的读忙子程序)3.指令集:LCD_1602 初始化指令小结:0x38 设置16*2显示,5*7点阵,8位数据接口0x01 清屏0x0f 开显示,显示光标,光标闪烁0x08 关闭显示0x0e 开显示,显示光标,光标不闪烁0x0c 开显示,不显示光标0x06 地址加1,当写入数据的时候光标右移0x02 地址计数器AC=0;(此时地址为0x80)光标归原点,但是DDRAM中断内容不变0x18 光标和显示一起向左移动4.显示地址:LCD1602内部RAM显示缓冲区地址的映射图,00~0F、40~4F分别对应LCD1602的上下两行的每一个字符,只要往对应的RAM地址写入要显示字符的ASCII代码,就可以显示出来。
5.读写时序:时序图1602手册中有,这里不引用了。
液晶字符显示————————————————————————————————作者:————————————————————————————————日期:1.基本简介LCD1602工业字符型液晶,能够同时显示16x02即32个字符。
(16列2行)1602液晶也叫1602字符型液晶,它是一种专门用来显示字母、数字、符号等的点阵型液晶模块。
它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM,显示效果也不好)。
1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。
目前市面上字符液晶绝大多数是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。
2.管脚功能1602采用标准的16脚接口,其中:第1脚:VSS为电源地第2脚:VCC接5V电源正极第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。
第4脚:RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
第5脚:RW为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作。
第6脚:E(或EN)端为使能(enable)端,高电平(1)时读取信息,负跳变时执行指令。
第7~14脚:D0~D7为8位双向数据端。
第15~16脚:空脚或背灯电源。
15脚背光正极,16脚背光负极。
⑶特性3.3V或5V工作电压,对比度可调内含复位电路提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能有80字节显示数据存储器DDRAM内建有192个5X7点阵的字型的字符发生器CGROM 8个可由用户自定义的5X7的字符发生器CGRAM3特性应用+3.3V电压,对比度可调内含复位电路提供各种控制命令,如:清屏、字符闪烁、光标闪烁、显示移位等多种功能有80字节显示数据存储器DDRAM内建有192个5X7点阵的字型的字符发生器CGROM8个可由用户自定义的5X7的字符发生器CGRA。
一、引言随着电子技术的不断发展,单片机在各个领域得到了广泛的应用。
电子钟作为单片机应用的一个重要实例,具有很高的实用价值。
本实训报告主要介绍了单片机电子钟的设计与实现过程,包括硬件电路设计、软件编程以及调试过程。
二、硬件电路设计1. 单片机选择本实训选用AT89C51单片机作为核心控制器,该单片机具有丰富的I/O端口、较强的计算能力和较大的存储空间,能够满足电子钟的设计需求。
2. 时钟芯片本实训采用DS1302时钟芯片作为时间源,该芯片具有年、月、日、周、时、分、秒的精确计时功能,并具备闰年补偿等功能。
3. 液晶显示屏本实训选用1602液晶显示屏用于显示时间、日期等信息。
1602液晶显示屏具有清晰显示多个字符和符号的特点,方便用户查看时间和其他信息。
4. 按键模块本实训设计按键模块用于用户输入和设置。
按键包括时间设置键、日期设置键、闹钟设置键等,方便用户进行各项操作。
5. 电源模块本实训采用DC5V电源模块,为整个电子钟提供稳定的电源供应。
三、软件编程1. 主程序主程序负责初始化单片机、时钟芯片、液晶显示屏等硬件设备,并进入主循环。
主循环中,程序会不断检测按键状态,根据按键输入调整时间、日期和闹钟设置。
2. 时钟控制程序时钟控制程序负责实现时钟的基本功能,包括计时、闰年补偿等。
程序通过定时器中断,每秒更新一次时间。
3. 显示程序显示程序负责将时间、日期等信息显示在液晶显示屏上。
程序使用1602液晶显示屏的指令集,动态显示时、分、秒和日期。
4. 按键扫描程序按键扫描程序负责检测按键状态,并根据按键输入调整时间、日期和闹钟设置。
程序采用轮询方式检测按键状态,以提高按键响应速度。
5. 闹钟程序闹钟程序负责实现闹钟功能,当时间达到设定的闹钟时间时,电子钟会发出蜂鸣声提示用户。
四、调试过程1. 硬件调试首先,对硬件电路进行调试,检查各元器件是否安装正确,连接是否牢固。
然后,使用万用表检测电源电压、单片机各引脚电压是否正常。
/*1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK*/
/*-----------------------------------------------
名称:LCD1602
公司:上海浩豚电子科技有限公司
编写:师访
日期:2009.5
修改:无
内容:通过标准程序动态显示字符
------------------------------------------------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
sbit RS = P2^4; //定义端口
sbit RW = P2^5;
sbit EN = P2^6;
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
/******************************************************************/
/* 微秒延时函数*/
/******************************************************************/
void delay_us(unsigned int n) //延时如果需要高精度延时请嵌入汇编
{
if (n == 0)
{
return ;
}
while (--n);
}
/******************************************************************/
/* 毫秒函数声明*/
/******************************************************************/
void delay_ms(unsigned char i)
{
unsigned char a, b;
for (a = 1; a < i; a++)
{
for (b = 1; b; b++)
{ ; }
}
}
/******************************************************************/ /* 写入命令函数*/ /******************************************************************/ void LCD_write_com(unsigned char com)
{
RS_CLR;
RW_CLR;
EN_SET;
P0 = com;
delay_us(5);
EN_CLR;
}
/******************************************************************/ /* 写入数据函数*/ /******************************************************************/ void LCD_write_Data(unsigned char Data)
{
RS_SET;
RW_CLR;
EN_SET;
P0 = Data;
delay_us(5);
EN_CLR;
}
/******************************************************************/ /* 清屏函数*/ /******************************************************************/ void LCD_clear(void)
{
LCD_write_com(0x01);
delay_ms(5);}
/******************************************************************/ /* 写入字符串函数*/ /******************************************************************/ void LCD_write_str(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
LCD_write_com(0x80 + x);
}
else
{
LCD_write_com(0xC0 + x);
}
while (*s)
{
LCD_write_Data( *s);
s ++;
}
}
/******************************************************************/ /* 写入字节函数*/ /******************************************************************/ void LCD_write_char(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
LCD_write_com(0x80 + x);
}
else
{
LCD_write_com(0xC0 + x);
}
LCD_write_Data( Data);
}
/******************************************************************/ /* 初始化函数*/ /******************************************************************/ void LCD_init(void)
{
LCD_write_com(0x38); /*显示模式设置*/
delay_ms(5);
LCD_write_com(0x38);
delay_ms(5);
LCD_write_com(0x38);
delay_ms(5);
LCD_write_com(0x38);
LCD_write_com(0x08); /*显示关闭*/
LCD_write_com(0x01); /*显示清屏*/
LCD_write_com(0x06); /*显示光标移动设置*/
delay_ms(5);
LCD_write_com(0x0C); /*显示开及光标设置*/
}
/******************************************************************/ /* 主函数*/
/******************************************************************/ void main(void)
{
unsigned char i;
unsigned char *p;
delay_ms(100);
LCD_init();
while (1)
{
i = 1;
p = "";
LCD_clear();
LCD_write_str(2,0,"Welcome to");
delay_ms(250);
while (*p)
{
LCD_write_char(i,1,*p);
i ++;
p ++;
delay_ms(250);
}
delay_ms(250);
}
}。