广告合作
  • 今日头条

    今日头条

  • 百度一下

    百度一下,你就知道

  • 新浪网

    新浪网 - 提供新闻线索,重大新闻爆料

  • 搜狐

    搜狐

  • 豆瓣

    豆瓣

  • 百度贴吧

    百度贴吧——全球领先的中文社区

  • 首页 尚未审核订阅工具 订阅

    Proteus在线仿真1602液晶串行显示之四线模式

    来源:网络收集  点击:  时间:2024-07-30
    【导读】:
    在单片机学习中一定会用到显示设备,以便于观察和学习。最常见的显示设备有 LED、LCD、数码管、TFT液晶等,当然还有一些辅助方式如串口打印信息、J-Link-RTT、逻辑分析仪等等。个人觉得逻辑分析仪是必备品。 本经验主要讲解Proteus仿真下结合Keil编程实现液晶LCD 1602的串行四线显示。 液晶LCD 1602是最简单的液晶显示设备,其操作简单方便,带有字库、便宜容易获得。一般市面上的1602液晶有黄绿屏和蓝屏两种,有两种电压驱动显示,5V驱动显示和3.3V驱动显示,而且液晶1602液晶可以支持8位并口显示和4位串口显示。仅需3条控制和4条数据地址线就可显示。在只写的情况下只需2条控制线和4条数据地址线。 液晶LCD 1602分两行显示,一行最多能显示16个字符,直接调用字库就行,每一行都有唯一的起始地址。四线显示更好的节约成本和资源,特别是在GPIO口有限的情况下或者不方便操作8个GPIO口时,四线显示的优势就体现出来了,也会有一定的缺陷比如显示速度不都快,但是对1602来说完全够,没必要担心这个问题。工具/原料more集成开发环境IDE Keil uVision4仿真软件Proteus ISIS 7 Professional方法/步骤1/5分步阅读

    【1】打开Proteus仿真软件,找到所需的元器件。

    MCU搜索AT89C52

    LCD1602搜索LM016L

    排阻搜索RESPACK-8

    【2】用元件器绘制好仿真电路图。

    LCD1602数据地址引脚连接在P0口,P0口默认是高阻状态,加排阻使其初始状态为高电平状态。

    LCD1602两个控制引脚接在P2口,LCD1602_RW引脚直接接地。

    P0口只是用低四位,高四位未使用。

    说明:

    因为是仿真所以有些部分可以省略不管,节约时间。本经验只讲解往LCD 1602里写数据,不讲解从LCD 1602里读出数据,所以第3引脚,即读写控制引脚WR直接接地即可。

    MCU选用Proteus里最常见的AT89C52单片机,其他单片机原理相似。

    MCU的复位电路和振荡电路可以省略不画,但是在做事物电路图时复位电路和振荡电路必须有。

    2/5

    【1】打开Keil uVision4软件,建立好相应的工程。

    【2】在工程中添加分组一下分组Core、User、Delay、LCD。

    Core存放启动代码STARTUP.A51,该启动代码用汇编编写的,初学者可以不用理会。

    User存放main.c文件,主函数所在的文件。

    Delay存放delay.c和delay.h文件,主要用于简答延时函数。

    LCD存放lcd.c和lcd.h文件主要是LCD1602相关的函数,比如写指令函数、写数据函数、初始化函数等

    【3】设置IDE生成.hex文件,.hex文件通过烧录软件直接烧录到MCU中运行,仿真中也需要加载这么文件,才能看到效果。

    【4】添加头文件路径。只要整个工程中的文件有.h结尾的都需要添加相应的文件路径。

    【5】在main.c文件中编写主函数,然后编译下看是否有错,有错,检测并更改错误,知道没错为止。

    #includereg52.h

    void main(void)

    {

    while(1)

    {

    }

    }

    3/5

    【1】编写延时函数、LCD1602 GIOP引脚的定义与初始化、LCD1602写数据函数、LCD1602写指令函数、LCD1602初始化函数等等。

    【2】延时函数:

    void vDelay(int i)

    {

    int x=0, y=0;

    for(x=0; x100; x++)

    for(y=0; yi; y++);

    }

    【3】LCD1602 GIOP引脚的定义:

    sbit LCD1602_RS_Pin = P2^0;

    sbit LCD1602_EN_Pin = P2^1;

    sbit LCD1602_DB4_Pin = P0^0;

    sbit LCD1602_DB5_Pin = P0^1;

    sbit LCD1602_DB6_Pin = P0^2;

    sbit LCD1602_DB7_Pin = P0^3;

    #define LCD1602_EN_SET()LCD1602_EN_Pin = 1

    #define LCD1602_EN_CLR() LCD1602_EN_Pin = 0

    #define LCD1602_RS_SET() LCD1602_RS_Pin = 1

    #define LCD1602_RS_CLR() LCD1602_RS_Pin = 0

    #define LCD1602_DB4_SET()LCD1602_DB4_Pin = 1

    #define LCD1602_DB4_CLR()LCD1602_DB4_Pin = 0

    #define LCD1602_DB5_SET()LCD1602_DB5_Pin = 1

    #define LCD1602_DB5_CLR()LCD1602_DB5_Pin = 0

    #define LCD1602_DB6_SET()LCD1602_DB6_Pin = 1

    #define LCD1602_DB6_CLR()LCD1602_DB6_Pin = 0

    #define LCD1602_DB7_SET()LCD1602_DB7_Pin = 1

    #define LCD1602_DB7_CLR()LCD1602_DB7_Pin = 0

    【4】LCD1602 GIOP引脚初始化

    static void vLCD1602_GPIO_Configuration(void)

    {

    LCD1602_EN_CLR();

    LCD1602_RS_CLR();

    LCD1602_DB4_CLR();

    LCD1602_DB5_CLR();

    LCD1602_DB6_CLR();

    LCD1602_DB7_CLR();

    }

    【5】LCD1602写数据函数:

    void vLCD1602_Write_Data(unsigned char dat)

    {

    if((dat7)%2==1){LCD1602_DB7_SET();}else{LCD1602_DB7_CLR();}

    if((dat6)%2==1){LCD1602_DB6_SET();}else{LCD1602_DB6_CLR();}

    if((dat5)%2==1){LCD1602_DB5_SET();}else{LCD1602_DB5_CLR();}

    if((dat4)%2==1){LCD1602_DB4_SET();}else{LCD1602_DB4_CLR();}

    LCD1602_RS_SET();

    LCD1602_EN_SET();

    vDelay(5);

    LCD1602_EN_CLR();

    if((dat3)%2==1){LCD1602_DB7_SET();}else{LCD1602_DB7_CLR();}

    if((dat2)%2==1){LCD1602_DB6_SET();}else{LCD1602_DB6_CLR();}

    if((dat1)%2==1){LCD1602_DB5_SET();}else{LCD1602_DB5_CLR();}

    if((dat0)%2==1){LCD1602_DB4_SET();}else{LCD1602_DB4_CLR();}

    LCD1602_RS_SET();

    LCD1602_EN_SET();

    vDelay(5);

    LCD1602_EN_CLR();

    }

    【6】LCD1602写指令函数

    void vLCD1602_Write_Command(unsigned char cmd)

    {

    if((cmd7)%2==1){LCD1602_DB7_SET();}else{LCD1602_DB7_CLR();}

    if((cmd6)%2==1){LCD1602_DB6_SET();}else{LCD1602_DB6_CLR();}

    if((cmd5)%2==1){LCD1602_DB5_SET();}else{LCD1602_DB5_CLR();}

    if((cmd4)%2==1){LCD1602_DB4_SET();}else{LCD1602_DB4_CLR();}

    LCD1602_RS_CLR();

    LCD1602_EN_SET();

    vDelay(5);

    LCD1602_EN_CLR();

    if((cmd3)%2==1){LCD1602_DB7_SET();}else{LCD1602_DB7_CLR();}

    if((cmd2)%2==1){LCD1602_DB6_SET();}else{LCD1602_DB6_CLR();}

    if((cmd1)%2==1){LCD1602_DB5_SET();}else{LCD1602_DB5_CLR();}

    if((cmd0)%2==1){LCD1602_DB4_SET();}else{LCD1602_DB4_CLR();}

    LCD1602_RS_CLR();

    LCD1602_EN_SET();

    vDelay(5);

    LCD1602_EN_CLR();

    }

    【7】LCD1602初始化函数

    void vLCD1602_Initialization(void)

    {

    vLCD1602_GPIO_Configuration();

    vDelay(5);

    vLCD1602_Write_Command(0x33);

    vDelay(5);

    vLCD1602_Write_Command(0x32);

    vDelay(5);

    vLCD1602_Write_Command(0x28);

    vDelay(5);

    vLCD1602_Write_Command(0x0C);

    vDelay(5);

    vLCD1602_Write_Command(0x01);

    vDelay(5);

    }

    【8】LCD1602显示字符串函数

    void vLCD1602_Show_String(unsigned char line, unsigned char x, unsigned char *str)

    {

    unsigned char WriteAdd = 0;

    if(line == LINE1)

    WriteAdd = LINE1_HEAD_ADDRESS + x;

    else if(line == LINE2)

    WriteAdd = LINE2_HEAD_ADDRESS + x;

    if((WriteAddLINE1_HEAD_ADDRESS) || (WriteAddLINE2_END_ADDRESS) || ((WriteAddLINE1_END_ADDRESS)(WriteAddLINE2_HEAD_ADDRESS)))

    return;

    vLCD1602_Write_Command(WriteAdd);//LCD1602_Write_Command

    while(*str)

    {

    vLCD1602_Write_Data(*str);//LCD1602_Write_Data

    str++;

    x++;

    WriteAdd++;

    if(x=16)

    {

    if(WriteAdd=LINE2_END_ADDRESS)

    {

    vLCD1602_Write_Command(LINE1_HEAD_ADDRESS);//LCD1602_Write_Command

    WriteAdd = LINE1_HEAD_ADDRESS;

    }

    else//WriteAddLINE1_END_ADDRESS

    {

    vLCD1602_Write_Command(LINE2_HEAD_ADDRESS);//LCD1602_Write_Command

    WriteAdd = LINE2_HEAD_ADDRESS;

    }

    x = 0;

    }

    }

    }

    所需要的宏定义:

    #define LINE11

    #define LINE22

    #define LINE1_HEAD_ADDRESS0X80

    #define LINE1_END_ADDRESS0X8F

    #define LINE2_HEAD_ADDRESS0XC0

    #define LINE2_END_ADDRESS0XCF

    说明:

    再开始编写代码时先要有一份1602的数据手册,

    1602数据手册手册网上很多随便找一份就好。主要看LCD 1602的读写时序,最主要是写时序,包括写数据和写地址。

    因为我们只往1602里写数据,所以读时序可以暂时不用看。还要明白一些基本的操作指令,这就够了,这就可以开始写程序了。

    4/5

    编写主函数测试程序。每隔一段时间加1,并显示在LCD1602上。

    #include lcd.h

    void main(void)

    {

    unsigned char i = 0;

    unsigned char dat = 0;

    vLCD1602_Initialization();//vLCD1602_Initialization

    vLCD1602_Show_String(LINE1, 1, System Running);

    vLCD1602_Show_String(LINE2, 2, Count:);

    while(1)

    {

    i++;

    dat = i / 100 + 0x30;

    vLCD1602_Write_Command(LINE2_HEAD_ADDRESS + 9);

    vLCD1602_Write_Data(dat);

    dat = (i / 10) % 10 + 0x30;

    vLCD1602_Write_Data(dat);

    dat = i%10 + 0x30;

    vLCD1602_Write_Data(dat);

    vDelay(100);

    }

    }

    5/5

    将.hex文件加载到仿真中,验证效果。

    注意事项

    本人原创经验,仅供参考,若有不足之处请留言指正,若觉得写得好或凑合的话,请点击本页面左下角投票,谢谢了\(^o^)/

    若有任何意见与帮助,请关注后私信留言,非喜勿喷

    需要相关帮助请投票后关注私信

    LCD1602四线显示串行显示PROTEUS仿真
    本文关键词:

    版权声明:

    1、本文系转载,版权归原作者所有,旨在传递信息,不代表看本站的观点和立场。

    2、本站仅提供信息发布平台,不承担相关法律责任。

    3、若侵犯您的版权或隐私,请联系本站管理员删除。

    4、文章链接:http://www.ff371.cn/art_1036537.html

    相关资讯

    ©2019-2020 http://www.ff371.cn/ 国ICP备20009186号06-04 12:34:28  耗时:1.018