delay1ms();
}
/*******************************************
函数功能:
判断液晶模块的忙碌状态
返回值:
result。
result=1,忙碌;result=0,不忙
*******************************************/
unsignedcharBusyTest(void)
{
bitresult;
RS=0;//根据规定,RS为低电平,RW为高电平时,可以读状态
RW=1;
E=1;//E=1,才允许读写
_nop_();//空操作
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
result=BF;//将忙碌标志电平赋给result
E=0;
returnresult;
}
/**************************************************
函数功能:
将模式设置指令或显示地址写入液晶模块
入口参数:
dictate
**************************************************/
voidWriteInstruction(unsignedchardictate)
{
while(BusyTest()==1);//如果忙就等待
RS=0;//根据规定,RS和R/W同时为低电平时,可以写入指令
RW=0;
E=0;//E置低电平
_nop_();
_nop_();//空操作两个机器周期,给硬件反应时间
P0=dictate;//将数据送入P0口,即写入指令或地址
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=1;//E置高电平(正跳变)
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/**************************************************
函数功能:
将数据(字符的标准ASCII码)写入液晶模块
入口参数:
y(为字符常量)
**************************************************/
voidWriteData(unsignedchary)
{
while(BusyTest()==1);
RS=1;//RS为高电平,RW为低电平时,可以写入数据
RW=0;
E=0;//E置低电平
P0=y;//将数据送入P0口,即将数据写入液晶模块
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=1;//E置高电平(正跳变)
_nop_();
_nop_();
_nop_();
_nop_();//空操作四个机器周期,给硬件反应时间
E=0;//当E由高电平跳变成低电平时,液晶模块开始执行命令
}
/******************************************
函数功能:
对LCD的显示模式进行初始化设置
******************************************/
voidLcdInitiate(void)
{
delay(15);//延时15ms,首次写指令时应给LCD一段较长的反应时间
WriteInstruction(0x38);//显示模式设置:
8位数据,16×2显示,5×7点阵,delay(5);//延时5ms
WriteInstruction(0x38);
delay(5);
WriteInstruction(0x38);
delay(5);
WriteInstruction(0x0f);//显示模式设置:
显示开,有光标,光标闪烁
delay(5);
WriteInstruction(0x06);//显示模式设置:
光标右移,字符不移
delay(5);
WriteInstruction(0x01);//清屏幕指令,将以前的显示内容清除
delay(5);
}
voidmain(void)//主函数
{
unsignedchari;
LcdInitiate();//调用LCD初始化函数
delay(10);
while
(1)
{
WriteInstruction(0x01);//清显示:
清屏幕指令
WriteInstruction(0x80);//第一行显示地址
i=0;
while(string[i]!
='\0')
{//显示字符
WriteData(string[i]);
i++;
delay(150);
}
for(i=0;i<4;i++)
delay(250);
WriteInstruction(0xc0);//第二行显示地址
i=0;
while(string1[i]!
='\0')
{//显示字符
WriteData(string1[i]);
i++;
delay(150);
}
for(i=0;i<4;i++)
delay(250);
}
}
打开Keil程序(本人使用的是Keil8.05中文版),执行菜单命令“工程”→“新建工程”创建“LCD”项目,并选择单片机型号为AT89C51。
执行菜单命令“文件”→“新建”创建文件,输入C语言源程序,保存为“LCD.C”。
在ProjectWorkspace窗口中右击源代码组1,选择“添加文件到组‘源代码组l’”将源程序“LCD.C”添加到项目中。
在Keil中执行执行菜单命令“工程”→“创建目标”(或点击“创建目标”快捷按钮),编译源程序。
如果编译成功,则在“OutputWindow”的“创建”窗口中显示没有错误,并创建了“LCD.HEX”文件。
3仿真与调试
关于Proteus与Keil的联合仿真调试,可参见我以前所写的博文或其它参考资料。
启动Proteus的ISIS,并将其放在屏幕的右上角(可将原理图放大到合适大小);再启动Keil的μVision3,并将其放在屏幕的左下角。
在Keil中执行菜单命令“调试”→“启动/停止调试”,或直接单击图标
,进入Keil调试环境。
同时,在ProteusISIS的窗口中可看出Proteus也进入了程序调试状态。
在Keil代码编辑窗口中设置相应断点,断点的设置方法:
在需要设置断点语句前双击鼠标左键,可设置断点;再次双击,可取消该断点。
在Keil中按F5键(或点击“运行”快捷按钮)运行程序。
1602LCD循环显示“WelcomtoChina”和“Hi!
Goodmorning!
”,如下图所示。
或可以点击单步、运行到光标处、全速运行等快捷按钮,以及同时观察工程窗口寄存器页面、存储器窗口等,来进行仿真调试。