#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;
}
}
}
}