微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > lcd1602 4位总线 乱码

lcd1602 4位总线 乱码

时间:10-02 整理:3721RD 点击:
我刚学习单片机用1602时总是出现乱码,在网上查了半天还是没有解决问题,望高人相助!下面是我的代码#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P2^6;
sbit rw=P2^5;
sbit en=P2^7;
uchar code table0[]="I LOVE YOU !";
uchar code table1[]="I LOVE YOU !";
void delay(uchar z)
{
  uchar x,y;
  for(x=z;x>0;x--)
    for(y=110;y>0;y--);
}
void write_com(uchar com)
{
  uchar gao,di;
  rs=0;
  rw=0;
  gao=com&0xf0;                  //分离高4位
  di=(com<<4)&0xf0;          //分离低4位
  P0=gao;
  delay(5);
  en=1;
  delay(5);
  en=0;
  P0=di;
  delay(5);
  en=1;
  delay(5);
  en=0;
}
void write_data(uchar date)
{
  uchar gao,di;
  rs=1;
  rw=0;
  gao=date&0xf0;         //分离高4位
  di=(date<<4)&0xf0;          //分离低4位
  P0=gao;
  delay(5);
  en=1;
  delay(5);
  en=0;
  P0=di;
  delay(5);
  en=1;
  delay(5);
  en=0;
}
void initial()
{
  en=0;
  write_com(0x38);
  write_com(0x0c);
  write_com(0x06);
  write_com(0x01);
  write_com(0x80);
}
void main()
{
  uchar i;
  initial();
  for(i=0;i<12;i++)
    {
      write_data(table0[i]);
      delay(20);  
    }
  write_com(0x80+0x40);
  for(i=0;i<12;i++)
    {
      write_data(table1[i]);
      delay(20);  
    }
}

4总线LCD初始化错了
void initial()
{
  en=0;
  write_com(0x32);
  write_com(0x28);
  write_com(0x0c);
  write_com(0x06);
  write_com(0x01);
  write_com(0x80);
}

没有给4总线配置端口

#ifndef __LCD__
#define __LCD__
sbit rs=P3^0;
sbit rw=P3^1;
sbit en=P3^2;
sbit key_left=P2^0;
sbit key_right=P2^1        ;
#define DATAPORT P0
#define BUSY  0x80                               //常量定义
#define uchar unsigned char
#define uint unsigned int
uchar code opens[]="MACROSS";
uchar code opens1[]="FRONTIER";
uchar code hanzi[3][8]={0x1f,0x11,0x11,0x1f,0x11,0x11,0x1f,0x00,
                                           0x0f,0x09,0x0f,0x09,0x0f,0x09,0x11,0x00,
                                           0x08,0x0f,0x12,0x0f,0x0a,0x1f,0x02,0x02};
void open();
void ini();
void write_order(uchar order,uchar BusyC) ;
void write_date(uchar date);
void delay(uchar z);
void writeCG();
void ini()
{
        rw=0;
        en=0;
        P2=0xff;
        writeCG();
        write_order(0x38,1);
        write_order(0x0c,1);
        write_order(0x06,1);
        write_order(0x01,1);
       
}
void lcd_wait(void)
{
    DATAPORT=0xff;             //读LCD前若单片机输出低电平,而读出LCD为高电平,则冲突,Proteus仿真会有显示逻辑黄色
        en=1;
    rs=0;   
    rw=1;   
    _nop_();
    _nop_();
        _nop_();
    while(DATAPORT&BUSY)  
        {  en=0;
           _nop_();
           _nop_();
           en=1;
           _nop_();
           _nop_();
           }         
   en=0;       
       
}
void write_order(uchar com,uchar BusyC)
{
/*        rs=0;
        P2=order;
        delay(4);
        en=1;
        delay(4);
        en=0;         */
         if(BusyC)lcd_wait();
        DATAPORT=com;
    rs=0;                   // 选中指令寄存器
    rw=0;                       // 写模式       
    en=1;   
        _nop_();   
        _nop_();
        _nop_();
    en=0;
}
void write_date(uchar date)
{       
/*        rs=1;
        P2=date;
        delay(4);
        en=1;
        delay(4);
        en=0;         */
         lcd_wait( );             //检测忙信号   
        DATAPORT=date;
    rs=1;                // 选中数据寄存器
    rw=0;                    // 写模式
    en=1;
    _nop_();
        _nop_();
        _nop_();
    en=0;
}
void delay(uchar z)
{
        uchar x,y;
        for(x=z;x>0;x--)
                for(y=110;y>0;y--);
}
void writeCG()
{
        uchar x,y;
        write_order(0x40,1);
        for(y=0;y<3;y++)
        {
                for(x=0;x<8;x++)
                {
                        write_date(hanzi[y][x]);
                }
        }
       
}
void open()
{
        uchar num;
        write_order(0x80+0x10,1);
        for(num=0;opens[num]!='\0';num++)
        {
                write_date(opens[num]);
                //delay(20);
        }
       
                        for(num=0;num<16;num++)
        {
                write_order(0x1c,1);
                //delay(200);
        }
                        for(num=0;num<5;num++)
        {
                write_order(0x18,1);
                //delay(200);
        }
                        for(num=0;num<4;num++)
        {
                write_order(0x1c,1);
                //delay(200);
        }
                        for(num=0;num<3;num++)
        {
                write_order(0x18,1);
                //delay(200);
        }
                        for(num=0;num<2;num++)
        {
                write_order(0x1c,1);
        //        delay(200);
        }
                        for(num=0;num<1;num++)
        {
                write_order(0x18,1);
        //        delay(100);
        }
        write_order(0x80+0x53,1);
        for(num=0;opens1[num]!='\0';num++)
        {
                write_date(opens1[num]);
        //        delay(500);
        }
}
#endif

把这段lcd初始化程序加进去,应该就好了

我把程序按你这种方式改了之后,以前屏幕会整体移动,现在好了,并且刚开始出现  I LOVE YOU 这几个单词,之后又没了,斜着看能看见几个字母,但不是刚才那几个字母了并且只出来了一行,这是怎么回事啊

这个是一整段程序吧,初始化程序应该就几行才对的啊

非常感谢,已经好了,我把write_com(0x32);删了,在最后加上 while(1);就好了

解决了么   我也乱码  还以为是我判忙函数的问题

你没有判忙函数也可以显示么?

如果小编的1602还没焊死,还有修改余地的话,可以使用8总线的驱动方式,因为8总线驱动方式你可以直接用74HC595驱动,595是3线驱动,把RW接地,RS,EN引出来,那么一共占用5个io口。

8总线方式可以省略判忙。

但是小编是四线传输啊   要判忙函数的吧

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top