⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds1302.c

📁 ds1302和液晶1602写的万年历!值得下载!
💻 C
字号:
#include <at89x51.h>
sbit T_CLK = P2^5; //实时时钟时钟线引脚 
sbit T_IO = P2^6; //实时时钟数据线引脚 
sbit T_RST = P2^7; //实时时钟复位线引脚 
sbit ACC0=ACC^0;
sbit ACC7=ACC^7;
sbit rs=P1^2;
sbit rw=P1^3;
sbit e=P1^4;
sbit set=P3^4; //设置
sbit add=P3^5; //加
sbit dec=P3^6; //减
void show();
void keyscan();
void inishow();
unsigned char hex_bcd(unsigned char hex_data);
unsigned char bcd_hex(unsigned char bcd_data);
unsigned char code tab[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
unsigned char code buf[7]={0x00,0x00,0x0c,0x0d,0x0a,0x01,0x0a};//初始时间格式为: 秒 分 时 日 月 星期 年 
unsigned char data ucCurtime[7];
unsigned char a,yearh,yearl,monh,monl,dah,dal,hoh,hol,wekl,mih,mil,seh,sel;
unsigned char Addr;
//延时
void delay()
{ 
	unsigned char y;
 	for(y=0;y<75;y++);
}
/******************************************************************** 
* 名称: InputByte
* 功能: 向1302写数据
***********************************************************************/
void InputByte(unsigned char ucDa) 
{ 
	unsigned char i;
	ACC = ucDa;
	for(i=8; i>0; i--)
	{
		T_IO = ACC0; //相当于汇编中的 RRC 
		T_CLK = 1;
		T_CLK = 0;
		ACC = ACC >> 1; 
	} 
}
/******************************************************************** 
* 名称: OutputByte
* 功能: 从1302读数据
***********************************************************************/
unsigned char OutputByte(void) 
{ 
	unsigned char i;
	for(i=8; i>0; i--)
	{
		ACC = ACC >>1; //相当于汇编中的 RRC 
		ACC7 = T_IO;
		T_CLK = 1;
		T_CLK = 0;
	} 
	return(ACC); 
}
/******************************************************************** 
* 名称: W1302
* 功能: 向1302写数据
***********************************************************************/
void W1302(unsigned char ucAddr, unsigned char ucDa)
{
	T_RST = 0;
	T_CLK = 0;
	T_RST = 1;
	InputByte(ucAddr); // 地址,命令 
	InputByte(ucDa); // 写1Byte数据
	T_CLK = 1;
	T_RST =0;
} 
/******************************************************************** 
* 名称: R1302
* 功能: 从1302读数据
***********************************************************************/
unsigned char R1302(unsigned char ucAddr)
{
	unsigned char ucDa,a;
	T_RST = 0;
	T_CLK = 0;
	T_RST = 1;
	InputByte(ucAddr); // 地址,命令 
	a = OutputByte(); // 读1Byte数据
	ucDa=bcd_hex(a); 
	T_CLK = 1;
	T_RST =0;
	return(ucDa);
}
/******************************************************************** 
* 名称: Set1302
* 功能: 设置初始时间
* 调用: W1302() 
* 输入: pSecDa: 初始时间地址。初始时间格式为: 秒 分 时 日 月 星期 年 
* 7Byte (BCD码) 1B 1B 1B 1B 1B 1B 1B
* 返回值: 无
***********************************************************************/
void set1302(unsigned char *pSecDa) 
{
	unsigned char i;
	unsigned char ucAddr = 0x80; 
	W1302(0x8e,0x00); // 控制命令,WP=0,写操作?
	for(i=0;i<7;i++)
	{   
		W1302(ucAddr,hex_bcd(*pSecDa)); // 秒 分 时 日 月 星期 年 	
		pSecDa++;
		ucAddr +=2;
	}
	W1302(0x8e,0x80); // 控制命令,WP=1,写保护?
}
/******************************************************************** 
* 名称: write_com
* 功能: 写命令到1602
* 返回值: 无
***********************************************************************/
void write_com(unsigned char j)//写命令
{
	e=0;
	rs=0;
	rw=0;
	e=1;
	P0=j;
	e=0;
	delay();
}
/******************************************************************** 
* 名称: write_dat
* 功能: 写数据到1602
* 返回值: 无
***********************************************************************/
void write_dat(unsigned char dat)//写数据
{
	e=0;
	rs=1;
	rw=0;
	e=1;
	P0=dat;
	e=0;
	delay();
}
/******************************************************************** 
* 名称: init
* 功能: 初始化1602
* 返回值: 无
***********************************************************************/
void init()//初始化lcd
{
	write_com(0x01);
	write_com(0x38);
	write_com(0x38);
	write_com(0x0e);
	write_com(0x06);
	write_com(0x0c);
}
/******************************************************************** 
* 名称: write1602
* 功能: 向1602指定地址写数据
* 返回值: 无
***********************************************************************/
void write1602(unsigned char add,unsigned char dat)//写入显示数据
{
	write_com(add);
	write_dat(dat);
}
/******************************************************************** 
* 名称: hex_bcd
* 功能: 将16进制转成bcd码
* 返回值: bcd_data
***********************************************************************/
unsigned char hex_bcd(unsigned char hex_data)
{
	unsigned char temp=0,bcd_data=0;	
	temp=hex_data%100;	
	bcd_data=bcd_data|temp/10<<4;	
	bcd_data=bcd_data|temp%10;
	return bcd_data;	
}
/******************************************************************** 
* 名称: bcd_hex
* 功能: 将bcd码转成16进制
* 返回值: temp
***********************************************************************/
unsigned char bcd_hex(unsigned char bcd_data)
{
	unsigned char temp=0;
	temp=((bcd_data>>4)*10)+(bcd_data&0x0f);
	return temp;
}
/******************************************************************** 
* 名称: keyscan
* 功能: 键盘扫描程序
* 返回值: 无
***********************************************************************/
void keyscan()
{
	unsigned char keynum;
	if(set==0);
	delay();
	if(set==0)
	{
		while(!set);
		delay();
		while(!set);		
		keynum++;		
		if(keynum==1)
		{	
			TR0=0;
			write_com(0x0f);
			write_com(0xce);				
		}
		if(keynum==2)
		{
			write_com(0xc8);		
		}
		if(keynum==3)
		{
			write_com(0xc5);			
		}
		if(keynum==4)
		{
			write_com(0x8b);		
		}
		if(keynum==5)
		{
			write_com(0x88);		
		}
		if(keynum==6)
		{
			write_com(0x85);				
		}
		if(keynum==7)
		{
			keynum=0;
			write_com(0x0c);			
			set1302(ucCurtime);
			TR0=1;
		}		

	}

	if(keynum!=0)
	{
		if(add==0)
		delay();
		if(add==0)
		{
			while(!add);
			delay();
			while(!add);
			if(keynum==1)
			{
				ucCurtime[5]++;
				if(ucCurtime[5]>7)
				ucCurtime[5]=1;
				write_com(0xce);
				write_dat(tab[ucCurtime[5]%10]);
				write_com(0xce);
			}
			if(keynum==2)
			{
				ucCurtime[1]++;
				if(ucCurtime[1]>59)
				ucCurtime[1]=0;
				write_com(0xc9);
				write_dat(tab[ucCurtime[1]%10]);
				write_com(0xc8);
				write_dat(tab[ucCurtime[1]/10]);
				write_com(0xc8);				
			}
			if(keynum==3)
			{
				ucCurtime[2]++;
				if(ucCurtime[2]>23)
				ucCurtime[2]=0;
				write_com(0xc6);
				write_dat(tab[ucCurtime[2]%10]);
				write_com(0xc5);
				write_dat(tab[ucCurtime[2]/10]);
				write_com(0xc5);
			}
			if(keynum==4)
			{
				ucCurtime[3]++;
				if(ucCurtime[4]==1||ucCurtime[4]==3||ucCurtime[4]==5||ucCurtime[4]==7||ucCurtime[4]==8||ucCurtime[4]==10||ucCurtime[4]==12)
				{
					if(ucCurtime[3]>31)
					ucCurtime[3]=01;
				}
				if(ucCurtime[4]==4||ucCurtime[4]==6||ucCurtime[4]==9||ucCurtime[4]==11)
				{
					if(ucCurtime[3]>30)
					ucCurtime[3]=01;
				}
				if(ucCurtime[4]==2)
				{	
					if(((ucCurtime[6]+2000)%4==0&&(ucCurtime[6]+2000)%100!=0)||((ucCurtime[6]+2000)%400==0))
					{
						if(ucCurtime[3]>29)
						ucCurtime[3]=01;
					}
					else 
					{
						if(ucCurtime[3]>28)
						ucCurtime[3]=01;
					}
				}		
				write_com(0x8c);
				write_dat(tab[ucCurtime[3]%10]);
				write_com(0x8b);
				write_dat(tab[ucCurtime[3]/10]);
				write_com(0x8b);
			}
			if(keynum==5)
			{
				ucCurtime[4]++;
				if(ucCurtime[4]>12)
				ucCurtime[4]=01;
				write_com(0x89);
				write_dat(tab[ucCurtime[4]%10]);
				write_com(0x88);
				write_dat(tab[ucCurtime[4]/10]);
				write_com(0x88);
			}
			if(keynum==6)
			{
				ucCurtime[6]++;
				if(ucCurtime[6]==100)
				ucCurtime[6]=0;
				write_com(0x86);
				write_dat(tab[ucCurtime[6]%10]);
				write_com(0x85);
				write_dat(tab[ucCurtime[6]/10]);
				write_com(0x85);
			}
		}
		if(dec==0)
		{
			while(!dec);
			delay();
			while(!dec);
			if(keynum==1)
			{
				if(ucCurtime[5]==1)
				ucCurtime[5]=0x08;
				ucCurtime[5]--;
				write_com(0xce);
				write_dat(tab[ucCurtime[5]%10]);
				write_com(0xce);
			}
			if(keynum==2)
			{
				if(ucCurtime[1]==0)
				ucCurtime[1]=60;
				ucCurtime[1]--;
				write_com(0xc9);
				write_dat(tab[ucCurtime[1]%10]);
				write_com(0xc8);
				write_dat(tab[ucCurtime[1]/10]);
				write_com(0xc8);
			}
			if(keynum==3)
			{
				if(ucCurtime[2]==0)
				ucCurtime[2]=24;
				ucCurtime[2]--;
				write_com(0xc6);
				write_dat(tab[ucCurtime[2]%10]);
				write_com(0xc5);
				write_dat(tab[ucCurtime[2]/10]);
				write_com(0xc5);
			}
			if(keynum==4)
			{
				if(ucCurtime[4]==1||ucCurtime[4]==3||ucCurtime[4]==5||ucCurtime[4]==7||ucCurtime[4]==8||ucCurtime[4]==10||ucCurtime[4]==12)
				{
					if(ucCurtime[3]==01)
					ucCurtime[3]=32;
				}
				if(ucCurtime[4]==4||ucCurtime[4]==6||ucCurtime[4]==9||ucCurtime[4]==11)
				{
					if(ucCurtime[3]==01)
					ucCurtime[3]=31;
				}
				if(ucCurtime[4]==2)
				{	
					if(((ucCurtime[6]+2000)%4==0&&(ucCurtime[6]+2000)%100!=0)||((ucCurtime[6]+2000)%400==0))
					{
						if(ucCurtime[3]==01)
						ucCurtime[3]=30;
					}
					else 
					{
						if(ucCurtime[3]==01)
						ucCurtime[3]=29;
					}
				}
				ucCurtime[3]--;
				write_com(0x8c);
				write_dat(tab[ucCurtime[3]%10]);
				write_com(0x8b);
				write_dat(tab[ucCurtime[3]/10]);
				write_com(0x8b);
			}
			if(keynum==5)
			{
				if(ucCurtime[4]==1)
				ucCurtime[4]=13;
				ucCurtime[4]--;
				write_com(0x89);
				write_dat(tab[ucCurtime[4]%10]);
				write_com(0x88);
				write_dat(tab[ucCurtime[4]/10]);
				write_com(0x88);
			}
			if(keynum==6)
			{
				if(ucCurtime[6]==0)
				ucCurtime[6]=100;
				ucCurtime[6]--;
				write_com(0x86);
				write_dat(tab[ucCurtime[6]%10]);
				write_com(0x85);
				write_dat(tab[ucCurtime[6]/10]);
				write_com(0x85);
			}
		}		
	}	
}

void show()
{
		Addr = 0x81;
		for (a=0;a<7;a++)
		{
			ucCurtime[a]=R1302(Addr);//格式为: 秒 分 时 日 月 星期 年 
			Addr += 2;
		}		
		yearh=ucCurtime[6]/10;
		yearl=ucCurtime[6]%10;
		monh=ucCurtime[4]/10;
		monl=ucCurtime[4]%10;
		dah=ucCurtime[3]/10;
		dal=ucCurtime[3]%10;		
		hoh=ucCurtime[2]/10;
		hol=ucCurtime[2]%10;
		mih=ucCurtime[1]/10;
		mil=ucCurtime[1]%10;
		seh=ucCurtime[0]/10;
		sel=ucCurtime[0]%10;		
		wekl=ucCurtime[5]%10;		
		write1602(0x85,tab[yearh]);
		write1602(0x86,tab[yearl]);		
		write1602(0x88,tab[monh]);
		write1602(0x89,tab[monl]);		
		write1602(0x8b,tab[dah]);
		write1602(0x8c,tab[dal]);		
		write1602(0xc5,tab[hoh]);
		write1602(0xc6,tab[hol]);		
		write1602(0xc8,tab[mih]);
		write1602(0xc9,tab[mil]);		
		write1602(0xcb,tab[seh]);
		write1602(0xcc,tab[sel]);
		write1602(0x8d,0x57);
		write1602(0x8e,0x65);
		write1602(0xce,tab[wekl]);		
}
void inishow()
{
		write1602(0x80,0x44);
		write1602(0x81,0x61);
		write1602(0x82,0x74);
		write1602(0x83,0x65);
		write1602(0x84,0x3a);//显示date:
		write1602(0x87,0x2d);//显示年
		write1602(0x8a,0x2d);//显示月
		write1602(0xc0,0x54);
		write1602(0xc1,0x69);
		write1602(0xc2,0x6d);
		write1602(0xc3,0x65);
		write1602(0xc4,0x3a);//显示time:
		write1602(0xc7,0x3a);//显示小时
		write1602(0xca,0x3a);//显示小时
		write1602(0x8f,0x6b);//显示wek:
}
/******************************************************************** 
* 名称: main
* 功能: 主程序
* 返回值: 无
***********************************************************************/
void main()
{
	init();//LCD初始化
	inishow();
	set1302(buf);
	TMOD=0X01;
	TH0=0XDC;
	TL0=0X00;
	EA=1;
	ET0=1;
	TR0=1;
	while(1)
	{
		keyscan();		
	}
}
void timer0() interrupt 1
{
	TH0=0XDC;
	show();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -