#include<reg52.h>
#include <intrins.h>
#include"IIC.h "
sbit sck=P1^0;
sbit io=P1^1;
sbit beep=P1^6; //定义蜂鸣器
sbit rst=P1^7;
sbit key1=P1^5;//小时+
sbit key2=P1^4;//分钟+
sbit key3=P3^7;//按键读取
sbit key4=P3^6;//按键返回计时
uchar code smg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x40};
uchar code smg_we[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//{0x08,0x18,0x28,0x38,0x48,0x58,0x68,0x78};
//共阴数码管 0-9 '-' '熄灭‘表
uint AdderCnt;
uint DuQu;
uint baochunchishu;//保存次数
uchar NOW[6]={2,3,5,9,5,5,}; // 闹铃设置数组 23:59:55 开闹钟
uchar time_data[7]={15,4,12,31,23,55,00}; //初值年.周.月.日.时.分.秒 15年星期四 12月31日 23点59分50秒
uchar write_add[7]={0x8c,0x8a,0x88,0x86,0x84,0x82,0x80};
uchar read_add[7]={0x8d,0x8b,0x89,0x87,0x85,0x83,0x81};
uchar value,count,status,keyvalue=0,value1;
uchar num1 ,num2,num3 ,num4,num5,num6,num7,num8,num9 ,num10,num11,num12,num13,num,t;
uchar num14 ,num15,num16 ,num17,num18,num19;
//---------- 函数声明 --------------//
void write_ds1302_byte(uchar dat);//单字节写
void write_ds1302(uchar add,uchar dat);
uchar read_ds1302(uchar add);//单字节读
void set_rtc(void);//设置时钟函数
void read_rtc(void);//读时钟
void time_pros(void);//处理函数
void time_pros1(void);//处理函数
void init();
uchar disp[16];
uchar disp1[16]=0;
void display(void);//显示函数
void display1(void);//显示保存数1
void display2(void);//显示保存数2
void delay(uint);//延时函数
void key_check();//按键检测
void naozhong(); //闹钟检测
void warn(); //报警声音
void dely500(void) ;//延时函数
void KeyCheck();//按键按下显示计时时间
void duqubaochunshu();//读取保存数
/*************单字节写函数***************/
void write_ds1302_byte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
sck=0;
io=dat&0x01;
dat=dat>>1;
sck=1;
}
}
/***********写地址,写数据函数***********/
void write_ds1302(uchar add,uchar dat)
{
rst=0;
_nop_();
sck=0;
_nop_();
rst=1;
_nop_();
write_ds1302_byte(add);//写地址
write_ds1302_byte(dat); //写数据
rst=0;
_nop_();
io=1;
sck=1;
}
/***********单字节读***********/
uchar read_ds1302(uchar add)//单字节读
{
uchar i;
rst=0;
_nop_();
sck=0;
_nop_();
rst=1;
_nop_();
write_ds1302_byte(add); //写地址
for(i=0;i<8;i++)
{
value=value>>1;
sck=0;
if(io)
value=value|0x80;
sck=1;
}
rst=0;
_nop_();
sck=0;
_nop_();
sck=1;
io=1;
return value;
}
/**************设置时钟函数****************/
void set_rtc(void)
{
uchar i,j;
for(i=0;i<7;i++)
{
j=time_data/10;
time_data=time_data%10;
time_data=time_data+j*16;
}
write_ds1302(0x8e,0x00);//去除写保护
for(i=0;i<7;i++)
{
write_ds1302(write_add,time_data);
}
write_ds1302(0x8e,0x80);//加写保护
}
/*********读时钟函数***********/
void read_rtc(void)
{
uchar i;
for(i=0;i<7;i++)
{
time_data=read_ds1302(read_add);
}
}
/*************处理函数***************/
void time_pros(void)//处理函数
{
disp[0]=time_data[6]%16;//显示miao
disp[1]=time_data[6]/16;//显示shimiao
disp[2]=10; //显示—号
disp[3]=time_data[5]%16;//显示分
disp[4]=time_data[5]/16;//显示十分
disp[5]=10; //显示—号
disp[6]=time_data[4]%16;//显示小时
disp[7]=time_data[4]/16;//显示十小时
disp[8]=time_data[3]%16;//显示
disp[9]=time_data[3]/16;//显示
disp[10]=time_data[2]%16;//显示
disp[11]=time_data[2]/16;//显示
disp[12]=time_data[1]%16;//显示
disp[13]=time_data[1]/16;//显示
disp[14]=time_data[0]%16;//显示
disp[15]=time_data[0]/16;//显示
}
/***********************************/
/*************处理保存函数***************/
void time_pros1(void)//处理函数
{
disp1[0]=num15/10; //保存次数十位
disp1[1]=num15%10; //保存次数个位
//disp1[2]=10; //显示—号
disp1[2]=num7%10;//十小时
disp1[3]=num8%10;//小时
//disp1[5]=10; //显示—号
disp1[4]=num9%10;//十分
disp1[5]=num10%10;;//分
disp1[6]=num11%10; //十秒
disp1[7]=num12%10; //秒
}
/***********显示函数************/
void display(void)
{
/*************显示ds1302的计时*************/
P2= smg_we[0]; //显示miao
P0=smg_du[disp[0]];//
delay(5);
P2= smg_we[1];
P0=smg_du[disp[1]];//显示shimiao
delay(5);
P2= smg_we[2] ; //显示—号
P0=smg_du[disp[2]];
delay(5);
P2= smg_we[3]; //显示分
P0=smg_du[disp[3]]; //
delay(5);
P2= smg_we[4]; //显示十分
P0=smg_du[disp[4]]; //
delay(5);
P2= smg_we[5] ; //显示—号
P0=smg_du[disp[5]];
delay(5);
P2= smg_we[6]; //显示小时
P0=smg_du[disp[6]]; //
delay(5);
P2= smg_we[7]; //显示十小时
P0=smg_du[disp[7]]; //
delay(5);
P2=0xff;
delay(5);
}
/*****************显示24C02保存的时间函数******************/
void display1(void)//显示保存时间
{
P2= smg_we[0] ;
P0=smg_du[disp1[7]]; //秒
delay(5);
P2= smg_we[1] ;
P0=smg_du[disp1[6]];//十秒
delay(5);
P2= smg_we[2] ;
P0=smg_du[disp1[5]];//分
delay(5);
P2= smg_we[3] ;
P0=smg_du[disp1[4]];//十分
delay(5);
P2= smg_we[4] ;
P0=smg_du[disp1[3]];//小时
delay(5);
P2= smg_we[5] ;
P0=smg_du[disp1[2]];//十小时
delay(5);
P2= smg_we[6] ;
P0=smg_du[disp1[1]];//计时次数个位
delay(5);
P2= smg_we[7] ;
P0=smg_du[disp1[0]];///计时次数十位
delay(5);
P2=0xff;
delay(5);
}
/**********延时函数************/
void delay(uint z)//延时函数
{
uint x,y;
for(x=z;x>0;x--)
for(y=25;y>0;y--);//20151025改原y=120
}
/************按键函数************/
void key_check()
{
if(key1==0) //
{
delay(5);
if(key1==0)
{
while(!key1); //松手检测
time_data[4]=((time_data[4]+1)>>4)*10 + ((time_data[4]+1)&0x0f); //小时加1
if(time_data[4]>23) time_data[4]=0; //判断
time_data[4]=time_data[4]%10+time_data[4]/10*16; //转十进制
write_ds1302(0x8E,0X00); //去除写保护
write_ds1302(0x84,time_data[4]); //写小时寄存器
write_ds1302(0x8E,0x80); //加写保护
//set=0;
}
}
if(key2==0)//
{
delay(5);
if(key2==0)
{
while(!key2); //松手检测
time_data[5]=((time_data[5]+1)>>4)*10 + ((time_data[5]+1)&0x0f); //分加1
if(time_data[5]>59) time_data[5]=0; //判断
time_data[5]=time_data[5]%10+time_data[5]/10*16; //转十进制
write_ds1302(0x8E,0X00); //去除写保护
write_ds1302(0x82,time_data[5]); //写分寄存器
write_ds1302(0x8E,0x80); //加写保护
}
}
/* if(key4==0)//
{
delay(5);
if(key4==0)
{
while(!key4)
{
key_check();//按键检测
read_rtc();
time_pros();//处理函数
display();
naozhong(); //定时闹钟
}
}
} */
}
/************************************************************************/
/* 闹钟函数 */
/************************************************************************/
void naozhong()
{
if(disp[7]==NOW[0]&&disp[6]==NOW[1]
&&disp[4]==NOW[2]&&disp[3]==NOW[3]
&&disp[1]==NOW[4]&&disp[0]==NOW[5]) // 设置NOW的时间与时钟时间显示比较
{
warn();//报警
}
}
/************************************************************************/
void warn() //报警声音
{
for(count=200;count>0;count--)
{
beep=~beep;
dely500();
}
for(count=100;count>0;count--)
{
beep=~beep;
dely500();
dely500();
}
}
/************************************************************************/
void timer0(void) interrupt 1
{
TH0=(65535-50000)/256;//设置定时器0为工作方式1.定时50ms.
TL0=(65535-50000)%256;
t++;
if(t==20)
{ t=0; num13++;
if (num==2)
{
num++;
}
else
{
num =0;
}
if(num13>=10)
{num13=0;status++;}
if(status>=2)
{status=0;}
}
}
/***********************中断保存*************************/
void int_0() interrupt 0 //using 0
{
EA=0; // CPU所有中断关
baochunchishu+=1; //保存次数
AdderCnt += 7;//
if(AdderCnt >= 255) //根据空间大小,对AdderCnt做限定
{
AdderCnt = 0;
baochunchishu=0;
}
num1=disp[0];
write_adress_data(0x00+AdderCnt,num1);//写秒
delay(10);
num2=disp[1];
write_adress_data(0x01+AdderCnt,num2);//写十秒
delay(10);
num3=disp[3];
write_adress_data(0x02+AdderCnt,num3);//写分
delay(10);
num4=disp[4];
write_adress_data(0x03+AdderCnt,num4); //写十分
delay(10);
num5=disp[6];
write_adress_data(0x04+AdderCnt,num5);//写小时
delay(10);
num6=disp[7];
write_adress_data(0x05+AdderCnt,num6); //写十小时
delay(10);
write_adress_data(0x06+AdderCnt,baochunchishu); //写保存次数
delay(10);
write_adress_data(255,AdderCnt); //写保存到现在使用的地址
delay(10);
EA=1;
}
/*****************************************************/
void init()
{
TMOD=0x01;
TH0=(65535-50000)/256;//设置定时器0为工作方式1.定时50ms.
TL0=(65535-50000)%256;
EA=1;
ET0=1;//开定时器中断
TR0=1;//启动定时器0
}
/**********************************************************************/
void dely500(void) //延时函数
{
unsigned char i;
for(i=250;i>0;i--)
_nop_();
}
/********************************************主函数******************************************************/
void main(void)
{
delay(200);
start();//IIC开始信号
delay(10);
delay(10);
AdderCnt=read_radress(255);//读 保存地址
delay(10);
baochunchishu=AdderCnt/7;//读 保存次数
EA=1; // CPU所有中断开(IE最高位MSB)
EX0=1; // INT0中断开
IT0=1; // INT0低电平触发(为1则为下降沿触发)
init();
set_rtc();
while(1)
{
key_check();//按键检测
read_rtc(); //读取时间
time_pros();//处理函数
time_pros1();//处理保存函数
display1(); //显示保存时间
KeyCheck();//按键按下显示计时时间
naozhong(); //定时闹钟
duqubaochunshu();//读取保存数
}
}
void KeyCheck()//按键按下显示计时时间
{
if(key4==0)
{
delay(5);
if(key4==0)
{
keyvalue=1;
}
while(!key4)
{
key_check();//按键检测
read_rtc();
time_pros();//处理函数
display();
naozhong(); //定时闹钟
}
}
keyvalue=0;
}
/****************************************/
void duqubaochunshu()//读取保存数
{if(key3==0)//原来的
{
delay(5);
if(key3==0)
{
while(!key3); //松手检测
delay(200);
start();//IIC开始信号
delay(10);
num15=read_radress(0x06+DuQu);//读 保存次数
delay(10);
num7=read_radress(0x05+DuQu);//读 十小时
delay(10);
num8=read_radress(0x04+DuQu);//读 小时
delay(10);
num9=read_radress(0x03+DuQu);//读 十分
delay(10);
num10=read_radress(0x02+DuQu);//读 分
delay(10);
num11=read_radress(0x01+DuQu);//读 十秒
delay(10);
num12=read_radress(0x00+DuQu);//读 秒
delay(10);
DuQu += 7;
if( DuQu > 255)
{
DuQu = 0;
}
}
}
}