电子密码锁仿真lcd1602不显示

protues仿真lcd1602不显示

img


以下是程序

#include
#include
#include "stdio.h"
#include "string.h"
#define uchar unsigned char
#define uint unsigned int
    
sbit LCM_RW=P2^5; //定义LCD引脚
sbit LCM_RS=P2^6;
sbit LCM_E=P2^7;
#define LCM_Data P0
#define Busy 0x80 //用于检测LCM状态字中的Busy标识

sbit K1=P1^0;    //按键定义
sbit K2=P1^1;
sbit K3=P1^2;
sbit K4=P1^3;
sbit K5=P1^4;
sbit K6=P1^5;
sbit K7=P1^6;
sbit K8=P1^7;

sbit red=P2^0;
sbit green=P2^1;
sbit beep=P2^2;


void LCMInit(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);
unsigned char ReadDataLCM(void);
unsigned char ReadStatusLCM(void);
void Delay5Ms(void);
void keyscan();
void xianshi();
void keyscan1();
void xianshi1();
void T0_init();
uchar jiance_geshi(uchar *a);

unsigned char code shuru[] ={"shuru:"};
unsigned char code right[] =  {"right"};
unsigned char code error[] =  {"error"};

unsigned char code fail[] =  {" fail "};
unsigned char code kongbai[] ={"               "};
unsigned char code g1[] =  "------";
uchar mima_chushi[6]="111111";
uchar mima[6]="";
uchar mima_xiu[6]="";

//变量的定义
uchar mima_num;
uchar flag_num,flag_correct,flag_xiugai,flag_error,flag_xiu1,flag_xiu2,flag_quxiao;

//5ms延时
void Delay5Ms(void)
{
    unsigned int TempCyc = 5552;
    while(TempCyc--);
}

void delay(unsigned int i)
{
    unsigned int j;
    unsigned char k;
    for(j=i;j>0;j--)
        for(k=125;k>0;k--);
}

//写数据
void WriteDataLCM(unsigned char WDLCM) 
{
    ReadStatusLCM(); //检测忙
    LCM_Data = WDLCM;
    LCM_RS = 1;
    LCM_RW = 0;
    LCM_E = 0; //若晶振速度太高可以在这后加小的延时
    LCM_E = 0; //延时
    LCM_E = 1;
}

//写指令
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
    if (BuysC) ReadStatusLCM(); //根据需要检测忙
    LCM_Data = WCLCM;
    LCM_RS = 0;
    LCM_RW = 0;    
    LCM_E = 0;
    LCM_E = 0;
    LCM_E = 1;    
}

//读数据
unsigned char ReadDataLCM(void)
{
    LCM_RS = 1; 
    LCM_RW = 1;
    LCM_E = 0;
    LCM_E = 0;
    LCM_E = 1;
    return(LCM_Data);
}

//读状态
unsigned char ReadStatusLCM(void)
{
    LCM_Data = 0xFF; 
    LCM_RS = 0;
    LCM_RW = 1;
    LCM_E = 0;
    LCM_E = 0;
    LCM_E = 1;
    while (LCM_Data & Busy); //检测忙信号
    return(LCM_Data);
}

void LCMInit(void) //LCM初始化
{
    LCM_Data = 0;
    WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
    Delay5Ms(); 
    WriteCommandLCM(0x38,0);
    Delay5Ms(); 
    WriteCommandLCM(0x38,0);
    Delay5Ms(); 

    WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
    WriteCommandLCM(0x08,1); //关闭显示
    WriteCommandLCM(0x01,1); //显示清屏
    WriteCommandLCM(0x06,1); // 显示光标移动设置
    WriteCommandLCM(0x0C,1); // 显示开及光标设置
}

//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData) //Y 为1 则是第二行
{
    Y &= 0x1;
    X &= 0xF; //限制X不能大于15,Y不能大于1
    if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
    X |= 0x80; //算出指令码
    WriteCommandLCM(X, 1); //发命令字
    WriteDataLCM(DData); //发数据
}

//按指定位置显示一串字符
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
    unsigned char ListLength;

  ListLength = 0;
    Y &= 0x1;
    X &= 0xF; //限制X不能大于15,Y不能大于1
    while (DData[ListLength]>0x19) //若到达字串尾则退出
        {
            if (X <= 0xF) //X坐标应小于0xF
                {
                    DisplayOneChar(X, Y, DData[ListLength]); //显示单个字符
                    ListLength++;
                    X++;
                }
        }
}

void qing_shuzu(uchar *a)
{
    uchar i,length;
    length=strlen(a);
    for(i=0;i0;
}

/*中断服务特殊功能寄存器配置*/    
void T0_init()
{
    
    TMOD = 0x01;  //定时器16为计数工作模式
    TH0 =0x4b;
    TL0 =0xfd; //50ms
    ET0 = 1; //开定时器0中断
    TR0 = 0;//启动定时器0
    EA = 1;    //开总中断
}

void keyscan()
{
    if(K1==0)
    {
        delay(10);//延时10ms消除按键抖动
        if(K1==0)
        {
            while(!K1);//若k1键确实按下,则等待k1释放
            mima[mima_num]='1';
            mima_num++;
            delay(5);
            
        }
    }
    if(K2==0)
    {
        delay(10);//延时10ms消除按键抖动 
        if(K2==0)
        {
            while(!K2);//若k2键确实按下,则等待k2释放
            mima[mima_num]='2';
            mima_num++;
            delay(5);
        }    
    }
        if(K3==0)
    {
        delay(10);//延时10ms消除按键抖动
        if(K3==0)
        {
            while(!K3);//若k3键确实按下,则等待k3释放
            mima[mima_num]='3';
            mima_num++;
            delay(5);
        }
    }
        if(K4==0)
    {
        delay(10);//延时10ms消除按键抖动
        if(K4==0)
        {
            while(!K4);//若k4键确实按下,则等待k4释放
            mima[mima_num]='4';
            mima_num++;
            delay(5);    
        }
    }
    
        if(K5==0)  //删除键
    {
        delay(10);  //软件消抖
        if(K5==0)
        {
            mima_num--;
            while(!K5); //松手检测
        }
    }
}    
void xianshi()
{    
    uchar i;
    for(i=0;i6,0,'*');
    }
    for(i=mima_num;i<6;i++)
    {
        DisplayOneChar(i+6,0,'-');
    }
}
    
/********************功能键扫描 显示*******************************/

void keyscan1()
{
        if(K8==0)  //取消登陆 键
    {
        delay(5);  //软件消抖
        if(K8==0)
        {
            flag_correct=0;  //跳出登陆  
            while(!K8); //松手检测
        }
    }
    
        if(K6==0)   //修改密码
    {
        delay(5);  //软件消抖
        if(K6==0)
        {
            DisplayListChar(0, 1, " first :");     
            DisplayListChar(9, 1, g1);  //显示----
            flag_xiugai=1;
            while(!K6); //松手检测
        }
    }
    
        if(K7==0)   //取消 修改密码
    {
        delay(5);  //软件消抖
        if(K7==0)
        {
            flag_xiugai=0;
            mima_num=0;
            flag_quxiao=1;
            while(!K7); //松手检测
        }
    }    
}

void xianshi1()
{
    uchar i;
    for(i=0;i9,1,'*');
    }
    for(i=mima_num;i<6;i++)
    {
        DisplayOneChar(i+9,1,'-');
    }
}

void luoji_xianshi()
{
    //static uchar fa=0;
    if(mima_num==0 && flag_num!=3 )  
    {
        DisplayListChar(6, 0, g1);  //显示----
        //fa=1;
    }
    /*if(mima_num==1 && flag_num!=3)  
    {
        DisplayListChar(0, 1, kongbai); //清掉错误信息
    }*/
    if(flag_num==3)
    {
        DisplayListChar(0, 1, fail);   //禁止登陆
        while(1);     //程序卡死
    }
}

uchar jiance_geshi(uchar *a)   //0 表示检查 不通过
{
    uchar i,length,flag;
    flag=0;
    length=strlen(a);
    for(i=1;iif(*(a+i)==(*a))
            flag++;
        }
    if(flag>4)
    {
        return 0;
    }
    else return 1;
    
}
void main()
{
    mima_num=0;
    flag_xiu2=0;
    beep=0;
    T0_init();
    LCMInit();
    DisplayListChar(0, 0, shuru);
    DisplayListChar(6, 0, g1);
    while(1)
    {
        if(flag_xiu2==1)  //
        {
            WriteCommandLCM(0x01,1); //显示清屏
            DisplayListChar(0, 0, shuru);
            DisplayListChar(6, 0, g1);
            flag_xiu2=0;
        }
        keyscan();
        xianshi();
        if(mima_num==6)  //6位输完 开始检测
        {
            if(strcmp(mima,mima_chushi)==1)       //strcmp 
            {
                DisplayListChar(0, 1, error);//错误   strcmp为1 因为mima_chushi 在code区
                red=0;
                beep=1;
                flag_num++;   //错误次数
                mima_num=0;
                TR0=1;
            }        
            else 
            {
                green=0;
                TR0=1;    //开启定时器
                mima_num=0;
                flag_correct=1;
            } 
        }
        luoji_xianshi();
        if(flag_correct) 
        {WriteCommandLCM(0x01,1); //显示清屏
            DisplayListChar(0, 0, right);}
        else DisplayListChar(0, 0, shuru);
        while(flag_correct)  //进入登陆装填
        {
            if(flag_xiu2==0){
            keyscan1();
                if(flag_quxiao) //修改密码取消按键
                {
                    DisplayListChar(0,1,kongbai);
                    flag_quxiao=0;
                }
            if(flag_xiugai==1)
            {
                keyscan();
                xianshi1();
                if(mima_num==6)
                {
                    if(!jiance_geshi(mima))  //检测密码是否符合格式 1表示符合
                    {
                        DisplayListChar(9, 0, error);  //0 不符合 才显示错误
                        flag_xiugai=0;
                        qing_shuzu();
                    }
                    else 
                    {
                        DisplayListChar(0, 1, " second:" );
                        strcpy(mima_xiu,mima);  //符合进入下一步
                        flag_xiu1=1;
                        mima_num=0; //为下一次保存密码准备
                        while(flag_xiu1)
                        {
                            keyscan();
                            xianshi1();
                            if(mima_num==6)
                            {
                                if(strcmp(mima,mima_xiu)==0)       //strcmp 比较这两次密码是否一致
                                {
                                    
                                    strcpy(mima_chushi,mima);
                                    flag_xiu1=0;
                                    delay(1000);
                                    mima_num=0;
                                    flag_xiugai=0;
                                    flag_xiu2=1;
                                }
                                else 
                                {
                                    DisplayListChar(6, 0, "mistake    ");
                                    flag_xiu1=0;
                                    mima_num=0;
                                    flag_xiugai=0;
                                }
                            }
                      }
                    }
                }
            }
        }
//            if(flag_xiu2==1)
//            {
//                keyscan1();
//                WriteCommandLCM(0x01,1); //显示清屏d
//                while(1);
//            }
    }
    }    
}


/*中断服务程序*/
void timer0() interrupt 1
{
    uchar count;
    TH0 =0x4b;
    TL0 =0xfd; //50ms
    count++;
    if (count == 20)  //1S
    {
        count=0;
        red=1;
        beep=0;
        green=1;
        TR0=0;
    }
}

大概思路:

1、检查硬件是否短路/短路,用数字万用表的红黑表笔分别点到LCD1602的电源和地引脚,也就是如图所示的VCC和GND引脚。
2、上电测量供电电压是否正常,上电后用数字万用表红黑表笔分别点到LCD1602的VCC和GND两个引脚,观察数字万用表的读数是否为5V(常用5V电压供电)
3、检查单片机最小系统是否正常工作,用示波器测量单片机的晶振电路是否起振,单片机、晶振等元件是否焊接良好。
4、检查LCD1602连接的排线是否有断开的线或者接触不良的接口,也有可能是排线损坏引起的原因,用数字万用表的导通测量档位测量排线以及接线是否正常导通.
5、以上硬件都检查正常没有问题的就检查下驱动程序,检查驱动程序是否正确

先点个灯看看单片机程序到底有没有跑起来,
然后单独测试LCD,避开其它代码的干扰

你这个目前程这个程序太长,建议先删掉与中断和按键有关的程序,看到主函数初始化时有LCD的显示,如果初始化没有观察到LCD显示,则有可能是中断或者或者LCD显示代码有问题,可以先去掉中断以便查找