1:LCD1602显示介绍
只能显示字符,可显示上下两行,每行16位。
每个字符是由点阵构成。每个点阵是5*7或5*10.通常用5*10.
各个字符之间有间隙,无法完美的显示图片。只能显示字符。
VSS即GND
VDD连接电源,5V。
VL,3 脚叫做液晶显示偏压信号,大家注意到小黑块没有,当我们要显示一个字符的时候,有的黑点显示,有的黑点就不能显示,这样就可以实现我们想要的字符了。我们这个 3 脚就是用来调整显示的黑点和不显示的之间的对比度,调整好了对比度,就可以让我们的显示更加清晰一些。在进行电路设计实验的时候,通常的办法是在这个引脚上接个电位器,也就是我们初中学过的滑动变阻器。通过调整电位器的分压值,来调整 3 脚的电压。而当产品批量生产的时候,我们可以把我们调整好的这个值直接用简单电路来实现,就如同在我们板子上,我们直接使用的是一个 18 欧的下拉电阻,市面上有的 1602 的下拉电阻大概 1 到 1.5K 也是比较合适的值
RS,4 脚是数据命令选择端。对于液晶,有时候我们要发送一些命令,让它实现我们想要的一些状态,有时候我们要发给它一些数据,让它显示出来,液晶就通过这个引脚来判断接收到的是命令还是数据,这个引脚我们接到了 ADDR0 上,通过跳线帽和 P1.0 连接在一起。大家注意学会读手册,看到这个引脚描述里:数据/命令选择端,而后跟了括号(H/L),他的意思就是当这个引脚是 H(High)高电平的时候,是数据,当这个引脚是 L(Low)低电平的时候,是命令。
R/W,5 脚和 4 脚用法类似,功能是读写选择端。我们既可以写给液晶数据或者命令,也可以读取液晶内部的数据或状态,就是控制这个引脚。R是读,W是写.这个引脚我们接到了 ADDR1 上,通过跳线帽和 P1.1 连接在一起。
E,6 脚是使能信号,很关键,液晶的读写命令和数据,都要靠它才能正常读写.
正好是8个端口,单片机的任一一组端口均可实现(如P0.0-P0.7)
D0,D1分别控制背光源正极和负极,目的是操纵1602显示器发光,在黑暗条件下也能看见。
注:存储时,每行可存储00H~27H的40个字符,但是显示时,只能显示00~10H的16个字符。
注:若想存储在02部分数据,并不是存储0x02,而是存储0x82(因为DB7固定为1,1的16进制为1000000,为0x80+0x02为0x82).
注:若想存储内容为1,则需要将"1"变更为ASCII值,即0x01+0x30,即为0x31
清屏指令,输入0x01,即可清屏
模式设置指令,RS~DB2是固定的,只有DB1选择I/D,(I,设置为1时,是光标右移,字符从左向右显示。。D,设置成0时,是光标左移,字符从右向左显示)。或者S可选择1或0(1是显示屏整个移动,0是显示屏整个不移动)。一般默认为0000 0110(即0x06,十六进制转换为10进制时,不计算前两位)
显示开关控制指令:前几位默认为0,不变。只有在DB2时改变0(关闭)或1(开启),通常是1,开启状态。。DB1的C可以设置为0(不显示光标)和1(显示光标).一般为不使用光标,为0。。DB0为设置光标是否闪烁。(0为不闪烁,1为闪烁)没使用光标,默认为0。。
即为0000 1100,即为0x0c
功能设定指令:DB1,DB0设置为X,X(任意值均可,一般设置为00)。。DB4设置为1时,是IO口控制为8口,DB4为0时,IO口控制为4口,一般默认为8口,即默认为1。。DB3设置为1时,显示为2行,设置为0时,显示为1行,一般默认为2行,即默认为1。。DB2设置为0时,即点阵为5*7显示,设置为1,即为5*10,一般默认为5*7,即设置为0。。即十六进制为0011 1000,即为0x38
初始化,有固定的代码。
RS的H高电平,1,是数据。L低电平,0,是命令。
RW一般都是0,写操作
E为使能管脚,需要刚开始有0-->1,有一个上升沿的过程。之后有1--->0的过程,有一个下降沿的过程。
DB0-DB7是写入的有效数据。
以上的时间参数可参考下图。最大是100纳秒,单片机最小为1微秒,可完全忽略上述的延时时间。也可以加入延时函数,如1毫秒,1微秒
2:硬件设计
对应实物图中1602开发板的各个引脚。
注:若屏幕上亮度不够,导致看不清时,需要调节3管脚的VO,从而调节滑动变阻器。
注:如4号管脚RS,可根据右图的电气连接知道,连接P2.6
3:软件设计
4:原始代码如下
main部分代码:
#include "public.h" #include "lcd1602.h" void main() { lcd1602_init();//LCD1602初始化 lcd1602_show_string(0,0,"Hello World!");//第一行显示 lcd1602_show_string(0,1,"0123456789");//第二行显示 while(1) { } }
lcd1602.c部分代码:
#include "lcd1602.h" // LCD1602写命令 #if (LCD1602_4OR8_DATA_INTERFACE==0)//8位LCD void lcd1602_write_cmd(u8 cmd) { LCD1602_RS=0;//选择命令 LCD1602_RW=0;//选择写 LCD1602_E=0; LCD1602_DATAPORT=cmd;//准备命令 delay_ms(1); LCD1602_E=1;//使能脚E先上升沿写入 delay_ms(1); LCD1602_E=0;//使能脚E后负跳变完成写入 } #else //4位LCD void lcd1602_write_cmd(u8 cmd) { LCD1602_RS=0;//选择命令 LCD1602_RW=0;//选择写 LCD1602_E=0; LCD1602_DATAPORT=cmd;//准备命令 delay_ms(1); LCD1602_E=1;//使能脚E先上升沿写入 delay_ms(1); LCD1602_E=0;//使能脚E后负跳变完成写入 LCD1602_DATAPORT=cmd<<4;//准备命令 delay_ms(1); LCD1602_E=1;//使能脚E先上升沿写入 delay_ms(1); LCD1602_E=0;//使能脚E后负跳变完成写入 } #endif //LCD1602写数据 #if (LCD1602_4OR8_DATA_INTERFACE==0)//8位LCD void lcd1602_write_data(u8 dat) { LCD1602_RS=1;//选择数据 LCD1602_RW=0;//选择写 LCD1602_E=0; LCD1602_DATAPORT=dat;//准备数据 delay_ms(1); LCD1602_E=1;//使能脚E先上升沿写入 delay_ms(1); LCD1602_E=0;//使能脚E后负跳变完成写入 } #else void lcd1602_write_data(u8 dat) { LCD1602_RS=1;//选择数据 LCD1602_RW=0;//选择写 LCD1602_E=0; LCD1602_DATAPORT=dat;//准备数据 delay_ms(1); LCD1602_E=1;//使能脚E先上升沿写入 delay_ms(1); LCD1602_E=0;//使能脚E后负跳变完成写入 LCD1602_DATAPORT=dat<<4;//准备数据 delay_ms(1); LCD1602_E=1;//使能脚E先上升沿写入 delay_ms(1); LCD1602_E=0;//使能脚E后负跳变完成写入 } #endif //LCD1602初始化 #if (LCD1602_4OR8_DATA_INTERFACE==0)//8位LCD void lcd1602_init(void) { lcd1602_write_cmd(0x38);//数据总线8位,显示2行,5*7点阵/字符 lcd1602_write_cmd(0x0c);//显示功能开,无光标,光标闪烁 lcd1602_write_cmd(0x06);//写入新数据后光标右移,显示屏不移动 lcd1602_write_cmd(0x01);//清屏 } #else void lcd1602_init(void) { lcd1602_write_cmd(0x28);//数据总线4位,显示2行,5*7点阵/字符 lcd1602_write_cmd(0x0c);//显示功能开,无光标,光标闪烁 lcd1602_write_cmd(0x06);//写入新数据后光标右移,显示屏不移动 lcd1602_write_cmd(0x01);//清屏 } #endif //LCD1602清屏 void lcd1602_clear(void) { lcd1602_write_cmd(0x01); } //LCD1602显示字符 void lcd1602_show_string(u8 x,u8 y,u8 *str) { u8 i=0; if(y>1||x>15)return;//行列参数不对则强制退出 if(y<1) //第1行显示 { while(*str!='\0')//字符串是以'\0'结尾,只要前面有内容就显示 { if(i<16-x)//如果字符长度超过第一行显示范围,则在第二行继续显示 { lcd1602_write_cmd(0x80+i+x);//第一行显示地址设置 } else { lcd1602_write_cmd(0x40+0x80+i+x-16);//第二行显示地址设置 } lcd1602_write_data(*str);//显示内容 str++;//指针递增 i++; } } else //第2行显示 { while(*str!='\0') { if(i<16-x) //如果字符长度超过第二行显示范围,则在第一行继续显示 { lcd1602_write_cmd(0x80+0x40+i+x); } else { lcd1602_write_cmd(0x80+i+x-16); } lcd1602_write_data(*str); str++; i++; } } }
lcd1605.h部分代码:
#ifndef _lcd1602_H #define _lcd1602_H #include "public.h" //LCD1602数据口4位和8位定义,若为1,则为LCD1602四位数据口驱动,反之为8位 #define LCD1602_4OR8_DATA_INTERFACE 0 //默认使用8位数据口LCD1602 //管脚定义 sbit LCD1602_RS=P2^6;//数据命令选择 sbit LCD1602_RW=P2^5;//读写选择 sbit LCD1602_E=P2^7; //使能信号 #define LCD1602_DATAPORT P0 //宏定义LCD1602数据端口 //函数声明 void lcd1602_init(void); void lcd1602_clear(void); void lcd1602_show_string(u8 x,u8 y,u8 *str); #endif