微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 为何LCD1602在仿真上能显示,在硬件上不能显示。

为何LCD1602在仿真上能显示,在硬件上不能显示。

时间:10-02 整理:3721RD 点击:


各位大神,LCD1602为何在仿真上能显示,在硬件上不能显示,求助啊。
       线路连接没有问题,也不存在背光问题。,
各位大神,帮我支支招。

程序如下:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define ulong unsigned long
#define uint  unsigned int
uchar idata     welcome[16]={"    clock       "};                //定义第一行显示数组
uchar idata   lwelcome[16]={"      clock     "};                //定义第一行显示数组
uchar idata   llwelcome[16]={"        clock   "};                //定义第一行显示数组
uchar idata  lllwelcome[16]={"          clock "};                //定义第一行显示数组
uchar  idata  sslcdtimer[16]={"    00:00:00    "};
uchar  idata tsslcdtimer[16]={"    00:00:00    "};
uchar  idata   lcdtimer[16]={"    00:00:00    "};                //定义第二行显示数组
uchar  idata  mlcdtimer[16]={"    00:  :      "};                //定义第二行显示数组
uchar  idata   hlcdtimer[16]={"      :00:      "};                //定义第二行显示数组
uchar  idata  setlcdtimer[16]={"    00:01:00    "};
uchar timecount;
uchar temps;
bit timeflag;
bit sstimeflag;
sbit ring=P2^0;//蜂鸣闹铃
sbit e=P2^7;//LCD显示器E                               
sbit rw=P2^6;//LCD显示器RW
sbit rs=P2^5;//LCD显示器RS
sbit P10=P1^0; //测试用闪灯
sbit Key=P3^2;//秒表暂停,清零
sbit Key0=P3^3;//调时,设定闹钟时间,秒表选择
sbit Key1=P3^4;//调时,设定闹钟时间改变

uchar th1_f; //在中断中装载的T0的值高8位
uchar tl1_f; //在中断中装载的T0的值低8位
uint m=0;
uint n=0;
ulong i;
uint f=0,g=1;  
uint j,k;
uchar code freq[3][14]=
{
{0xF2,0x42,
0xF3,0xC1,
0xF5,0x17,
0xF5,0xB6,
0xF6,0xD0,
0xF7,0xD1,
0xF8,0xB6},
{0xF9,0x21,
0xF9,0xE0,
0xFA,0x8B,
0xFA,0xD7,
0xFB,0x68,
0xFB,0xE8,
0xFC,0x5B },
{0xFC,0x8D,
0xFC,0xEE,
0xFD,0x44,
0xFD,0x6D,
0xFD,0xB4,
0xFD,0xF4,
0xFE,0x2D},
};         //音乐频率表,低音,中音,高音,系统振荡频率11.0592MHz
uint code song1[]={26,25,23,25,31,26,25,26,23,25,26,25,23,22,21,16,25,23,22,22,23,23,23,26,23,22,21,25,23,22,21,16,21,15,26,25,23,25,31,26,25,26,23,25,26,25,23,22,21,16,25,23,22,22,23,23,23,26,23,22,21,25,23,22,21,16,21,15};
//编制音乐

//**************************************************
//软件延时函数(系统晶振为11.0592MHz),延时时间约为40μs
//入口条件:无符号整型变量del1,最终的延时时间为(del1*40)μs
//**************************************************
void delay(uint del1)
{
        uchar del2;
        for(;del1>0;del1--)
                for(del2=10;del2>0;del2--);
}
//**************************************************
//液晶显示器判忙函数
//**************************************************
void busy()
{
        uchar temp;
        temp=0x00;
        rs=0;
        rw=1;
        while((temp&0x80)==0x80)
        {
                P0=0xff;
                e=1;
                temp=P0;
                e=0;
        }
}
//**************************************************
//向液晶显示器写命令函数
//**************************************************
void WR_Com(uchar temp)
{
        busy();
        rs=0;
        rw=0;
        P0=temp;
        e=1;
        e=0;
}
//**************************************************
//向液晶显示器写数据函数
//**************************************************
void WR_Data(uchar num)
{
        busy();
        rs=1;
        rw=0;
        P0=num;
        e=1;
        e=0;
}
//**************************************************
//向液晶显示器写入显示数据函数
//入口条件:液晶显示器行首地址(指示第一行还是第二行)和待显示数组的首地址
//**************************************************
//void disp_lcdchar(uchar addr,uchar temp1)
//{
//    WR_Com(addr);
//        delay(100);
//        WR_Data(temp1);
//}
       
void disp_lcd(uchar addr,uchar *temp1)
{
        uchar i;
        WR_Com(addr);
        delay(100);
        for(i=0;i<16;i++)
        {
                WR_Data(temp1);
                delay(100);
        }
}       
//**************************************************
//液晶显示器初始化函数
//**************************************************
void lcd_ini()
{
        char i;
        for(i=3;i>0;i--)
        {
                P0=0x30;
                rs=0;
                rw=0;
                e=1;
                e=0;
                delay(100);
        }
        P0=0x38;
        rs=0;
        rw=0;
        e=1;
        e=0;
        delay(100);
}
//**************************************************
//液晶显示器复位函数
//**************************************************
void lcd_Reset()
{
        WR_Com(0x01);
        delay(100);
        WR_Com(0x06);
        delay(100);
        WR_Com(0x0c);
        delay(100);
}
//**************************************************
//外部中断函数,秒表暂停,清零
//**************************************************
void modess() interrupt 0 using 0  
{       
    delay(10000);                                                                                                       
        n++;
        if(n==3)
        n=0;
}
//**************************************************
//外部中断函数,模式选择
//**************************************************
void modepp() interrupt 2  using 1
{                                                                                                               
        delay(30000);
        m++;
        if(m==6)
        n=0;
        if(m==7)
        m=0;
}

//**************************************************
//定时/计数器中断函数,1S及0.01S
//**************************************************
void timer0() interrupt 1  using 2
{
        TH0=0xdc;
        TL0=0x23;
        sstimeflag=1;
        if(--timecount==0)
        {
                timecount=100;
                timeflag=1;
        }
}
//**************************************************
//定时/计数器中断函数,装入音乐频率计数初值
//**************************************************
void timer1() interrupt 3  using 3
{
  TL1=tl1_f;TH0=th1_f; //调入预定时值
  ring=!ring; //取反音乐输出IO
}                        
                                                                                                                                                                                                                  
//**************************************************
//主函数
//**************************************************
void main()
{
    P10=1;
        lcd_ini();
        lcd_Reset();
/*        for(i=0;i<10;i++)
        {                                                                                        
          temps=welcome;
          disp_lcdchar(0x80+1,temps); //LCD 单字符从左到右显示
          delay(10000);
         }*/
        disp_lcd(0x80,welcome);
    delay(10000);
        disp_lcd(0x80,lwelcome);
    delay(10000);
        disp_lcd(0x80,llwelcome);
    delay(10000);
        disp_lcd(0x80,lllwelcome);
        delay(10000);
        disp_lcd(0x80,llwelcome);
        delay(10000);
        disp_lcd(0x80,lwelcome);
        delay(10000);
        disp_lcd(0x80,welcome);        //LCD滚动显示
        delay(10000);
        disp_lcd(0xc0,lcdtimer);
        P10=0;
        TMOD=0x11;
        TH0=0xdc;
        TL0=0x23;
        TR0=1;
    IE=0x86;
        timeflag=0;         //1秒计时标志
        sstimeflag=0; //0.01秒计时标志
        timecount=100;
        while(1)
        {
         while(m==6)//秒表
         {
            IE=0x87;
            if(n==0) //秒表跑动
                {
             if(sstimeflag==1)
             {
              sstimeflag=0;
              sslcdtimer[11]+=1;
                  if(sslcdtimer[11]>=0x3a)
                  {
                     sslcdtimer[11]=0x30;
                            sslcdtimer[10]+=1;
                          if(sslcdtimer[10]>=0x3a)
                          {
                           sslcdtimer[10]=0x30;
                           sslcdtimer[8]+=1;
                             if(sslcdtimer[8]>=0x3a)
                             {
                               sslcdtimer[8]=0x30;
                                   sslcdtimer[7]+=1;
                                   if(sslcdtimer[7]>=0x36)
                                      {
                                          sslcdtimer[7]=0x30;
                                          }
                          }
               }
            }
                         disp_lcd(0xc0,sslcdtimer);
          }
                  if(n==1)//秒表暂停
                  {
                   disp_lcd(0xc0,sslcdtimer);
                  }
                  if(n>=2)//秒表清零
                 {
                   disp_lcd(0xc0,tsslcdtimer);
                   for(i=0;i<16;i++)
                   sslcdtimer=tsslcdtimer;
                 }
          }
   }
            while(m==0||m>=3) //时钟程序,只要不是调时,就一直运行
           {
              IE=0x86;
                    if(timeflag==1)
                  {
                        timeflag=0;
                        lcdtimer[11]+=1;
                        if(lcdtimer[11]>=0x3a)
                        {
                                lcdtimer[11]=0x30;
                                lcdtimer[10]+=1;
                                if(lcdtimer[10]>=0x36)
                                {
                                        lcdtimer[10]=0x30;
                                        lcdtimer[8]+=1;
                                        if(lcdtimer[8]>=0x3a)
                                        {
                                                lcdtimer[8]=0x30;
                                                lcdtimer[7]+=1;
                                                  if(lcdtimer[7]>=0x36)
                                                {
                                                        lcdtimer[7]=0x30;
                                                        lcdtimer[5]+=1;
                                                   if(lcdtimer[5]>=0x3a)
                                                      {
                                                       lcdtimer[5]=0x30;
                                                           lcdtimer[4]+=1;
                                                            if(lcdtimer[4]>=0x33&&lcdtimer[5]>=0x35)
                                                        {
                                                         lcdtimer[5]=0x30;
                                                         lcdtimer[4]=0x30;
                                }
                                                }
                                                  }
                                        }
                                }
                    }
           }
                                           if(m==0)
                                    {
                                                     disp_lcd(0xc0,lcdtimer);
                                                                          if(!Key1)//关掉闹钟
                                                                          {
                                                                            g=0;
                                                                                }
                                                                          if(lcdtimer[8]==setlcdtimer[8]&&lcdtimer[7]==setlcdtimer[7]&&lcdtimer[5]==setlcdtimer[5]&&lcdtimer[4]==setlcdtimer[4])
                                                                                     f=1;  //开启闹钟 ,播放音乐
                                                  if(f&&g)
                                                {
                                                            /*ring=1;
                                                            delay(10000);         
                                                                                            ring=0;
                                                                                             f=0; */
                                                        IE=0x8e;
                                                                                            j=song1/10-1;
                                                    k=2*(song1%10-1);
                                                th1_f=freq[j][k]; //取出对应的定时值送给T0
                                                tl1_f=freq[j][++k];
                                                TR1=1;
                                                                                                for(n=0;n<50000;n++); //音符间延时
                                                                                            i++;
                                                                                                TR1=0;
                                                                                                f=0;
                                                }
                                       }
        }
      while(m==1)          //调时分
        {
           if(!Key1)
           {
               delay(10000);
               timeflag=0;
               lcdtimer[8]+=1;
                          if(lcdtimer[8]>=0x3a)
                        {
                                lcdtimer[8]=0x30;
                                lcdtimer[7]+=1;
                                if(lcdtimer[7]>=0x36)
                                {
                                  lcdtimer[7]=0x30;
                                }
                        }
           }
                   disp_lcd(0xc0,lcdtimer);
                delay(8000);
                mlcdtimer[11]=lcdtimer[11];
                mlcdtimer[10]=lcdtimer[10];
                mlcdtimer[5]=lcdtimer[5];
                mlcdtimer[4]=lcdtimer[4];
                disp_lcd(0xc0,mlcdtimer);
    }
          while(m==2)  //调时时
         {
           if(!Key1)
           {
              delay(10000);
                  lcdtimer[5]+=1;
                   if(lcdtimer[5]>=0x3a)
                        {
                                lcdtimer[5]=0x30;
                                lcdtimer[4]+=1;       
                        }
                  if(lcdtimer[4]==0x32&&lcdtimer[5]>=0x34)
                           {
                                   lcdtimer[5]=0x30;
                                   lcdtimer[4]=0x30;                         
                           }
       }
                disp_lcd(0xc0,lcdtimer);
                delay(8000);
            hlcdtimer[11]=lcdtimer[11];
                hlcdtimer[10]=lcdtimer[10];
                hlcdtimer[8]=lcdtimer[8];
                hlcdtimer[7]=lcdtimer[7];
                disp_lcd(0xc0,hlcdtimer);
      }
                 while(m==3)//显示闹铃时间
         {
           if(!Key1)
           {
              delay(10000);                 
       }
            disp_lcd(0xc0,setlcdtimer);
      }
                      while(m==4) //调闹铃分
        {
           if(!Key1)   
           {
               delay(10000);
               setlcdtimer[8]+=1;
                          if(setlcdtimer[8]>=0x3a)
                        {
                                setlcdtimer[8]=0x30;
                                setlcdtimer[7]+=1;
                                if(setlcdtimer[7]>=0x36)
                                {
                                  setlcdtimer[7]=0x30;
                                }
                        }
           }
                   disp_lcd(0xc0,setlcdtimer);
                delay(8000);
                mlcdtimer[11]=setlcdtimer[11];
                mlcdtimer[10]=setlcdtimer[10];
                mlcdtimer[5]=setlcdtimer[5];
                mlcdtimer[4]=setlcdtimer[4];
                disp_lcd(0xc0,mlcdtimer);
    }
          while(m==5)//调闹铃时
         {
           if(!Key1)
           {
              delay(10000);
                  setlcdtimer[5]+=1;
                   if(setlcdtimer[5]>=0x3a)
                        {
                                setlcdtimer[5]=0x30;
                                setlcdtimer[4]+=1;       
                        }
                  if(setlcdtimer[4]==0x32&&setlcdtimer[5]>=0x34)
                           {
                                   setlcdtimer[5]=0x30;
                                   setlcdtimer[4]=0x30;                         
                           }
       }
                disp_lcd(0xc0,setlcdtimer);
                delay(8000);
            hlcdtimer[11]=setlcdtimer[11];
                hlcdtimer[10]=setlcdtimer[10];
                hlcdtimer[8]=setlcdtimer[8];
                hlcdtimer[7]=setlcdtimer[7];
                disp_lcd(0xc0,hlcdtimer);
      }
  }

软件仿真不是万能,像你这个问题,只能自己去找,别人还真难帮到你的。
出现这样的问题,就要一个个排查,先从你的LCD函数看有没问题,看能不能有显示的时候再去加入你的闹钟之类的东西吧,个人感觉比较大的可能性是你的LCD的时序还不对。软件仿真时的时序跟硬件上的时序还是有小差别的,对照着规格书上的时序去排查吧

一般是硬件问题 最好结合硬件原理图的方式进行查错

仿真和实际电路有时候是有区别的,不能完全依赖仿真判断设计是否正确;
你这个问题我判断是由于时序不能满足1602造成的,你每次在对R/W、E、RS操作后加一条或两条空操作,应该能解决问题。

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

网站地图

Top