BF=1,表示忙,LCM不能接收命令和数据;BF=0,表示LCM不忙,可以接收命令和数据。
AC位为地址计数器的值,范围为0~127。
【00~7FH】
例如:
(Busy_Check(>&0x80>==0x80>。
//取出最高位,判断是否忙。
【通常就是用来判断最高位是否为“1”,表示LCD忙,“0”表示不忙】
(10>写DDRAM或CGRAM命令格式:
【数据寄存器写入】
RS
D7
D6
D5
D4
D3
D2
D1
D0
1
0
DATA
功能:
将数据写入CGRAM或DDRAM中,应与CGRAM或DDRAM地址设置命令结合使用。
【命令9和命令10,肯定使用】
(11>读DDRAM或CGRAM命令格式:
【数据寄存器读出】
RS
D7
D6
D5
D4
D3
D2
D1
D0
1
1
DATA
功能:
从CGRAM或DDRAM中读出数据,应与CGRAM或DDRAM地址设置命令结合使用。
【一般不用】
液晶显示模块是一个慢显示器件,如果在执行每条指令之前,一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。
所以在写入命令或数据时,要先查询液晶显示模块是否忙。
显示字符时首先要输入显示字符地址,也就是告诉模块在什么位置显示字符,表8-2是TC1602EL液晶模块的内部显示位与DDRAM地址的对应关系。
表8-2显示位与DDRAM地址的对应关系
4.LCD显示器的初始化
LCD使用之前须对它进行初始化,初始化可通过复位完成,也可在复位后完成,初始化过程如下:
(1>清屏;
(2>功能设置;【一般有多条语句进行设置】
(3>开/关显示设置;
(4>输入方式设置。
8.2LCD显示器与单片机的接口与应用
下图是LCD显示器与8051单片机的接口连接图,图中RT-1602C的数据线与P0口相连,RS与P2.0相连,
与P2.1相连,E端与P2.2相连。
编程在LCD显示器的第一行、第一列开始显示“GOOD”,第二行、第6列开始显示“BYE”。
【第1脚:
VSS为电源地;
第2脚:
VDD为+5V电源;
第3脚:
VEE为液晶显示对比度调整端,可通过电位器调整对比度。
第4脚:
RS为数据/命令选择端
第5脚:
,读写操作选择<1-读,0-写)。
第6脚:
当E端由高电平跳变成低电平时<负跳变),液晶模块执行命令】
【例1】在LCD上显示GOODBYE245【已通过CAP8-EX1】
#include
sbitRS=P2^0。
sbitRW=P2^1。
sbitE=P2^2。
unsignedcharLCD_Status。
unsignedcharnum[]="0123456789"。
voiddelay(unsignedintcount>
{unsignedchari。
while(count-->
for(i=0。
i<120。
i++>。
}
unsignedcharBusy_Check(>//检查忙函数
{RS=0。
RW=1。
//RS=0,控制寄存器,RW=1,读
E=1。
delay(2>。
LCD_Status=P0。
//读出LCD的状态
delay(2>。
E=0。
//E端出现负跳变
returnLCD_Status。
}
voidwcmd(unsignedcharcmd>//写命令函数,RS=0;RW=0
{//&0x80取出最高位D7,见命令9<读忙标志BF及光标地址AC命令格式)
while((Busy_Check(>&0x80>==0x80>。
//写命令前,先检查设备是否忙?
RS=0;RW=0;//指令寄存器写入
E=1;//E设置为高电平
P0=cmd;//命令由P1口送入LCD
delay(2>;
E=0;//E由高电平到低电平跳变,液晶模块执行命令
}
voidwdat(unsignedchardat>//写数据函数,RS=1;RW=0
{
while((Busy_Check(>&0x80>==0x80>。
//写数据前,先检查设备是否忙?
RS=1;RW=0;
E=1;//E由高电平到低电平跳变,液晶模块执行命令
P0=dat;//数据由P1口送入LCD
delay(2>;//延时大约2ms
E=0;
}
voidLCD_init(>//初始化函数,主要写命令
{wcmd(0x38>。
//38H=00111000,使用8位,用5×7的字型,2行
delay(20>。
//改为0x3C=00111100,就用5×10字型
wcmd(0x01>。
//01H=00000001,清屏【命令1】
delay(20>。
//已经用检测是否忙,可以不用延时
wcmd(0x06>。
//06H=00000110,字符不动,光标自动右移一格【命令3】
delay(20>。
wcmd(0x0e>。
//0eH=00001110,开显示,有光标,字符不闪烁【命令4】
delay(20>。
}
//因为LCD是一慢速显示器件,所以在执行每条指令之前一定要确认LCD
//的忙标志为0,即非忙状态,否则该命令将失效。
voidmain(>//主函数
{unsignedcharx=245。
LCD_init(>。
//0x80,见命令8<显示缓冲区DDRAM地址设置命令格式)
wcmd(0x80+00>;//写入显示缓冲区起始地址为第1行第1列
wdat(‘G’>;//第1行第1列显示字母“G”
wdat(‘O’>;//第1行第2列显示字母“O”
wdat(‘O’>;//第1行第3列显示字母“O”
wdat(‘D’>;//第1行第4列显示字母“D”
//【80H+45H=C5H】
wcmd(0x80+0x45>;//写入显示缓冲区起始地址为第2行第6列
wdat(‘B’>;//第2行第6列显示字母“B”
wdat(‘Y’>;//第2行第7列显示字母“Y”
wdat(‘E’>;//第2行第8列显示字母“E”
wdat(x/100+0x30>。
//加0x30,把数字变为字符型,//最高位
wdat((x/10>%10+0x30>。
wdat(x%10+0x30>。
//最低位
/*wdat(num[x/100]>。
//最高位,也可以用字符数组来变换
wdat(num[(x/10>%10]>。
wdat(num[x%10]>。
//最低位*/
while(1>;
}
【写入时,需要送相应的字符。
如果需要显示数字,则需要转换成字符】
【例2】向LCD1602写任意的字符串【已通过CAP8-EX2】
#include//【已通过CAP8-EX2】
#include//strlen函数的原型在string.h中
voidInit_LCD(>。
voidShowString(unsignedchar,unsignedchar>。
voidWcmd(unsignedchar>。
voidWdat(unsignedchar>。
voidDelay(unsignedint>。
unsignedcharBusy_Check(>。
unsignedcharPrompt[]="1234567890abcdefghijklmnopqrstuvwxyz"。
sbitRS=P2^0。
sbitRW=P2^1。
sbitEN=P2^2。
voidDelay(unsignedintcount>////延时函数
{
unsignedchari。
while(count-->
for(i=0。
i<120。
i++>。
}
voidInit_LCD(>//初始化LCD
{
Wcmd(0x38>。
//00111000,8位,2行显示,用5×7点阵字符
Delay(1>。
Wcmd(0x01>。
//00000001,清屏
Delay(1>。
Wcmd(0x06>。
//00000110,字符不动,光标自动右移一格。
命令3
Delay(1>。
Wcmd(0x0e>。
//00001110,开显示,有光标,字符不闪烁
Delay(1>。
//0x0c=00001100,开显示,无光标,字符不闪烁
}
voidShowString(unsignedcharx,unsignedchary>
{
unsignedchari=0。
if(y==1>
{Wcmd(0x80|x>。
//命令8要求最高位为“1”,第一行的第x位置开始写
if(strlen(Prompt>>16>
for(i=0。
i<16。
i++>//一行显示16个字符
Wdat(Prompt[i]>。
else
for(i=0。
i。
i++>//一行显示16个字符
Wdat(Prompt[i]>。
}
if(y==2>
{
Wcmd(0xc0|x>。
//0x80+0x40=0xc0,从第二行的第x位置开始写
if(strlen(Prompt>>31>
for(i=16。
i<32。
i++>//一行显示16个字符
Wdat(Prompt[i]>。
else
for(i=16。
i。
i++>
Wdat(Prompt[i]>。
}
}
voidWcmd(unsignedcharcmd>//写命令函数
{
while((Busy_Check(>&0x80>==0x80>。
RS=0。
RW=0。
//写命令,RS=0;RW=0
EN=1。
P0=cmd。
Delay(1>。
EN=0。
//EN由高电平到低电平跳变,液晶模块执行命令
}
voidWdat(unsignedchardat>//写数据函数
{
while((Busy_Check(>&0x80>==0x80>。
RS=1。
RW=0。
//写数据,RS=1;RW=0
EN=1。
P0=dat。
Delay(1>。
EN=0。
//EN由高电平到低电平跳变,液晶模块执行命令
}
unsignedcharBusy_Check(>//检查是否忙
{
unsignedcharLCD_Status。
RS=0。
RW=1。
//读忙状态,RS=0;RW=1
EN=1。
LCD_Status=P0。
Delay(1>。
EN=0。
//EN由高电平到低电平跳变,液晶模块执行命令
returnLCD_Status。
}
voidmain(>//主函数
{
Init_LCD(>。
ShowString(0,1>。
//(x,y>,x开始写的列(从0~15>,y=1,显示在第1行
if(strlen(Prompt>>16>ShowString(0,2>。
//(x,y>,x开始写的列,y=2在第2行
while(1>。
}
【例题扩展1】用LCD1602来显示ADC0809的转换结果
#include【已经通过CAP8-LCD-0809】
#include
sbitRS=P2^0。
sbitRW=P2^1。
sbitE=P2^2。
sbitADDC=P1^6。
sbitADDB=P1^5。
sbitADDA=P1^4。
unsignedcharLCD_Status。
unsignedcharnum[]="0123456789"。
unsignedcharmes[]="TheValueis:
"。
sbitOE=P1^0。
sbitEOC=P1^1。
sbitSTART=P1^2。
sbitCLK=P1^3。
voiddelay(unsignedintcount>
{unsignedchari。
while(count-->
for(i=0。
i<120。
i++>。
}
unsignedcharBusy_Check(>//检查忙函数
{RS=0。
RW=1。
E=1。
delay(2>。
E=0。
returnLCD_Status。
}
voidwcmd(unsignedcharcmd>
{while((Busy_Check(>&0x80>==0x80>。
RS=0。
RW=0。
E=1。
P0=cmd。
delay(2>。
E=0。
}
voidwdat(unsignedchardat>
{while((Busy_Check(>&0x80>==0x80>。
RS=1。
RW=0。
E=1。
P0=dat。
delay(2>。
E=0。
}
voidinit(>
{wc