protues仿真lcd1602不显示
#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显示代码有问题,可以先去掉中断以便查找