新闻  |   论坛  |   博客  |   在线研讨会
基于51单片机的1602LCD显示
0750long | 2010-05-03 21:19:49    阅读:6072   发布文章

基于51单片机的1602LCD显示

    LCD(liquid crystal display)为液晶显示器,它一般不会单独使用,而是将LCD面板、驱动与控制电路组合成LCD模块(1iquid crystal display moulde,简称为LCM)来使用。LCM是一种很省电的显示设备,常被应用在数字或微处理器控制的系统,做为简易的人机接口,但人们一般还是习惯称之为LCD显示器。

 

硬件设计

采用51单片机控制1602LCD显示器的电路如下所示。

点击看大图

在桌面上双击图标,打开ISIS 7 Professional窗口(本人使用的是v7.4 SP3中文版)。单击菜单命令“文件”→“新建设计”,选择DEFAULT模板,保存文件名为“LCD.DSN”。在器件选择按钮中单击“P”按钮,或执行菜单命令“库”→“拾取元件/符号”,添加如下表所示的元件。

51单片机AT89C51    一片

晶体CRYSTAL 12MHz   一只

瓷片电容CAP 22pF    二只

电解电容CAP-ELEC 10uF   一只

电阻RES 10K         一只

排阻 RESPAC-8 10K       一只

1602液晶显示器 LM016L   一只

 

若用Proteus软件进行仿真,则上图中的晶振和复位电路以及U131脚,都可以不画,它们都是默认的。

在ISIS原理图编辑窗口中放置元件,再单击工具箱中元件终端图标,在对象选择器中单击POWER和GROUND放置电源和地。放置好元件后,布好线。左键双击各元件,设置相应元件参数,完成电路图的设计。

软件设计

1602LCD显示两行字符的流程图如下所示。

点击看大图

 

1602LCD显示“Welcom to China”和“Hi!Good morning!”的详细C51程序如下。

//LCD循环显示"Welcome to China""Hi!Good morning!"

#include<reg51.h>    //包含单片机的头文件

#include<intrins.h>  //包含_nop_()函数定义的头文件

sbit RS="P2"^0;    //寄存器选择位,将RS位定义为P2.0引脚

sbit RW="P2"^1;    //读写选择位,将RW位定义为P2.1引脚

sbit E="P2"^2;     //使能信号位,将E位定义为P2.2引脚

sbit BF="P0"^7;    //忙碌标志位,,将BF位定义为P0.7引脚

unsigned char code string[ ]={"Welcome to China"};

unsigned char code string1[ ]={"Hi!Good morning!"};

 

/*************************************************

函数功能:延时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();

 }

 

/*******************************************

函数功能:判断液晶模块的忙碌状态

返回值:resultresult=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;  //将忙碌标志电平赋给result

       E=0;

    return result;

}

 

/**************************************************

函数功能:将模式设置指令或显示地址写入液晶模块

入口参数:dictate

**************************************************/

void WriteInstruction (unsigned char dictate)

{  

       while(BusyTest()==1); //如果忙就等待

       RS=0;             //根据规定,RSR/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(为字符常量)

**************************************************/

void WriteData(unsigned char y)

{

       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的显示模式进行初始化设置

******************************************/

void LcdInitiate(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);

 }

 

void main(void)            //主函数

{

       unsigned char i;

     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”。在Project Workspace窗口中右击源代码组1,选择“添加文件到组‘源代码组 l’”将源程序“LCD.C”添加到项目中。

Keil中执行执行菜单命令“工程”→“创建目标”(或点击“创建目标”快捷按钮),编译源程序。如果编译成功,则在“Output Window”的“创建”窗口中显示没有错误,并创建了“LCD.HEX”文件。

 

仿真与调试

关于ProteusKeil的联合仿真调试,可参见我以前所写的博文或其它参考资料。

启动ProteusISIS,并将其放在屏幕的右上角(可将原理图放大到合适大小);再启动Keil的μVision3,并将其放在屏幕的左下角。

    在Keil中执行菜单命令“调试”→“启动/停止调试”,或直接单击图标进入Keil调试环境。同时,在Proteus ISIS的窗口中可看出Proteus也进入了程序调试状态。

    在Keil代码编辑窗口中设置相应断点,断点的设置方法:在需要设置断点语句前双击鼠标左键,可设置断点;再次双击,可取消该断点。

在Keil中按F5键(或点击“运行”快捷按钮)运行程序。1602LCD循环显示“Welcom to China”和“Hi!Good morning!”,如下图所示。

或可以点击单步、运行到光标处、全速运行等快捷按钮,以及同时观察工程窗口寄存器页面、存储器窗口等,来进行仿真调试。

 

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客