红外遥控器来调DS1302时钟的时间,在LCD1602上显示时间

用红外遥控器来调DS1302时钟的时间,可以实现,按一下调时间的键,来调秒,按加号键秒+1,按减号键秒-1,再次按调时间的键调分钟,在按调小时,同理,年月日,时分秒都能调节,而且逻辑正确,不管是闰年还是闰月等都会加到相应的天数就恢复为1,例如某个2月是29天,那末当调节天的时候,网上+,加到29,再加会变成1,同理,其他月份都是这样的,当调整完时间后,再次按下调整时间按钮,时间开始从你调节的时间开始运行。

代码在慧静51单片机上测试通过,其他单片机稍微调整引脚即可。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v9W2p3Ny-1607993246787)(IMG_20201215_084356#pic_center)]

#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SCLK=P2^1; //时钟
sbit IO=P2^0; //数据
sbit CE=P2^4; //DS1302复位(片选)
sbit rs=P1^0;
sbit rw=P1^1;
sbit en=P2^5;
sbit BF=P0^7;
sbit FM=P2^3;
sbit duan=P2^6;
uchar yue,chao;
uchar flag_hong;
uchar irtime,extern1_num,bit_num,flag_irtime_ok;
uchar data_irtime[33],data_ircode[4],flag;
char time[7]={0,12,21,13,4,7,20};//秒分时日月周年13-08-15 23:59:50
uchar flag2;
uchar w;
/***********以下为LCD1602部分
***********************************************/
//判忙函数
void panmang()
{
P0=0xff; //注意:先拉高才能正确的读取
do
{
rs=0;
rw=1;
en=0;
en=1;
}while(BF==1);
en=0;
}
//写数据的函数
void write_date(uchar date)
{
panmang();
rs=1;
rw=0;
P0=date;
en=0;
en=1;
en=0;
}
//写指令的函数
void write_com(uchar com)
{
panmang();
rs=0;
rw=0;
P0=com;
en=0;
en=1;
en=0;
}
//初始化的函数
void init_LCD1602()
{
duan=1;
P0=0;
duan=0;
en=0;
write_com(0x38); //16
2显示
write_com(0x0c); //开显示 不显示光标 光标不闪烁
write_com(0x06); //光标地址都自加1
write_com(0x01); //注意:清屏指令
}
/************以下为DS1302的部分
**********************************************************/
//延时函数
void delay(uint n)
{
while (n–);
}
//三条线初始化的函数
void xian_init()
{
CE=0;
SCLK=0;
IO=0;
}
//写一个字节的函数
void writezijie(uchar date)
{
uchar i;
SCLK=0;
for(i=0;i<8;i++)
{
IO=date&0x01;
SCLK=1;
date>>=1;
SCLK=0;
}
}
//读一个字节的函数
uchar duzijie()
{
uchar i,date=0;
for(i=0;i<8;i++)
{
date>>=1;
if(IO==1)
date|=0x80;
SCLK=1;
SCLK=0;

}
return date;
}
//写数据的函数
void writeshuju(uchar addr,uchar shuju)
{
xian_init();
CE=1;
writezijie(addr);
writezijie(shuju);
IO=0;
CE=0;
}
//读数据的函数
uchar readshuju(uchar addr)
{
uchar temp;
xian_init();
CE=1;
writezijie(addr);
temp=duzijie();
IO=0;
CE=0;
return temp;
}
//清除写保护
void clear_wp()
{
xian_init();
CE=1;
writezijie(0x8e);
writezijie(0);
IO=0;
CE=0;
}
//设置写保护
void setup_wp()
{
xian_init();
CE=1;
writezijie(0x8e);
writezijie(1);
IO=0;
CE=0;
}
//将数据转换成BCD码的形式
void zhuanhuan_BCD(uchar shuzu)
{
uchar an,i;
for(i=0;i<7;i++)
{
an=shuzu[i]/10;
shuzu[i]=shuzu[i]%10;
shuzu[i]=shuzu[i]+an
16;
}
}
//给寄存器初始化的数据
void chushihua()
{ uchar tmp,i;
tmp=0x80; //传写地址
for(i=0;i<7;i++) //7次写入
{
writeshuju(tmp,time[i]);
tmp+=2;
}
}
//从寄存器中读取数据的函数
void dujicunqi(uchar *timedata)
{
if(flag_hong==0)
{
chao=0x81;
yue=0;
for(yue;yue<7;yue++)
{
timedata[yue]=readshuju(chao);
chao+=2;
}
}

else if(flag_hong==1)
{
delay(1000);
}

}
//时间停止的函数
void stop()
{
flag_hong=1;
clear_wp();
writeshuju(0x80,time[0]|0x80);
setup_wp();
}
//时间重新启动
void start()
{
uchar an;
flag_hong=0;
clear_wp();
an=time[0]&0x7f;
writeshuju(0x80,an);
writeshuju(0x82,time[1]&0x7f);
writeshuju(0x84,time[2]&0x7f);
writeshuju(0x86,time[3]&0x7f);
writeshuju(0x88,time[4]&0x7f);
writeshuju(0x8c,time[6]&0x7f);
setup_wp();
}
/**************以下为红外遥控部分
********************************************/
void delay1ms()
{
unsigned char i,j;
for(i=0;i<10;i++)
for(j=0;j<33;j++)
;
}
void delaynms(unsigned char n)
{
unsigned char i;
for(i=0;i<n;i++)
delay1ms();
}
void beep() //蜂鸣器响一声函数
{
unsigned char i;
for (i=0;i<100;i++)
{
delay1ms();
FM=!FM; //BEEP取反
}
FM=1; //关闭蜂鸣器
delaynms(250); //延时
}
//定时器初始化的函数
void initial_timer0()
{
TMOD=0x02;
TH0=0;
TL0=0;
EA=1;
ET0=1;
TR0=1;
}
//外部中段0初始化的函数
void initial_extern0()
{
IT0=1;
EA=1;
EX0=1;
}
//定时器t0中断函数
void timer0() interrupt 1
{
irtime++;
}
//外部中断0的函数 根据每位数据的时间并将其储存到数组里
void extern0() interrupt 0
{
extern1_num++;
if(extern1_num1)
{
irtime=0;
}
else
{
if(irtime>48)
{
bit_num=0;
flag=1;
}
if(flag
1)
{
data_irtime[bit_num]=irtime;
irtime=0;
bit_num++;
if(bit_num==33)
{
flag_irtime_ok=1;
extern1_num=0;
flag=0;
}
}
}

}
//根据每位数据的时间来转换成0和1
void irdata_processing()
{
uchar value,k=1,i,j;
for(j=0;j<4;j++)
{
for(i=0;i<8;i++)
{
value=value>>1;
if(data_irtime[k]>6)
{
value=value|0x80;
}
k++;
}
data_ircode[j]=value;
}
}
//将数据显示到LCD1602上
void lcd1602_display()
{
write_com(0x80+10);

if(data_ircode[2]/16<10)
{
  write_date(data_ircode[2]/16+0x30);
}
else
{
  write_date(data_ircode[2]/16+0x37);
}

if(data_ircode[2]%16<10)
{
write_date(data_ircode[2]%16+0x30);
}
else
{
write_date(data_ircode[2]%16+0x37);
}
}

//调节时间的函数
void tiaotime()
{
if(data_ircode[2]==0x09)
{
++w;
stop();
}

	if(w==1)						 //调秒
	 {
	   if(data_ircode[2]==0x15)
	   {
	     clear_wp();
	     time[0]=time[0]&0x7f;
		 if(time[0]%16==0x9)
		 {
		   time[0]=time[0]|0xf;
		 }
		 time[0]++;
		 setup_wp();
		 if(time[0]/16==0x6)
		 {
		   clear_wp();
		   time[0]=0;
		   setup_wp();
		 }
	   }
	   if(data_ircode[2]==0x07)
	   {
	   	 clear_wp();
		 time[0]=time[0]&0x7f;
		 time[0]--;
			  if(time[0]%16==0xf)
			 {
			   switch(time[0]/16)
			   { 
			   	 case 0x0: time[0]=0x09; break;		//09
			   	 case 0x1: time[0]=0x19; break;		//19
			   	 case 0x2: time[0]=0x29; break;		//29
			   	 case 0x3: time[0]=0x39; break;		//39
				 case 0x4: time[0]=0x49; break;		//39
			   }
			 }
		 setup_wp();
		 if(time[0]==-1)
		 {
		   clear_wp();
		   time[0]=0x59;
		   setup_wp();
		 }  
	   }
	 
	 } 




	 if(w==2)					   //调分
	 {
	   if(data_ircode[2]==0x15)
	   {
	     clear_wp();
	     time[1]=time[1]&0x7f;
		 if(time[1]%16==0x9)
		 {
		   time[1]=time[1]|0xf;
		 }
		 time[1]++;
		 setup_wp();
		 if(time[1]/16==0x6)
		 {
		   clear_wp();
		   time[1]=0;
		   setup_wp();
		 }
	   }
	   if(data_ircode[2]==0x07)
	   {
	   	 clear_wp();
		 time[1]=time[1]&0x7f;
		 time[1]--;
			  if(time[1]%16==0xf)
			 {
			   switch(time[1]/16)
			   { 
			   	 case 0x0: time[1]=0x09; break;		//09
			   	 case 0x1: time[1]=0x19; break;		//19
			   	 case 0x2: time[1]=0x29; break;		//29
			   	 case 0x3: time[1]=0x39; break;		//39
				 case 0x4: time[1]=0x49; break;		//39
			   }
			 }
		 setup_wp();
		 if(time[1]==-1)
		 {
		   clear_wp();
		   time[1]=0x59;
		   setup_wp();
		 }  
	   }
	 
	 } 


	  if(w==3)					   //调小时
	 {
	   if(data_ircode[2]==0x15)
	   {
	     clear_wp();
	     time[2]=time[2]&0x7f;
		 if(time[2]%16==0x9)
		 {
		   time[2]=time[2]|0xf;
		 }
		 time[2]++;
		 setup_wp();
		 if(time[2]==0x24)
		 {
		   clear_wp();
		   time[2]=0;
		   setup_wp();
		 }
	   }
	   if(data_ircode[2]==0x07)
	   {
	   	 clear_wp();
		 time[2]=time[2]&0x7f;
		 time[2]--;
			  if(time[2]%16==0xf)
			 {
			   switch(time[2]/16)
			   { 
			   	 case 0x0: time[2]=0x09; break;		//09
			   	 case 0x1: time[2]=0x19; break;		//19
			   }
			 }
		 setup_wp();
		 if(time[2]==-1)
		 {
		   clear_wp();
		   time[2]=0x23;
		   setup_wp();
		 }  
	   }
	 
	 } 



	  if(w==4)					   //调天数
	 {
	   if(data_ircode[2]==0x15)
	   {
	     clear_wp();
	     time[3]=time[3]&0x7f;
		 if(time[3]%16==0x9)
		 {
		   time[3]=time[3]|0xf;
		 }
		 time[3]++;
		 setup_wp();
		 if(time[3]==0x32)
		 {
		   clear_wp();
		   time[3]=1;
		   setup_wp();
		 }
	   }
	   if(data_ircode[2]==0x07)
	   {
	   	 clear_wp();
		 time[3]=time[3]&0x7f;
		 time[3]--;
			  if(time[3]%16==0xf)
			 {
			   switch(time[3]/16)
			   { 
			   	 case 0x0: time[3]=0x09; break;		//09
			   	 case 0x1: time[3]=0x19; break;		//19
				 case 0x2: time[3]=0x29; break;		//29
			   }
			 }
		 setup_wp();
		 if(time[3]==0)
		 {
		   clear_wp();
		   time[3]=0x31;
		   setup_wp();
		 }  
	   }
	 
	 } 


	 if(w==5)					   //调月份
	 {
	   if(data_ircode[2]==0x15)
	   {
	     clear_wp();
	     time[4]=time[4]&0x7f;
		 if(time[4]%16==0x9)
		 {
		   time[4]=time[4]|0xf;
		 }
		 time[4]++;
		 setup_wp();
		 if(time[4]==0x13)
		 {
		   clear_wp();
		   time[4]=1;
		   setup_wp();
		 }
	   }
	   if(data_ircode[2]==0x07)
	   {
	   	 clear_wp();
		 time[4]=time[4]&0x7f;
		 time[4]--;
			  if(time[4]%16==0xf)
			 {
			   switch(time[4]/16)
			   { 
			   	 case 0x0: time[4]=0x09; break;		//09
			   }
			 }
		 setup_wp();
		 if(time[4]==0)
		 {
		   clear_wp();
		   time[4]=0x12;
		   setup_wp();
		 }  
	   }
	 
	 } 




	  if(w==6)					   //调年份
	 {
	   if(data_ircode[2]==0x15)
	   {
	     clear_wp();
	     time[6]=time[6]&0x7f;
		 if(time[6]%16==0x9)
		 {
		   time[6]=time[6]|0xf;
		 }
		 time[6]++;
		 setup_wp();
		  if(time[6]==0x70)
		 {
		   clear_wp();
		   time[6]=0x20;
		   setup_wp();
		 }
	   }
	   if(data_ircode[2]==0x07)
	   {
	   	 clear_wp();
		 time[6]=time[6]&0x7f;
		 time[6]--;
			  if(time[6]%16==0xf)
			 {
			   switch(time[6]/16)
			   { 
				 case 0x0: time[0]=0x09; break;		//09
			   	 case 0x1: time[0]=0x19; break;		//19
			   	 case 0x2: time[0]=0x29; break;		//29
			   	 case 0x3: time[0]=0x39; break;		//39
				 case 0x4: time[0]=0x49; break;		//49
				 case 0x5: time[0]=0x59; break;		//59
			   }
			 }
		 setup_wp();
		 if(time[6]/16==0x1)
		 {
		   clear_wp();
		   time[6]=0x20;
		   setup_wp();
		 }  
	   }
	 
	 } 




 	 if(w==7)
	{
	   w=0;
	   start();
	} 

}

//主函数
void main()
{
init_LCD1602(); //LCD1602初始化
initial_timer0(); //定时器0初始化
initial_extern0(); //外部中断0初始化
zhuanhuan_BCD(time);//将数组里的数据转换成BDC码的形式
clear_wp(); //清除写保护
chushihua(); //给寄存器写入数据 //秒分时日月周年13-08-15 23:59:50
setup_wp(); //设置写保护
while(1)
{

if(flag_irtime_ok==1)
	   {
	     irdata_processing();
		 flag_irtime_ok=0;
		 beep();
		 flag2=1;
	   } 
  lcd1602_display();

if(flag2==0)
{
dujicunqi(time);

 write_com(0x80+0);
 write_date(time[6]/16+'0');   //年
 write_date(time[6]%16+'0');   //年
 write_date('-');

 write_date(time[4]/16+'0');   //月
 write_date(time[4]%16+'0');   //月
 write_date('-');

 write_date(time[3]/16+'0');   //日
 write_date(time[3]%16+'0');   //日



 write_com(0x80+0x40+0);
 write_date(time[2]/16+'0');   //时
 write_date(time[2]%16+'0');   //时
 write_date(':');

 write_date(time[1]/16+'0');   //分
 write_date(time[1]%16+'0');   //分
 write_date(':');

 write_date(time[0]/16+'0');   //秒
 write_date(time[0]%16+'0');   //秒
 delay(1000);

}
else
{
tiaotime();
flag2=0;
}

}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值