以下是我用DS1302和LCD1602组合写的一个万年历程序,可是有些地方出现乱码,我怀疑是初始化还有从DS1302读取数据时候出错,可是看了好久,又感觉不会错。这个问题想了好久。
#include <reg51.h>
#include <intrins.h>
#define LCD1602_DB P0
//一些待用数据的定义
unsigned char LCD1602_digital[]={"0123456789"};
unsigned char time[7]={0};//年周月日时分秒
unsigned char WriteDS1302_address[]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};
unsigned char ReadDS1302_address[]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};
//ds1302端口的设置
sbit DS1302_IO=P3^5;
sbit DS1302_RST=P3^6;
sbit DS1302_CK=P3^4;
//LCD1602接口的设置
sbit LCD1602_RS=P2^2;
sbit LCD1602_RW=P2^1;
sbit LCD1602_E=P2^0;
sbit BF=P0^7;
//--------------------------以下是关于LCD1602所需要的自定义函数--------------------------
//定义延时函数
void delay(unsigned char time)
{
unsigned char t=2;
while(time--)
{
while(t--);
}
}
//定义检测LCD1602是否处于空闲状态函数
bit LCD1602_busytest(void)
{
bit result;
LCD1602_RS=0;
LCD1602_RW=1;
LCD1602_E=1;
_nop_();
_nop_();
_nop_();
result=BF;
LCD1602_E=0;
return result;
}
//定义LCD1602写指令函数
void Write1602_command(unsigned char command)
{
LCD1602_DB=command;
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_E=1;
LCD1602_E=0;
delay(1);
}
//定义LCD1602写数据函数
void Write1602_dat(unsigned char dat)
{
while(LCD1602_busytest()==1);
LCD1602_DB=dat;
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_E=1;
LCD1602_E=0;
delay(1);
}
//定义LCD1602显示函数
void LCD1602_display_char(unsigned char x,unsigned char y,unsigned char dat)
{
unsigned char address;
switch(y)
{
case 1: address=0x80+x; break;
case 2: address=0xc0+x; break;
}
Write1602_command(address);
_nop_();
Write1602_dat(dat);
_nop_();
}
//定义 LCD1602初始化函数
void LCD1602_init()
{
Write1602_command(0x38);delay(2);
Write1602_command(0x38);delay(2);
Write1602_command(0x0c);delay(2);
Write1602_command(0x06);delay(2);
Write1602_command(0x01);delay(2);
}
//--------------------------以上是LCD1602所需要的自定义函数--------------------------
//--------------------------以下是DS1302所需要的自定义函数--------------------------
//自定义写DS1302函数
void Write1302(unsigned char dat)
{
unsigned char i;
DS1302_CK=0;
delay(2);
for(i=0;i<8;i++)
{
DS1302_IO=dat&0x01;
delay(2);
DS1302_CK=1;
delay(2);
DS1302_CK=0;
dat>>=1;
}
}
//自定义写DS1302设定
void Write1302set(unsigned char command,unsigned char dat)
{
DS1302_RST=0;
DS1302_CK=0;
DS1302_RST=1;
delay(2);
Write1302(command);
Write1302(dat);
DS1302_CK=1;
DS1302_RST=0;
}
//自定义读DS1302函数
unsigned char Read1302(void)
{
unsigned char i,dat;
delay(2);
for(i=0;i<8;i++)
{
dat>>=1;
if(DS1302_IO==1)
dat|=0x80;
DS1302_CK=1;
delay(2);
DS1302_CK=0;
delay(2);
}
return dat;
}
//自定义DS1302数据函数
unsigned char Read1302set(unsigned char command)
{
unsigned char dat;
DS1302_RST=0;
DS1302_CK=0;
DS1302_RST=1;
Write1302(command);
dat=Read1302();
DS1302_CK=1;
DS1302_RST=0;
return dat;
}
//自定义DS1302初始化函数
void DS1302_init(void)
{
Write1302set(0x8e,0x00); //去保护,改写数据
Write1302set(0x80,0x49); //秒
Write1302set(0x82,0x54); //分
Write1302set(0x84,0x17); //时
Write1302set(0x86,0x27); //日
Write1302set(0x88,0x08); //月
Write1302set(0x8a,0x07);//周
Write1302set(0x8c,0x13); //年
Write1302set(0x8e,0x80);//加保护,防止数据出错
}
//--------------------------以上是DS1302所需的的自定义函数--------------------------
//------------------------以下是自定义10进制数与BCD码相互转换函数-------------------
//自定义10进制数转BCD码
unsigned char TentoBCD(unsigned char Ten)
{
unsigned char BCD;
BCD=Ten%10+Ten/10*16;return BCD;}
//自定义BCD码进制转10进制数
unsigned char BCDtoTen(unsigned char BCD)
{
unsigned char Ten,i,j;
i=BCD%16;
j=BCD/16*10;
Ten=i+j;
return Ten;
}
//------------------------以上是自定义10进制与BCD码相互转换函数---------------------
//以下是主函数
void main(void)
{
unsigned char i;
unsigned char temp[7];
LCD1602_init();DS1302_init();
while(1)
{
for(i=0;i<7;i++)
{
temp[i]=BCDtoTen(Read1302set(ReadDS1302_address[i]));
_nop_();
}
LCD1602_display_char(0,1,LCD1602_digital[(temp[0]/10)]);
LCD1602_display_char(1,1,LCD1602_digital[(temp[0]%10)]);
LCD1602_display_char(2,1,'-');
LCD1602_display_char(3,1,LCD1602_digital[(temp[2]/10)]);
LCD1602_display_char(4,1,LCD1602_digital[(temp[2]%10)]);
LCD1602_display_char(5,1,'-');
LCD1602_display_char(6,1,LCD1602_digital[(temp[3]/10)]);
LCD1602_display_char(7,1,LCD1602_digital[(temp[3]%10)]);
LCD1602_display_char(14,1,LCD1602_digital[(temp[1]/10)]);
LCD1602_display_char(15,1,LCD1602_digital[(temp[1]%10)]);
LCD1602_display_char(4,2,LCD1602_digital[(temp[4]/10)]);
LCD1602_display_char(5,2,LCD1602_digital[(temp[4]%10)]);
LCD1602_display_char(6,2,':');
LCD1602_display_char(7,2,LCD1602_digital[(temp[5]/10)]);
LCD1602_display_char(8,2,LCD1602_digital[(temp[5]%10)]);
LCD1602_display_char(9,2,':');
LCD1602_display_char(10,2,LCD1602_digital[(temp[6]/10)]);
LCD1602_display_char(11,2,LCD1602_digital[(temp[6]%10)]);
}
}
//以上是主函数
------努力だ、勉强だ、それは天才だ。
谁よりも三倍、四倍、五倍勉强する者、それが天才だ。

#include <reg51.h>
#include <intrins.h>
#define LCD1602_DB P0
//一些待用数据的定义
unsigned char LCD1602_digital[]={"0123456789"};
unsigned char time[7]={0};//年周月日时分秒
unsigned char WriteDS1302_address[]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};
unsigned char ReadDS1302_address[]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};
//ds1302端口的设置
sbit DS1302_IO=P3^5;
sbit DS1302_RST=P3^6;
sbit DS1302_CK=P3^4;
//LCD1602接口的设置
sbit LCD1602_RS=P2^2;
sbit LCD1602_RW=P2^1;
sbit LCD1602_E=P2^0;
sbit BF=P0^7;
//--------------------------以下是关于LCD1602所需要的自定义函数--------------------------
//定义延时函数
void delay(unsigned char time)
{
unsigned char t=2;
while(time--)
{
while(t--);
}
}
//定义检测LCD1602是否处于空闲状态函数
bit LCD1602_busytest(void)
{
bit result;
LCD1602_RS=0;
LCD1602_RW=1;
LCD1602_E=1;
_nop_();
_nop_();
_nop_();
result=BF;
LCD1602_E=0;
return result;
}
//定义LCD1602写指令函数
void Write1602_command(unsigned char command)
{
LCD1602_DB=command;
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_E=1;
LCD1602_E=0;
delay(1);
}
//定义LCD1602写数据函数
void Write1602_dat(unsigned char dat)
{
while(LCD1602_busytest()==1);
LCD1602_DB=dat;
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_E=1;
LCD1602_E=0;
delay(1);
}
//定义LCD1602显示函数
void LCD1602_display_char(unsigned char x,unsigned char y,unsigned char dat)
{
unsigned char address;
switch(y)
{
case 1: address=0x80+x; break;
case 2: address=0xc0+x; break;
}
Write1602_command(address);
_nop_();
Write1602_dat(dat);
_nop_();
}
//定义 LCD1602初始化函数
void LCD1602_init()
{
Write1602_command(0x38);delay(2);
Write1602_command(0x38);delay(2);
Write1602_command(0x0c);delay(2);
Write1602_command(0x06);delay(2);
Write1602_command(0x01);delay(2);
}
//--------------------------以上是LCD1602所需要的自定义函数--------------------------
//--------------------------以下是DS1302所需要的自定义函数--------------------------
//自定义写DS1302函数
void Write1302(unsigned char dat)
{
unsigned char i;
DS1302_CK=0;
delay(2);
for(i=0;i<8;i++)
{
DS1302_IO=dat&0x01;
delay(2);
DS1302_CK=1;
delay(2);
DS1302_CK=0;
dat>>=1;
}
}
//自定义写DS1302设定
void Write1302set(unsigned char command,unsigned char dat)
{
DS1302_RST=0;
DS1302_CK=0;
DS1302_RST=1;
delay(2);
Write1302(command);
Write1302(dat);
DS1302_CK=1;
DS1302_RST=0;
}
//自定义读DS1302函数
unsigned char Read1302(void)
{
unsigned char i,dat;
delay(2);
for(i=0;i<8;i++)
{
dat>>=1;
if(DS1302_IO==1)
dat|=0x80;
DS1302_CK=1;
delay(2);
DS1302_CK=0;
delay(2);
}
return dat;
}
//自定义DS1302数据函数
unsigned char Read1302set(unsigned char command)
{
unsigned char dat;
DS1302_RST=0;
DS1302_CK=0;
DS1302_RST=1;
Write1302(command);
dat=Read1302();
DS1302_CK=1;
DS1302_RST=0;
return dat;
}
//自定义DS1302初始化函数
void DS1302_init(void)
{
Write1302set(0x8e,0x00); //去保护,改写数据
Write1302set(0x80,0x49); //秒
Write1302set(0x82,0x54); //分
Write1302set(0x84,0x17); //时
Write1302set(0x86,0x27); //日
Write1302set(0x88,0x08); //月
Write1302set(0x8a,0x07);//周
Write1302set(0x8c,0x13); //年
Write1302set(0x8e,0x80);//加保护,防止数据出错
}
//--------------------------以上是DS1302所需的的自定义函数--------------------------
//------------------------以下是自定义10进制数与BCD码相互转换函数-------------------
//自定义10进制数转BCD码
unsigned char TentoBCD(unsigned char Ten)
{
unsigned char BCD;
BCD=Ten%10+Ten/10*16;return BCD;}
//自定义BCD码进制转10进制数
unsigned char BCDtoTen(unsigned char BCD)
{
unsigned char Ten,i,j;
i=BCD%16;
j=BCD/16*10;
Ten=i+j;
return Ten;
}
//------------------------以上是自定义10进制与BCD码相互转换函数---------------------
//以下是主函数
void main(void)
{
unsigned char i;
unsigned char temp[7];
LCD1602_init();DS1302_init();
while(1)
{
for(i=0;i<7;i++)
{
temp[i]=BCDtoTen(Read1302set(ReadDS1302_address[i]));
_nop_();
}
LCD1602_display_char(0,1,LCD1602_digital[(temp[0]/10)]);
LCD1602_display_char(1,1,LCD1602_digital[(temp[0]%10)]);
LCD1602_display_char(2,1,'-');
LCD1602_display_char(3,1,LCD1602_digital[(temp[2]/10)]);
LCD1602_display_char(4,1,LCD1602_digital[(temp[2]%10)]);
LCD1602_display_char(5,1,'-');
LCD1602_display_char(6,1,LCD1602_digital[(temp[3]/10)]);
LCD1602_display_char(7,1,LCD1602_digital[(temp[3]%10)]);
LCD1602_display_char(14,1,LCD1602_digital[(temp[1]/10)]);
LCD1602_display_char(15,1,LCD1602_digital[(temp[1]%10)]);
LCD1602_display_char(4,2,LCD1602_digital[(temp[4]/10)]);
LCD1602_display_char(5,2,LCD1602_digital[(temp[4]%10)]);
LCD1602_display_char(6,2,':');
LCD1602_display_char(7,2,LCD1602_digital[(temp[5]/10)]);
LCD1602_display_char(8,2,LCD1602_digital[(temp[5]%10)]);
LCD1602_display_char(9,2,':');
LCD1602_display_char(10,2,LCD1602_digital[(temp[6]/10)]);
LCD1602_display_char(11,2,LCD1602_digital[(temp[6]%10)]);
}
}
//以上是主函数
------努力だ、勉强だ、それは天才だ。
谁よりも三倍、四倍、五倍勉强する者、それが天才だ。
