请问我在Proteus中LCD1602不能显示DS1302中的数据是什么原因?是程序出现错误了吗?要怎么改?

Shaquila_Chau 2018-06-09 08:47:57

//------------------------------------
//主函数
//功能:DS1302+LCD1602实时时钟显示
//能显示时间、日历,具有按键调整功能
//------------------------------------
#include "reg52.h"
#include "LCD1602.h"
#include "DS1302.h"
unsigned char time_add[7];
void LcdDisplay();
void keyscan();
sbit add_y=P1^6; //调整年按键
sbit add_w=P1^5; //调整星期按键
sbit add_m=P1^4; //调整月按键
sbit add_d=P1^3; //调整日按键
sbit add_hour=P1^2; //调整小时按键
sbit add_min=P1^1; //调整分按键
sbit add_sec=P1^0; //调整秒按键


//--------------------------------------
//函数名:main
//函数功能:主函数
//--------------------------------------
void main()
{
LcdInit();
Ds1302Init();
while(1)
{
Ds1302ReadTime();
LcdDisplay();
keyscan();
}
}
//---------------------------------------
//函数名:keyscan()
//函数功能:时间、日历按键调整显示函数
//---------------------------------------
void keyscan()
{
Ds1302Write(0x8E,0x00);
if(add_sec==0)
{
time_add[0]=(TIME[0]>>4)*10+(TIME[0]&0x0F);
time_add[0]=(time_add[0]+1)%60;
TIME[0]=(time_add[0]/10<<4)|(time_add[0]%10);
Ds1302Write(WRITE_RTC_ADDR[0],TIME[0]);
}
if(add_min==0)
{
time_add[1]=(TIME[1]>>4)*10+(TIME[1]&0x0f);
time_add[1]=(time_add[1]+1)%60;
TIME[1]=(time_add[1]/10<<4)|(time_add[1]%10);
Ds1302Write(WRITE_RTC_ADDR[1],TIME[1]);
}
if(add_hour==0)
{
time_add[2]=(TIME[2]>>4)*10+(TIME[2]&0x0f);
time_add[2]=(time_add[2]+1)%24;
TIME[2]=(time_add[2]/10<<4)|(time_add[2]%10);
Ds1302Write(WRITE_RTC_ADDR[2],TIME[2]);
}
if(add_d==0)
{
time_add[3]=(TIME[3]>>4)*10+(TIME[3]&0x0f);
time_add[3]=(time_add[3]+1)%32;
TIME[3]=(time_add[3]/10<<4)|(time_add[3]%10);
Ds1302Write(WRITE_RTC_ADDR[3],TIME[3]);
}
if(add_m==0)
{
time_add[4]=(TIME[4]>>4)*10+(TIME[4]&0x0f);
time_add[4]=(time_add[4]+1)%13;
TIME[4]=(time_add[4]/10<<4)|(time_add[4]%10);
Ds1302Write(WRITE_RTC_ADDR[4],TIME[4]);
}
if(add_w==0)
{
time_add[5]=(TIME[5]>>4)*10+(TIME[5]&0x0f);
time_add[5]=(time_add[5]+1)%7;
TIME[5]=(time_add[5]/10<<4)|(time_add[5]%10);
Ds1302Write(WRITE_RTC_ADDR[5],TIME[5]);
}
if(add_y==0)
{
time_add[6]=(TIME[6]>>4)*10+(TIME[6]&0x0f);
time_add[6]=(time_add[6]+1)%100;
TIME[6]=(time_add[6]/10<<4)|(time_add[6]%10);
Ds1302Write(WRITE_RTC_ADDR[6],TIME[6]);
}
}
//-------------------------------------------------------
//函数名:LcdDisplay()
//函数功能:显示函数
//-------------------------------------------------------
void LcdDisplay()
{
LcdWriteCom(0x80+0x40);
LcdWriteData('T');
LcdWriteData(':');
LcdWriteData('0'+TIME[2]/16);
LcdWriteData('0'+(TIME[2]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[1]/16);
LcdWriteData('0'+(TIME[1]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[0]/16);
LcdWriteData('0'+(TIME[0]&0x0f));
LcdWriteCom(0x80);
LcdWriteData('D');
LcdWriteData(':');
LcdWriteData('2');
LcdWriteData('0');
LcdWriteData('0'+TIME[6]/16);
LcdWriteData('0'+(TIME[6]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[4]/16);
LcdWriteData('0'+(TIME[4]&0x0f));
LcdWriteData('-');
LcdWriteData('0'+TIME[3]/16);
LcdWriteData('0'+(TIME[3]&0x0f));
LcdWriteCom(0x8D);
LcdWriteData('0'+(TIME[5]&0x07));
}






头文件DS1302
	#ifndef  _DS1302_H_
#define _DS1302_H_
#include "reg52.h"
#include "intrins.h"
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif

sbit DSIO=P2^5;
sbit RST=P2^6;
sbit SCLK=P2^7;
void Ds1302Write(uchar addr,uchar dat);
uchar Ds1302Read(uchar addr);
void Ds1302Init();
void Ds1302ReadTime();
extern uchar TIME[7];
uchar code READ_RTC_ADDR[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
uchar code WRITE_RTC_ADDR[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
uchar TIME[7]={0x00,0x00,0x19,0x05,0x06,0x02,0x18}; //DS1302时钟初始化2018年6月3日星期二12点00分00秒;储存顺序是秒分是日月周年,储存格式为BCD码
//---------------------------------//
//函数名:Ds1302Write
//函数功能:向DS1302写命令
//---------------------------------//
void Ds1302Write(uchar addr,uchar dat)
{
uchar n;
RST=0;

_nop_();
SCLK=0;

_nop_();
RST=1;

_nop_();

for(n=0; n<8; n++)
{
DSIO=addr & 0x01;

addr >>=1;
SCLK=1;

_nop_();
SCLK=0;

_nop_();
}

for(n=0;n<8;n++)
{
DSIO=dat & 0x01;
dat >>=1;
SCLK=1;
_nop_();
SCLK=0;
_nop_();
}

RST=0; //传输数据结束
_nop_();

}
//----------------------------//
//函数名:Ds1302Read
//函数功能:读取一个地址的数据
//----------------------------//
uchar Ds1302Read(uchar addr)
{
uchar n,dat,dat1;
RST=0;
_nop_();
SCLK=0;
_nop_();
RST=1;
_nop_();

for(n=0;n<8;n++)
{
DSIO=addr & 0x01;
addr >>=1;
SCLK=1;
_nop_();
SCLK=0;
_nop_();
}
_nop_();

for(n=0;n<8;n++)
{
dat1=DSIO;
dat=(dat >>1)|(dat<<7);
SCLK=1;
_nop_();
SCLK=0;
_nop_();
}

RST=0;
_nop_();
SCLK=1;
_nop_();
DSIO=0;
_nop_();
DSIO=1;
_nop_();
return dat;
}
//--------------------------------
//函数名:Ds1302Init
//函数功能:初始化DS1302
//--------------------------------
void Ds1302Init()
{
uchar n;
Ds1302Write(0x8E,0X00);
for(n=0; n<7; n++)
{
Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);
}
Ds1302Write(0x8E,0x80);
}
//--------------------------------
//函数名:Ds1302ReadTime
//函数功能:读取时钟信息
//--------------------------------
void Ds1302ReadTime()
{
uchar n;
for(n=0;n<7;n++)
{
TIME[n]=Ds1302Read(READ_RTC_ADDR[n]);
}
}
#endif












头文件LCD1602
	#ifndef  _LCD1602_H_
#define _LCD1602_H_
#include "reg52.h"
#ifndef uchar
#define uchar unsigned char
#endif
#ifndef uint
#define uint unsigned int
#endif

#define LCD1602_DATAPINS P0
sbit LCD1602_E=P2^2;
sbit LCD1602_RW=P2^1;
sbit LCD1602_RS=P2^0;
void Lcd1602_Delay1ms(uint c);
void LcdWriteCom(uchar com);
void LcdWriteData(uchar dat);
void LcdInit();
//---------------------------------------------
//函数名:Lcd1602_Delay1ms
//函数功能;延时函数,延时1ms
//说明:该函数是在12MHZ晶振下,12分频单片机延时
//---------------------------------------------
void Lcd1602_Delay1ms(uint c)
{
uchar a,b;
for(;c>0;c--)
{
for(b=199;b>0;b--)
{
for(a=1;a>0;a--);
}
}
}
//----------------------------------------------
//函数名:LcdWriteCom
//函数功能:向LCD写入一个字节的命令
//----------------------------------------------
void LcdWriteCom(uchar com)
{
LCD1602_E=0;
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_DATAPINS=com;
Lcd1602_Delay1ms(1);
LCD1602_E=1;
Lcd1602_Delay1ms(5);
LCD1602_E=0;
}
//------------------------------------------------
// 函数名:LcdWriteData
//函数功能:向LCD写入一个字节的数据
//输入:dat
//------------------------------------------------
void LcdWriteData(uchar dat)
{
LCD1602_E=0;
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_DATAPINS=dat;
Lcd1602_Delay1ms(1);
LCD1602_E=1;
Lcd1602_Delay1ms(5);
LCD1602_E=0;

}
//-------------------------------------------------
//函数名:LcdInit()
//函数功能:初始化LCD屏
//-------------------------------------------------
void LcdInit()
{
LcdWriteCom(0x38);
LcdWriteCom(0x0c);
LcdWriteCom(0x06);
LcdWriteCom(0x01);
LcdWriteCom(0x80);
}
#endif


...全文
1154 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
tianxj001 2018-06-10
  • 打赏
  • 举报
回复
你这样写,容易出错,还是换成这样比较好,代码一样简练 dat>>=1; dat|=DSIO<<7; 因为这里dat本身移位和后面端口数据与操作,有严格的顺序要求,这样情况,建议分开写。写在一起,一不小心编译器实际上的操作顺序错误了,这种隐性错误查起来繁复。
tianxj001 2018-06-10
  • 打赏
  • 举报
回复
引用 楼主 weixin_42424504 的回复:
[code=for(n=0;n<8;n++) { dat1=DSIO; dat=(dat >>1)|(dat<<7); SCLK=1; _nop_(); SCLK=0; _nop_(); } [/code]
很明显,LCD显示函数是正确的,读1302错误,给你看了看,这里明显错误。
tianxj001 2018-06-10
  • 打赏
  • 举报
回复
引用 3 楼 weixin_42424504 的回复:
[quote=引用 2 楼 tianxj001 的回复:] 你这样写,容易出错,还是换成这样比较好,代码一样简练 dat>>=1; dat|=DSIO<<7; 因为这里dat本身移位和后面端口数据与操作,有严格的顺序要求,这样情况,建议分开写。写在一起,一不小心编译器实际上的操作顺序错误了,这种隐性错误查起来繁复。
你好我已经按照你说的改了程序但是LCD现在出现了如下错误[/quote] 好好去检查DS1302内部寄存器地址和程序关系,看起来,你读的数据错位了。
Shaquila_Chau 2018-06-10
  • 打赏
  • 举报
回复
引用 2 楼 tianxj001 的回复:
你这样写,容易出错,还是换成这样比较好,代码一样简练 dat>>=1; dat|=DSIO<<7; 因为这里dat本身移位和后面端口数据与操作,有严格的顺序要求,这样情况,建议分开写。写在一起,一不小心编译器实际上的操作顺序错误了,这种隐性错误查起来繁复。
你好我已经按照你说的改了程序但是LCD现在出现了如下错误

27,373

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧