
1602LCD显示原理
通过电压来改变填充在两块平行板之间的液晶材料内部分子的排列状况,以达到遮光和透光的目的来显示深浅不一,错落有致的图象,而且只要在两块平板间再加上三元色的滤光层,就可实现显示彩色图象。液晶是具有流动特性的物质,所以只需外加很微小的力量即可使液晶分子运动,以最常见普遍的向列型液晶为例,液晶分子可轻易的借着电场作用使得液晶分子转向,由于液晶的光轴与其分子轴相当一致,故可借此产生光学效果,而当加于液晶的电场移除消失时,液晶将借着其本身的d性及黏性,液晶分子将十分迅速的回撤消来未加电场前的状态。
1602液晶资料详解
1602LCD采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如下表所示:
编号 符号 引脚说明 编号 符号 引脚说明
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 背光源负极
1602液晶模块引脚说明:
第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脚:背光源负极。
1602LCD的指令说明及时序
1602液晶模块内部的控制器共有11条控制指令,如下表所示:
序号 指令 RS R/W D7 D6 D5 D4 D3 D2 D1 D0
1 清显示 0 0 0 0 0 0 0 0 0 1
2 光标返回 0 0 0 0 0 0 0 0 1
3 置输入模式 0 0 0 0 0 0 0 1 I/D S
4 显示开/关控制 0 0 0 0 0 0 1 D C B
5 光标或字符移位 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 读出的数据内容
602液晶模块的读写 *** 作、屏幕和光标的 *** 作都是通过指令编程来实现的。(说明:1为高电平、0为低电平)
指令1:清显示,指令码01H,光标复位到地址00H位置。
指令2:光标复位,光标返回到地址00H。
指令3:光标和显示模式设置 I/D:光标移动方向,高电平右移,低电平左移 S:屏幕上所有文字是否左移或者右移。高电平表示有效,低电平则无效。
指令4:显示开关控制。 D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示 C:控制光标的开与关,高电平表示有光标,低电平表示无光标 B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。
指令5:光标或显示移位 S/C:高电平时移动显示的文字,低电平时移动光标。
指令6:功能设置命令 DL:高电平时为4位总线,低电平时为8位总线 N:低电平时为单行显示,高电平时双行显示 F: 低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。
指令7:字符发生器RAM地址设置。
指令8:DDRAM地址设置。
指令9:读忙信号和光标地址 BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。
指令10:写数据。
指令11:读数据。
读状态 输入 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=高脉冲 输出 无
602LCD的RAM地址映射及标准字库表
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,下图是1602的内部显示地址。
在这里插入描述
例如第二行第一个字符的地址是40H,那么是否直接写入40H就可以将光标定位在第二行第一个字符的位置呢?这样不行,因为写入显示地址时要求最高位D7恒定为高电平1所以实际写入的数据应该是01000000B(40H)+10000000B(80H)=11000000B(C0H)。
在对液晶模块的初始化中要先设置其显示模式,在液晶模块显示字符时光标是自动右移的,无需人工干预。每次输入指令前都要判断液晶模块是否处于忙的状态。
1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,如图所示,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”
在这里插入描述
显示字符编码
根据1602LCD的文档说明,可根据文档的要求进行编程,显示需要显示的字符,通过程序代码的实现,能够更清楚1602LCD的使用。
#include<reg52h> //包含头文件,这个嘛,就不用多说了~~
#define uint unsigned int //预定义一下
#define uchar unsigned char
sbit rs=P3^5; //1602的数据/指令选择控制线
sbit rw=P3^6; //1602的读写控制线
sbit en=P3^7; //1602的使能控制线
/P2口接1602的D0~D7,注意不要接错了顺序,我以前可在这上面吃过亏~/
uchar code table[]="LCD1602 check ok"; //要显示的内容1放入数组tablel
uchar code table1[]="study up"; //要显示的内容2放入数组table1
void delay(uint n) //延时函数
{
uint x,y;
for(x=n;x>0;x--)
for(y=110;y>0;y--);
}
void lcd_wcom(uchar com) //1602写命令函数
{
rs=0; //选择指令寄存器
rw=0; //选择写
P2=com; //把命令字送入P2
delay(5); //延时一小会儿,让1602准备接收数据
en=1; //使能线电平变化,命令送入1602的8位数据口
en=0;
}
void lcd_wdat(uchar dat) //1602写数据函数
{
rs=1; //选择数据寄存器
rw=0; //选择写
P2=dat; //把要显示的数据送入P2
delay(5); //延时一小会儿,让1602准备接收数据
en=1; //使能线电平变化,数据送入1602的8位数据口
en=0;
}
void lcd_init() //1602初始化函数
{
lcd_wcom(0x38); //8位数据,双列,57字形
lcd_wcom(0x0c); //开启显示屏,关光标,光标不闪烁
lcd_wcom(0x06); //显示地址递增,即写一个数据后,显示位置右移一位
lcd_wcom(0x01); //清屏
}
void main() //主函数
{
uchar n,m=0;
lcd_init(); //液晶初始化
lcd_wcom(0x80); //显示地址设为80H(即00H,)上排第一位
for(m=0;m<16;m++) //将table[]中的数据依次写入1602显示
{
lcd_wdat(table[m]);
delay(200);
}
lcd_wcom(0x80+0x44); //重新设定显示地址为0xc4,即下排第5位
for(n=0;n<8;n++) //将table1[]中的数据依次写入1602显示
{
lcd_wdat(table1[n]);
delay(200);
}
while(1); //动态停机
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
void init_1602()
{
LCD_1602_EN=0;
LCD_1602_RW=0; //这句话你忘写了,液晶数据也不进去的。。
write_1602_com(0x38); //设置16X2显示,5X7点阵,8位数据接口
write_1602_com(0x0e); //设置开显示,不显示光标
write_1602_com(0x06); //写一个字符后地址指针加1
write_1602_com(0x01); //显示清0,数据指针清0
write_1602_com(0x80); //设置初始显示为第一行第一列
}
/实例81:用LCD显示字符'A'/#include<reg51h> /包含单片机寄存器的头文件#include<intrinsh> /包含_nop_()函数定义的头文件sbit RS=P20; /寄存器选择位,将RS位定义为P20引脚sbit RW=P21; /读写选择位,将RW位定义为P21引脚sbit E=P22; /使能信号位,将E位定义为P22引脚sbit BF=P07; /忙碌标志位,将BF位定义为P07引脚/函数功能:延时1ms(3j+2)i=(3×33+2)×10=1010(微秒),可以认为是1毫秒/void delay1ms() unsigned char i,j; for(i=0;i<10;i+) for(j=0;j<33;j+) ; /函数功能:延时若干毫秒入口参数:n/ void delay(unsigned char n) unsigned char i;for(i=0;i<n;i+) delay1ms(); /函数功能:判断液晶模块的忙碌状态返回值:result。result=1,忙碌;result=0,不忙/ unsigned char BusyTest(void) bit result;RS=0; /根据规定,RS为低电平,RW为高电平时,可以读状态 RW=1; E=1; /E=1,才允许读写 _nop_(); /空 *** 作 _nop_(); _nop_(); _nop_(); /空 *** 作四个机器周期,给硬件反应时间 result=BF; /将忙碌标志电平赋给resultE=0; return result; /函数功能:将模式设置指令或显示地址写入液晶模块入口参数:dictate/void WriteInstruction (unsigned char dictate) while(BusyTest()=1); /如果忙就等待 RS=0; /根据规定,RS和R/W同时为低电平时,可以写入指令 RW=0; E=0; /E置低电平(根据表8-6,写指令时,E为高脉冲, / 就是让E从0到1发生正跳变,所以应先置"0" _nop_(); _nop_(); /空 *** 作两个机器周期,给硬件反应时间 P0=dictate; /将数据送入P0口,即写入指令或地址 _nop_(); _nop_(); _nop_(); _nop_(); /空 *** 作四个机器周期,给硬件反应时间 E=1; /E置高电平 _nop_(); _nop_(); _nop_(); _nop_(); /空 *** 作四个机器周期,给硬件反应时间 E=0; /当E由高电平跳变成低电平时,液晶模块开始执行命令 /函数功能:指定字符显示的实际地址入口参数:x/ void WriteAddress(unsigned char x) WriteInstruction(x|0x80); /显示位置的确定方法规定为"80H+地址码x" /函数功能:将数据(字符的标准ASCII码)写入液晶模块入口参数:y(为字符常量)/ void WriteData(unsigned char y) while(BusyTest()=1); RS=1; /RS为高电平,RW为低电平时,可以写入数据 RW=0; E=0; /E置低电平(根据表8-6,写指令时,E为高脉冲, / 就是让E从0到1发生正跳变,所以应先置"0" P0=y; /将数据送入P0口,即将数据写入液晶模块 _nop_(); _nop_(); _nop_(); _nop_(); /空 *** 作四个机器周期,给硬件反应时间 E=1; /E置高电平 _nop_(); _nop_(); _nop_(); _nop_(); /空 *** 作四个机器周期,给硬件反应时间 E=0; /当E由高电平跳变成低电平时,液晶模块开始执行命令 /函数功能:对LCD的显示模式进行初始化设置/void LcdInitiate(void) delay(15); /延时15ms,首次写指令时应给LCD一段较长的反应时间 WriteInstruction(0x38); /显示模式设置:16×2显示,5×7点阵,8位数据接口delay(5); /延时5msWriteInstruction(0x38);delay(5);WriteInstruction(0x38);delay(5);WriteInstruction(0x0f); /显示模式设置:显示开,有光标,光标闪烁delay(5);WriteInstruction(0x06); /显示模式设置:光标右移,字符不移delay(5);WriteInstruction(0x01); /清屏幕指令,将以前的显示内容清除delay(5); void main(void) /主函数 LcdInitiate(); /调用LCD初始化函数 WriteAddress(0x07); /将显示地址指定为第1行第8列 WriteData('A'); /将字符常量'A'写入液晶模块 /字符的字形点阵读出和显示由液晶模块自动完成 while(1);一、 LCD1602循环右移显示字符串斧头帮 2010-05-10Proteus仿真图:C程序:/用LCD循环右移显示"Welcome to China"#include<reg51h> /包含单片机寄存器的头文件#include<intrinsh> /包含_nop_()函数定义的头文件sbit RS=P20; /寄存器选择位,将RS位定义为P20引脚sbit RW=P21; /读写选择位,将RW位定义为P21引脚sbit E=P22; /使能信号位,将E位定义为P22引脚sbit BF=P07; /忙碌标志位,将BF位定义为P07引脚unsigned char code string ="Welcome to China" /函数功能:延时1ms(3j+2)i=(3×33+2)×10=1010(微秒),可以认为是1毫秒/void delay1ms() unsigned char i,j; for(i=0;i<10;i+) for(j=0;j<33;j+) ; /函数功能:延时若干毫秒入口参数:n/ void delay(unsigned char n) unsigned char i;for(i=0;i<n;i+) delay1ms(); /函数功能:判断液晶模块的忙碌状态返回值:result。result=1,忙
实际上1602显示汉字不怎么好写,因为显示一个汉字要16X16的点阵才可以,而1602是8X8的点阵(显示屏幕由16X2个8X8的点阵构成),按你的要求显示你的名字就得要8个8X8的点阵才能显示,而1602里面刚好显示8个自定义字符,所以刚刚好可以显示你的名字、、、、下面给出锐志开发板的程序,你修改一下就可以用了、、、、、、
#include<reg52h> //包含单片机寄存器的头文件
#include<intrinsh> //包含_nop_()函数定义的头文件
sbit RS=P2^0; //寄存器选择位,将RS位定义为P20引脚
sbit RW=P2^1; //读写选择位,将RW位定义为P21引脚
sbit E=P2^2; //使能信号位,将E位定义为P22引脚
sbit BF=P0^7; //忙碌标志位,,将BF位定义为P07引脚
unsigned char code User[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//自定义字符℃ /
/
函数功能:延时1ms
/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
;
}
/
函数功能:延时若干毫秒
入口参数:n
/
void delay(unsigned int n)
{
unsigned int i;
for(i=0;i<n;i++)
delay1ms();
}
/
函数功能:判断液晶模块的忙碌状态
返回值:result。result=1,忙碌;result=0,不忙
/
bit BusyTest(void)
{
bit result;
RS=0; //根据规定,RS为低电平,RW为高电平时,可以读状态
RW=1;
E=1; //E=1,才允许读写
_nop_(); //空 *** 作
_nop_();
_nop_();
_nop_(); //空 *** 作四个机器周期,给硬件反应时间
result=BF; //将忙碌标志电平赋给result
E=0;
return result;
}
/
函数功能:将模式设置指令或显示地址写入液晶模块
入口参数:dictate
/
void Write_com (unsigned char dictate)
{
while(BusyTest()==1); //如果忙就等待
RS=0; //根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
E=0; //E置低电平(写指令时,
// 就是让E从0到1发生正跳变,所以应先置"0"
_nop_();
_nop_(); //空 *** 作两个机器周期,给硬件反应时间
P0=dictate; //将数据送入P0口,即写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_(); //空 *** 作四个机器周期,给硬件反应时间
E=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空 *** 作四个机器周期,给硬件反应时间
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/
函数功能:指定字符显示的实际地址
入口参数:x
/
void WriteAddress(unsigned char x)
{
Write_com(x|0x80); //显示位置的确定方法规定为"80H+地址码x"
}
/
函数功能:将数据(字符的标准ASCII码)写入液晶模块
入口参数:y(为字符常量)
/
void WriteData(unsigned char y)
{
while(BusyTest()==1);
RS=1; //RS为高电平,RW为低电平时,可以写入数据
RW=0;
E=0; //E置低电平(写指令时,,
// 就是让E从0到1发生正跳变,所以应先置"0"
P0=y; //将数据送入P0口,即将数据写入液晶模块
_nop_();
_nop_();
_nop_();
_nop_(); //空 *** 作四个机器周期,给硬件反应时间
E=1; //E置高电平
_nop_();
_nop_();
_nop_();
_nop_(); //空 *** 作四个机器周期,给硬件反应时间
E=0; //当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/
函数功能:对LCD的显示模式进行初始化设置
/
void LcdInt(void)
{
delay(15); //延时15ms,首次写指令时应给LCD一段较长的反应时间
Write_com(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口
delay(5); //延时5ms
Write_com(0x38);
delay(5);
Write_com(0x38); //3次写 设置模式
delay(5);
Write_com(0x0F); //显示模式设置:显示开,有光标,光标闪烁
delay(5);
Write_com(0x06); //显示模式设置:光标右移,字符不移
delay(5);
Write_com(0x01); //清屏幕指令,将以前的显示内容清除
delay(5);
}
void main(void) //主函数
{
unsigned char i,j;
LcdInt(); //调用LCD初始化函数
delay(10);
while(1)
{
Write_com(0x01);//清显示:清屏幕指令
delay(5);
Write_com(0x40); //设定CGRAM地址
delay(5);
for(j=0;j<8;j++ )
{
WriteData(User[j]);//写入自定义图形 ℃
}
WriteAddress(0x05);//设定屏幕上的显示位置
delay(5);
WriteData(0x00); //从CGRAM里取出自定义图形显示
while(1);
}
}
51单片机对lcd1602一些基础程序
#include <intrinsh>
#define dataport P1
sbit RS=P2^ 6;
sbit RW=P2^5;
sbit EN=P2^4;
//========================
//=========================
void waitfor() //检测忙信号函数
{
dataport=0xff;
RS=0;RW=1;_nop_(); //选择指令寄存器 读 *** 作
EN=1;_nop_(); //使能 *** 作
while(dataport&0x80); //如果最高位是1 表示1602正忙 原地踏步 忙完后芯片会将高位拉低
EN=0;
}
//======================
void writedata(unsigned char dataw) //写数据到lcm
{
waitfor(); //测忙
RS=1;RW=0;_nop_(); //选择数据寄存器 写 *** 作
dataport=dataw;_nop_(); //将数据送到数据口
EN=1;_nop_();_nop_();EN=0; //使能
}
//==========================
void writecmd(unsigned char cmd) //写命令到lcm
{
waitfor();
RS=0;RW=0;_nop_();
dataport=cmd;_nop_();
EN=1;_nop_();_nop_();EN=0;
}
//===========================
void init(void) // 初始化函数
{
writecmd(0x38); //功能设定 8位数据传输 双行显示
writecmd(0x0c);//显示器开关
writecmd(0x01);//清屏
writecmd(0x06);//字符进入模式 每进入一个字符光标向右移动一格 原有字符不动
//我在刚开始学的时候不知道下一个字符显示在哪 是和AC值有关还是和光标位置有关
//最后摸索出来是只和光标定位有关 现在还是不知道Ac值有什么用
}
//=========================
void location(unsigned char x,unsigned char y) //确实坐标函数
{
unsigned char temp;
temp=x&0x0f; //只要x数据的后四位
if(y){temp=temp|0x40;} //第一行为0 第二行为1 如果y=1则地址加0x40
temp|=0x80; //DDRAM地址的命令DB7为一
writecmd(temp);
}
//==============================
void displyonechar(unsigned char x,unsigned char y,unsigned char dataw) //显示一个字符函数
{
location(x,y);
writedata(dataw);
}
//=======================================
void displylistchar(unsigned char x,unsigned char y,unsigned char p) //显示字符串
{
while(p) //当一个字符型数组读完时P指的为零
{
displyonechar(x,y,(p++));
x++;
}
}
//=====================================================
void writecgram(unsigned char address,unsigned char p) //写CGRAM的数据
{
unsigned char i=8;
writecmd(address); //CGRAM里的地址 初始值0x40 每次加0x80
while(i--)
{
writedata(p);
p++;
}
}
//=====================================================
void displyonecharacter(unsigned char x,unsigned char y,unsigned char address,unsigned char p) //显示一个自定义字符
{
unsigned char i=8;
writecmd(address); //CGRAM里的地址 初始值0x40 每次加0x08
while(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 nin[]={0x08,0x0f,0x12,0x0f,0,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,nin);
displyonecharacter(1,0,0x80,yue);
displyonecharacter(1,0,0xc0,ri);
不好意思,您的经验真得很不够,这是十分简单的程序,你不懂估计是没有去看液晶的数据手册,或者懒得去看,都是不好的
//
/ 写入字节函数 /
//
void ShowChar(unsigned char pos,unsigned char c)
{
unsigned char p;
if (pos>=0x10) //液晶中,写入不同的行,使用不同的命令,命令保存在p这个变量里面,如果写入第一行,使用else那里的命令,否则使用下面的
p=pos+0xb0; //命令代码高4位为0xc表示写入第二行,即0xb0+0x10=0xc0,后面的四位指示第二行具体哪一个位置,一共有16个位置
else
p=pos+0x80; //命令代码高4位为0x8表示写入第二行,即0x80+0x00=0x80,后面的四位指示第一行具体哪一个位置,一共有16个位置
WriteCommand (p);//写命令
WriteData (c); //写数据
}
//
/ 写入字符串函数 /
//
void ShowString (unsigned char line,char ptr)
{
unsigned char l,i;
l=line<<4; //就是乘以16,0-15在第一行,16-35在第二行
for (i=0;i<16;i++)
ShowChar (l++,(ptr+i));//循环显示16个字符 //调用上面的函数在l位置进行显示
}
以上就是关于如何使用voiddisplay函数控制液晶1602显示全部的内容,包括:如何使用voiddisplay函数控制液晶1602显示、这是在CC2530单片机下面写的一个1602的液晶显示程序,大家看看哪里出问题了啊,是不是IO口的初始化有问题。、1602液晶显示模块执行读 *** 作时,wr信号要设置成什么电平等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)