DS1302输出时间,在lcd上显示

完整电路图:

完整代码: 

#include <reg51.h>
#include <intrins.h>			//包含_nop_( )空函数指令的头文件

#define uchar unsigned char
#define uint unsigned int
#define out P2
sbit RS=P3^0; 					
sbit RW=P3^1;				
sbit E=P3^2; 
sbit RST=P1^7 ;
sbit SCLK =P1^6;
sbit DSIO=P1^5;					

void lcd1602_initial(void);			//lcd1602初始化函数
void lcd1602_write_command(uchar com); 	//lcd1602写命令函数
void lcd1602_write_data(uchar dat);		//lcd1602写数据函数
void lcd1602_string(uchar ad ,uchar *s);//lcd1602写字符串
void delay(uint);						//延时函数
void Ds1302Write(uchar add,uchar dat);
uchar Ds1302Read(uchar add);
void Ds1302Readtime_data();
uchar bcd_decimal(uchar bcd);
void write_time();
void xinshi_time();

uchar code table1[]={"2021-01-24"};
uchar code table2[]={"23:59:50"};
uchar nian,zhou,yue,ri,shi,fen,miao;

//---DS1302写入和读取时分秒的地址命令---//
//---秒分时日月周年 最低位读写位;-------//
uchar code read_add[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d}; 
uchar code write_add[7]= {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};

//---DS1302时钟初始化2013年1月1日星期二12点00分00秒。---//
//---存储顺序是秒分时日月周年,存储格式是用BCD码---//
uchar code time_data[7]= {0x58, 0x40, 0x14, 0x29, 0x01, 0x01, 0x21};
uchar code     xingqi1[]={"MON"};
uchar code     xingqi2[]={"TUE"};
uchar code     xingqi3[]={"WED"};
uchar code     xingqi4[]={"THU"};
uchar code     xingqi5[]={"FRI"};
uchar code     xingqi6[]={"SAT"};
uchar code     xingqi7[]={"SUN"};	 

/**************************************************************
*函数名		:delay
*函数功能	:延时函数
*函数参数	:需要延时的毫秒数:uint j
*函数返回值	:无
****************************************************************/
void delay(uint j){	 //1ms延时子程序
	uchar i=250;
	for(;j>0;j--){
		while(--i);
		i=249;
		while(--i);
		i=250;
	}
}

/**************************** ds1302的驱动程序*********************************/

/*******************************************************************************
*函数名     :Ds1302Read
*函数功能   :读取ds1302中的数据
*函数参数   :所需写入的地址:ucahr addr
*函数返回值 :返回写入的数据:ucahr dat
*******************************************************************************/
uchar Ds1302Read(uchar addr){
	uchar n,dat,dat1;
	RST = 0;
	_nop_();

	SCLK = 0;//先将SCLK置低电平。
	_nop_();
	RST = 1;//然后将RST(CE)置高电平。
	_nop_();

	for(n=0; n<8; n++){	//开始传送八位地址命令
		DSIO = addr & 0x01;//数据从低位开始传送
		addr >>= 1;
		SCLK = 1;//数据在上升沿时,DS1302读取数据
		_nop_();
		SCLK = 0;//DS1302下降沿时,放置数据
		_nop_();
	}
	_nop_();
	for(n=0; n<8; n++){	 //读取8位数据
		dat1 = DSIO;//从最低位开始接收
		dat = (dat>>1) | (dat1<<7);
		SCLK = 1;
		_nop_();
		SCLK = 0;//DS1302下降沿时,放置数据
		_nop_();
	}

	RST = 0;
	_nop_();	//以下为DS1302复位的稳定时间,必须的。
	SCLK = 1;
	_nop_();
	DSIO = 0;
	_nop_();
	DSIO = 1;
	_nop_();
	return dat;	
}
/*******************************************************************************
*函数名     : Ds1302Write
*函数功能   : 写入设置的时间
*函数参数   : 地址:ucahr addr,数据:ucahr dat
*函数返回值 : 无
*******************************************************************************/
void Ds1302Write(uchar addr, uchar dat){
	uchar n;
	RST = 0;
	_nop_();
	SCLK = 0;//先将SCLK置低电平。
	_nop_();
	RST = 1; //然后将RST(CE)置高电平。
	_nop_();

	for (n=0; n<8; n++){  //开始传送八位地址命令
		DSIO = addr & 0x01;//数据从低位开始传送
		addr >>= 1;
		SCLK = 1;//数据在上升沿时,DS1302读取数据
		_nop_();
		SCLK = 0;
		_nop_();
	}
	for (n=0; n<8; n++){   //写入8位数据
		DSIO = dat & 0x01;
		dat >>= 1;
		SCLK = 1;//数据在上升沿时,DS1302读取数据
		_nop_();
		SCLK = 0;
		_nop_();	
	}	
		 
	RST = 0;//传送数据结束
	_nop_();
}
/*******************************************************************************
*函数名     :Ds1302Init
*函数功能   :ds1302的初始化
*函数参数   :无
*函数返回值 :无
*******************************************************************************/
void Ds1302Init(){
	uchar n;
	Ds1302Write(0x8E,0X00);		 //禁止写保护,就是关闭写保护功能
	for (n=0; n<7; n++){         //写入7个字节的时钟信号:分秒时日月周年	
		Ds1302Write(write_add[n],time_data[n]);	
	}
	Ds1302Write(0x8E,0x80);		 //打开写保护功能
}


/*******************************************************************************
*函数名     :bcd_decimal
*函数功能   :将BCD吗转成10进制数
*函数参数   :需要转化的bcd:ucahr bcd
*函数返回值 : 转化完成的十进制数:ucahr decimal
*******************************************************************************/
uchar bcd_decimal(uchar bcd){
	uchar decimal;
	decimal = bcd>>4;
	decimal = decimal*10+(bcd&=0x0f);
	return decimal;
}

/*******************************************************************************
*函数名     :write_time 
*函数功能   :将时间显示在lcd上
*函数参数   :地址:ucahr add, 时间:uchar date
*函数返回值 :无
*******************************************************************************/
void write_time(uchar add,uchar date){
	 uchar shi,ge;
	 shi = date/10;
	 ge = date%10;
	 lcd1602_write_command(0x80+add);
	 lcd1602_write_data(0x30+shi);
	 lcd1602_write_data(0x30+ge);
}

/*******************************************************************************
*函数名     :write_week 
*函数功能   :将星期显示在lcd上
*函数参数   :星期的表示值:0-6,分别对应周一到周日:uchar dat
*函数返回值 :无
*******************************************************************************/
void write_week(uchar dat){
	
	 switch(dat){
	 	 case 1:  lcd1602_string(0x80+13,xingqi1); break;
		 case 2:  lcd1602_string(0x80+13,xingqi2); break;
		 case 3:  lcd1602_string(0x80+13,xingqi3); break;
		 case 4:  lcd1602_string(0x80+13,xingqi4); break;
		 case 5:  lcd1602_string(0x80+13,xingqi5); break;
		 case 6:  lcd1602_string(0x80+13,xingqi6); break;
		 case 7:  lcd1602_string(0x80+13,xingqi7); break;
	 }
	
}

/*******************************************************************************
*函数名     : xianshi_time
*函数功能   : 显示时间
*函数参数   : 无
*函数返回值 : 无
*******************************************************************************/
void xianshi_time(){
	  //Ds1302Readtime_data();
	  miao = bcd_decimal(Ds1302Read(0x81));
	  fen =  bcd_decimal(Ds1302Read(0x83));
	  shi =  bcd_decimal(Ds1302Read(0x85));
	  ri =   bcd_decimal(Ds1302Read(0x87));
	  yue =  bcd_decimal(Ds1302Read(0x89));
	  zhou = bcd_decimal(Ds1302Read(0x8b));
	  nian = bcd_decimal(Ds1302Read(0x8d));

	  write_time(0,nian);
	  lcd1602_write_command(0x80+2);
	  lcd1602_write_data(0x2d);
	  write_time(3,yue);
	  lcd1602_write_command(0x80+5);
	  lcd1602_write_data(0x2d);
      write_time(6,ri);
	 
      write_week(zhou);

      write_time(0x40+0,shi);
	  lcd1602_write_command(0xc0+2);
	  lcd1602_write_data(0x3a);
      write_time(0x40+3,fen);
	  lcd1602_write_command(0xc0+5);
	  lcd1602_write_data(0x3a);
	  write_time(0x40+6,miao);	
}


/**************************** lcd1602的驱动程序**********************/

/**************************************************************
*函数名		:lcd1602_write_command
*函数功能	:lcd1602的写命令函数
*函数参数	:所要设置的命令:uchar command
*函数返回值	:无
****************************************************************/
void lcd1602_write_command(uchar command) 	{
	E=0;
	RS=0;
	RW=0;
	out=command;
	E=1;
	_nop_( );
	E=0;
	delay(1);
}
/**************************************************************
*函数名		:lcd1602_write_data
*函数功能	:lcd1602的写数据函数
*函数参数	:要写入的数据:uchar dat
*函数返回值	:无
****************************************************************/
void lcd1602_write_data(uchar dat){   
	E=0;
	RS=1;
	RW=0;
	out=dat;
	E=1;
	_nop_();
	E=0;
	delay(1);	
}
/**************************************************************
*函数名		: lcd1602_initial
*函数功能	: lcd1602的初始化
*函数参数	: 无
*函数返回值	: 无
****************************************************************/
void lcd1602_initial(void){
    lcd1602_write_command(0x38);	       //写入命令0x38:8位两行显示,5×7点阵字符
    lcd1602_write_command(0x0C);	       //写入命令0x0C:开整体显示,光标关,无黑块
    lcd1602_write_command(0x06);	       //写入命令0x06:光标右移
    lcd1602_write_command(0x01); 	       //写入命令0x01:清屏
    delay(1);
}
/**************************************************************
*函数名		:lcd1602_string
*函数功能	:将字符串写入对应的地址上
*函数参数	:地址:uchar ad 字符串:uchar *s
*函数返回值	:无
****************************************************************/
void lcd1602_string(uchar ad,uchar *s){
    lcd1602_write_command(ad);
    while(*s>0){
       lcd1602_write_data(*s++);		//输出字符串,且指针增1
       delay(100);
   }
}


/*********************************主函数************************/
/**************************************************************
*函数名    : 主函数
*函数功能  : 驱动程序
*函数参数  : 无
*函数返回值: 无
****************************************************************/
void main(void){
   lcd1602_initial( );			//调用对LCD初始化函数  
   Ds1302Init();
   while(1)
   {
//		lcd1602_string(0x80,table1);		//显示的第1行数据
//		lcd1602_string(0x80+0x40,table2);	//显示第2行数据
		xianshi_time();	
		
		delay(300); 			//延时	
	}
}

 效果展示:

猜你喜欢

转载自blog.csdn.net/fw1035/article/details/113390616