右边那个用于插入1602,左边那个电位器(滑动变阻器)用于调节液晶的对比度,转动后,字符的颜色会发生深浅变化。
这样插上去,插反了容易把液晶烧坏。
1602:1行可以显示16个字符,一共两行。
还有1601,0801,0802,12864,12232、320240、320640。
12864:图形液晶,横着有128个点,竖着有64个点。要让显示东西,控制矩阵内这些任何的点就会显示图形或汉字。如果是带字库的液晶,写字的时候,直接把汉字赋给液晶的数据口,这些字体就能出来。
1602只能显示数字和字符,即数字、英文字母、符号,所有的asc码,不能显示汉字。
这种液晶就是两色,还有带有灰度值得,可以显示出动画,还有wei 彩的、真彩的就是彩色液晶,也可以由单片机驱动。
液晶比数码管有意思多了,而且比数码管简单。
1602有好几种接口,这里是并行接口。
3VL就是液晶对比度调节。
4RS液晶写数据之前要先接收命令,表示他要干什么,命令是要让液晶内部进行一些设置,数据就是直接要显示的数据。首先命令在什么位置显示什么东西,就像光标闪烁就是命令。H电平接收数据,L电平接收命令。
5RW读写数据,液晶可以写数据,也可以从里面读数据。今天简化一下,就不读数据了。
D0~D7,8位数据口。
15~16不接背光就不亮了。
设计电路板才需要考虑尺寸,所以不看了。
控制器接口这是液晶内部。
要读当前状态是否允许写,比如上一个状态还没有显示出来又写了一个,这就不行,数据会丢失。这是高速操作用的。
我们只看写,1.2:RS=L(选中了命令,命令就是指令),RW=L(写),D0~D7指令码(后面讲,D0~D7可以送指令也可以送数据,由RS决定),E=高脉冲前者为高脉冲,后者为低脉冲。输出就不管了。
1.3也是读,就不看了。
1.4:RS=H(选中数据),RW=L(写),D0~D7(数据),E=高脉冲。
数字芯片要读懂时序图。
读的就不看了,看写的。
能看到许多都是两条线,那是因为一个是写,一个是读。
我们只看写的,首先RS,RW变低,过一段时间,再给E一个高脉冲,持续一段时间,再拉为低电平,持续一段时间,再将RS、RW变回高。具体写程序再看。
延时多少时间,要看时序参数:
不同厂家操作时序不一样,这里郭天祥说按照长沙太阳人公司(就是上面这些内容的出处)的不能正常工作.....然后看了英文原版的。
我们可以不检测,我们做个延时,等他忙完,在进行第二个操作,可以省不少事情,不至于程序写的麻烦。
看到省略号后面还有,视频中字符是从右侧慢慢移到左边的,实际上就是写到了后面,先全部写完,有一个整屏移动指令,就全都移动出来了。还有别的方向的。但是省略号后面那些不在显示范围内。
5*7点阵:其实每个字符是由5行7列的点阵组成的
要显示东西,肯定要让D=1,光标显示关闭等会我们分别试试看看效果。
N=1,每写一个字节,地址指针自动加1,下一次直接写数据就可以了,N=0,就是倒着往前写。
80字节RAM:00~67。
数据指针,也是指令,要先设置数据指到什么位置,然后再写数据,不能直接写0-27,前面要有个80H+,80H+1地址就是01,80H就是00。
我们写的时候不按照这个,按照自己的方法。
1602和51单片机的接口
这里中间74LS00那里不看,可能是自动写入方法。RD和WR第二功能还没讲,用的时候自己看。
15、16背光,加了一个10Ω电阻,怕直接加5V电压后电流过大把芯片烧坏,用它限流。
D0~D7数据口接了P0口,6接口是使能端,接了P3.4。然后5这个IO口和我们的不一样,因为这里只写,所以视频中直接接了低电平,4是数据命令选择端,接了P3.5,3是偏压信号,接地,液晶显示需要负电压,并用滑动变阻器调节,电压就会变化,内部对比度就会变化。
接下来程序,我们先把光标写出来
注意D0~D7连接着数码管的,写数据时,数码管也会变,实验板是usb供电,同时把数码管和液晶打开,功耗会过大,usb供电电流比较小,功耗不够,液晶就会不亮,所以我们把数码管全部关端,把锁存端关闭就可以。
然后就照着下面的图写就可以了
这里我先尝试按照视频中的电路接法,用的仿真,把RW接地。由于RW一直为低,所以就不需要tSP1的等待时间了
1 #include<reg51.h> 2 3 #define uchar unsigned char 4 #define uint unsigned int 5 6 sbit DUAN=P2^6; 7 sbit WEI=P2^7; 8 sbit lcden=P3^4; 9 sbit lcdrs=P3^5; 10 //sbit lcdrw=P3^6; 11 12 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; 13 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 无显示 14 15 void Delay1ms(); 16 void delay(int n); 17 void write_com(uchar com); 18 void write_data(uchar date); 19 void init(); 20 21 void main() 22 { 23 init(); 24 while(1); 25 } 26 void write_com(uchar com) 27 { 28 //写命令 29 lcdrs=0;//数据命令选择端,选择命令 30 P0=com;//送指令 31 delay(5); 32 lcden=1; 33 delay(5); 34 lcden=0; 35 } 36 void write_data(uchar date) 37 { 38 //写数据 39 lcdrs=1;//数据命令选择端,选择数据 40 P0=date;//送数据 41 delay(5); 42 lcden=1; 43 delay(5); 44 lcden=0; 45 } 46 void init() 47 { 48 //第一步关闭数码管两个锁存器 49 DUAN=0; 50 WEI=0; 51 //第二步初始化液晶 52 lcden=0;//使能 53 write_com(0x38);//模式初始化 54 write_com(0x0f);//开显示,显示光标,光标闪烁 55 write_com(0x06);//光标+1,不整屏移动了 56 57 } 58 void delay(int n) 59 { 60 while(n--) 61 { 62 Delay1ms(); 63 } 64 } 65 void Delay1ms() //@12.000MHz 66 { 67 unsigned char i, j; 68 69 i = 2; 70 j = 239; 71 do 72 { 73 while (--j); 74 } while (--i); 75 }
代码是成功的,我们也可以让光标不闪烁,即将0x0f改为0x0e;
但是会发现,前面有一个黑块,这这么回事?
本以为没有初始化光标,所以在init中write_com(0x06)后面加了一个write_com(0x80);结果不行,光标没了...
可能是一开始有数据,我们先清屏一下,加上write_com(0x01)
1 #include<reg51.h> 2 3 #define uchar unsigned char 4 #define uint unsigned int 5 6 sbit DUAN=P2^6; 7 sbit WEI=P2^7; 8 sbit lcden=P3^4; 9 sbit lcdrs=P3^5; 10 //sbit lcdrw=P3^6; 11 12 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; 13 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 无显示 14 15 void Delay1ms(); 16 void delay(int n); 17 void write_com(uchar com); 18 void write_data(uchar date); 19 void init(); 20 21 void main() 22 { 23 init(); 24 while(1); 25 } 26 void write_com(uchar com) 27 { 28 //写命令 29 lcdrs=0;//数据命令选择端,选择命令 30 P0=com;//送指令 31 delay(5); 32 lcden=1; 33 delay(5); 34 lcden=0; 35 } 36 void write_data(uchar date) 37 { 38 //写数据 39 lcdrs=1;//数据命令选择端,选择数据 40 P0=date;//送数据 41 delay(5); 42 lcden=1; 43 delay(5); 44 lcden=0; 45 } 46 void init() 47 { 48 //第一步关闭数码管两个锁存器 49 DUAN=0; 50 WEI=0; 51 //第二步初始化液晶 52 lcden=0;//使能 53 write_com(0x38);//模式初始化 54 write_com(0x0f);//开显示,显示光标,光标闪烁 55 write_com(0x06);//光标+1,不整屏移动了 56 write_com(0x01);//显示清零,数据指针清零 57 write_com(0x80);//数据地址指针初始化00 58 59 } 60 void delay(int n) 61 { 62 while(n--) 63 { 64 Delay1ms(); 65 } 66 } 67 void Delay1ms() //@12.000MHz 68 { 69 unsigned char i, j; 70 71 i = 2; 72 j = 239; 73 do 74 { 75 while (--j); 76 } while (--i); 77 }
光标有了,接下来可以写数据了,我们先写一个1
1 #include<reg51.h> 2 3 #define uchar unsigned char 4 #define uint unsigned int 5 6 sbit DUAN=P2^6; 7 sbit WEI=P2^7; 8 sbit lcden=P3^4; 9 sbit lcdrs=P3^5; 10 //sbit lcdrw=P3^6; 11 12 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; 13 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 无显示 14 15 void Delay1ms(); 16 void delay(int n); 17 void write_com(uchar com); 18 void write_data(uchar date); 19 void init(); 20 21 void main() 22 { 23 init(); 24 write_data('1'); 25 while(1); 26 } 27 void write_com(uchar com) 28 { 29 //写命令 30 lcdrs=0;//数据命令选择端,选择命令 31 P0=com;//送指令 32 delay(5); 33 lcden=1; 34 delay(5); 35 lcden=0; 36 } 37 void write_data(uchar date) 38 { 39 //写数据 40 lcdrs=1;//数据命令选择端,选择数据 41 P0=date;//送数据 42 delay(5); 43 lcden=1; 44 delay(5); 45 lcden=0; 46 } 47 void init() 48 { 49 //第一步关闭数码管两个锁存器 50 DUAN=0; 51 WEI=0; 52 //第二步初始化液晶 53 lcden=0;//使能 54 write_com(0x38);//模式初始化 55 write_com(0x0e);//开显示,显示光标,光标闪烁 56 write_com(0x06);//光标+1,不整屏移动了 57 write_com(0x01);//显示清零,数据指针清零 58 write_com(0x80);//数据地址指针初始化00 59 60 } 61 void delay(int n) 62 { 63 while(n--) 64 { 65 Delay1ms(); 66 } 67 } 68 void Delay1ms() //@12.000MHz 69 { 70 unsigned char i, j; 71 72 i = 2; 73 j = 239; 74 do 75 { 76 while (--j); 77 } while (--i); 78 }
成功并且光标后移1位
如果我们直接写write_com(1)
那么显示就不对。
这里可以看一个手册
这里给出了每个字符对应的16进制数,即asc值。
这就是各个字符的16进制编码,从图中可以看到1的是31,a是41,之前串口通信的时候我们也看到过。
我们写'1'就是给了1的asc
如果我们直接给了0x31,那么也是输出1
如果我们想多输入几个,那么主函数如下
1 void main() 2 { 3 init(); 4 write_data('1'); 5 delay(20); 6 write_data('b'); 7 while(1); 8 }
接下来我们写两行,第一行:I LIKE MCU! 第二行:123456789,那么为了简便,我们要用到循环,不过有的人可能会这么写:
1 #include<reg51.h> 2 3 #define uchar unsigned char 4 #define uint unsigned int 5 6 sbit DUAN=P2^6; 7 sbit WEI=P2^7; 8 sbit lcden=P3^4; 9 sbit lcdrs=P3^5; 10 //sbit lcdrw=P3^6; 11 12 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; 13 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 无显示 14 uchar code Table[]="I LIKE MCU!"; 15 uchar code Table1[]="123456789"; 16 void Delay1ms(); 17 void delay(int n); 18 void write_com(uchar com); 19 void write_data(uchar date); 20 uchar num=0; 21 void init(); 22 23 void main() 24 { 25 init(); 26 for(num=0;num<11;num++) 27 { 28 write_data(Table[num]); 29 delay(5); 30 } 31 for(num=0;num<9;num++) 32 { 33 write_data(Table1[num]); 34 delay(5); 35 } 36 while(1); 37 } 38 void write_com(uchar com) 39 { 40 //写命令 41 lcdrs=0;//数据命令选择端,选择命令 42 P0=com;//送指令 43 delay(5); 44 lcden=1; 45 delay(5); 46 lcden=0; 47 } 48 void write_data(uchar date) 49 { 50 //写数据 51 lcdrs=1;//数据命令选择端,选择数据 52 P0=date;//送数据 53 delay(5); 54 lcden=1; 55 delay(5); 56 lcden=0; 57 } 58 void init() 59 { 60 //第一步关闭数码管两个锁存器 61 DUAN=0; 62 WEI=0; 63 //第二步初始化液晶 64 lcden=0;//使能 65 write_com(0x38);//模式初始化 66 write_com(0x0e);//开显示,显示光标,光标闪烁 67 write_com(0x06);//光标+1,不整屏移动了 68 write_com(0x01);//显示清零,数据指针清零 69 write_com(0x80);//数据地址指针初始化00 70 71 } 72 void delay(int n) 73 { 74 while(n--) 75 { 76 Delay1ms(); 77 } 78 } 79 void Delay1ms() //@12.000MHz 80 { 81 unsigned char i, j; 82 83 i = 2; 84 j = 239; 85 do 86 { 87 while (--j); 88 } while (--i); 89 }
一行哪有那么多字符额...
所以我们要换行
1 #include<reg51.h> 2 3 #define uchar unsigned char 4 #define uint unsigned int 5 6 sbit DUAN=P2^6; 7 sbit WEI=P2^7; 8 sbit lcden=P3^4; 9 sbit lcdrs=P3^5; 10 //sbit lcdrw=P3^6; 11 12 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; 13 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 无显示 14 uchar code Table[]="I LIKE MCU!"; 15 uchar code Table1[]="123456789"; 16 void Delay1ms(); 17 void delay(int n); 18 void write_com(uchar com); 19 void write_data(uchar date); 20 uchar num=0; 21 void init(); 22 23 void main() 24 { 25 init(); 26 for(num=0;num<11;num++) 27 { 28 write_data(Table[num]); 29 delay(5); 30 } 31 write_com(0x80+0x40);//换行,第一行0-27H,第二行40H-60H 32 for(num=0;num<9;num++) 33 { 34 write_data(Table1[num]); 35 delay(5); 36 } 37 while(1); 38 } 39 void write_com(uchar com) 40 { 41 //写命令 42 lcdrs=0;//数据命令选择端,选择命令 43 P0=com;//送指令 44 delay(5); 45 lcden=1; 46 delay(5); 47 lcden=0; 48 } 49 void write_data(uchar date) 50 { 51 //写数据 52 lcdrs=1;//数据命令选择端,选择数据 53 P0=date;//送数据 54 delay(5); 55 lcden=1; 56 delay(5); 57 lcden=0; 58 } 59 void init() 60 { 61 //第一步关闭数码管两个锁存器 62 DUAN=0; 63 WEI=0; 64 //第二步初始化液晶 65 lcden=0;//使能 66 write_com(0x38);//模式初始化 67 write_com(0x0e);//开显示,显示光标,光标闪烁 68 write_com(0x06);//光标+1,不整屏移动了 69 write_com(0x01);//显示清零,数据指针清零 70 write_com(0x80);//数据地址指针初始化00 71 72 } 73 void delay(int n) 74 { 75 while(n--) 76 { 77 Delay1ms(); 78 } 79 } 80 void Delay1ms() //@12.000MHz 81 { 82 unsigned char i, j; 83 84 i = 2; 85 j = 239; 86 do 87 { 88 while (--j); 89 } while (--i); 90 }
如果想让每一个字符出现的慢一点,就把delay加长。
接下来我们让所有字符从右往左移动出来。
之前的不全,少了这个指令
cursor光标,display shift显示移动
在不改变DD RAM的情况下,他会移动光标或显示
00:光标左移
01:光标右移
10:显示左移,光标跟随显示移动
11:显示右移
写一条指令移动一下
首先我们就不能写在00了,就要从10开始
1 #include<reg51.h> 2 3 #define uchar unsigned char 4 #define uint unsigned int 5 6 sbit DUAN=P2^6; 7 sbit WEI=P2^7; 8 sbit lcden=P3^4; 9 sbit lcdrs=P3^5; 10 //sbit lcdrw=P3^6; 11 12 //uchar code Table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; 13 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 无显示 14 uchar code Table[]="I LIKE MCU!"; 15 uchar code Table1[]="123456789"; 16 void Delay1ms(); 17 void delay(int n); 18 void write_com(uchar com); 19 void write_data(uchar date); 20 uchar num=0; 21 void init(); 22 23 void main() 24 { 25 init(); 26 for(num=0;num<11;num++) 27 { 28 write_data(Table[num]); 29 delay(5); 30 } 31 write_com(0x80+0x53);//换行,第一行0-27H,第二行40H-60H 32 for(num=0;num<9;num++) 33 { 34 write_data(Table1[num]); 35 delay(5); 36 } 37 for(num=0;num<16;num++) 38 { 39 write_com(0x1c);//显示左移1次 40 delay(100); 41 } 42 while(1); 43 } 44 void write_com(uchar com) 45 { 46 //写命令 47 lcdrs=0;//数据命令选择端,选择命令 48 P0=com;//送指令 49 delay(5); 50 lcden=1; 51 delay(5); 52 lcden=0; 53 } 54 void write_data(uchar date) 55 { 56 //写数据 57 lcdrs=1;//数据命令选择端,选择数据 58 P0=date;//送数据 59 delay(5); 60 lcden=1; 61 delay(5); 62 lcden=0; 63 } 64 void init() 65 { 66 //第一步关闭数码管两个锁存器 67 DUAN=0; 68 WEI=0; 69 //第二步初始化液晶 70 lcden=0;//使能 71 write_com(0x38);//模式初始化 72 write_com(0x0e);//开显示,显示光标,光标闪烁 73 write_com(0x06);//光标+1,不整屏移动了 74 write_com(0x01);//显示清零,数据指针清零 75 write_com(0x80+0x10);//数据地址指针初始化10 76 77 } 78 void delay(int n) 79 { 80 while(n--) 81 { 82 Delay1ms(); 83 } 84 } 85 void Delay1ms() //@12.000MHz 86 { 87 unsigned char i, j; 88 89 i = 2; 90 j = 239; 91 do 92 { 93 while (--j); 94 } while (--i); 95 }
怪异,视频中是0x10,我的必须是0x1c,方向和上面的数据手册相反,下次实验板试试好了
仿真用0x1c,单片机用0x18