專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

點(diǎn)陣萬年歷(帶時(shí)間、年月日星期調(diào)整及鬧鐘功能)C程序

作者:佚名   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2012年06月27日   【字體:

/*此程序是一款用3216點(diǎn)陣屏與DS1302芯片以及
三個(gè)按鍵與STC12C5204AD 4KROM單片機(jī)組合成的
萬年歷電子鐘具體功能如下:正常情況下上半屏
(3208)顯示主時(shí)間。當(dāng)?shù)?次按下功能鍵時(shí),下半
屏?xí)笠茲L動顯示“年、月、日、星期”,當(dāng)再
次按下時(shí),便進(jìn)入年、月、日、星期、鬧鈴等調(diào)
整模式,按加與減方便調(diào)整,附加功能,當(dāng)在左
移滾動顯示“年、月、日、星期”時(shí),按下加“+”
按鍵,便可以回到主界面,當(dāng)在響鈴時(shí),按下
“+鍵”便可以將本次響鈴關(guān)閉,當(dāng)按響鈴時(shí)下“-”
按鍵時(shí),便可以關(guān)閉鬧鈴功能,再次按下時(shí),可
以恢復(fù)鬧鈴功能*/

視頻效果祥見:http://www.tudou.com/programs/view/hQmJSwtHWWc/

完整的源代碼下載地址:http://www.torrancerestoration.com/f/dzwnl.rar

#include <reg52.h>
#define uchar unsigned char 
#define uint unsigned int
#define LINE P2//定義行線IO口,即74HC154控制端
sbit DATA1=P1^4;//74HC595數(shù)據(jù)端
sbit CLK=P1^5;//74HC595移位脈沖端
sbit CLKR=P1^6;//74HC595數(shù)據(jù)鎖存端
sbit BBT =P2^7;//蜂鳴器引腳
sbit SCLK=P1^2;//DS1302移位脈沖端
sbit DATA=P1^1;//DS1302數(shù)據(jù)端
sbit RST=P1^0;//DS1302控制端
sbit key=P3^4;//功能按鍵
sbit key1=P3^3;//加"+"按鍵
sbit key2=P3^2;//加"+"按鍵
uchar line;//行掃描變量
uchar move;//移位次數(shù)變量
uchar mov;//年月日時(shí)間左移變量,即移8次將1個(gè)字移完后加1
uchar yin;//按鍵計(jì)數(shù)器變量,一共10次,即功能按鍵有10種功能
uchar lk;//掃描兩行還是1行變量
uchar readvalue;//DS1302轉(zhuǎn)換結(jié)果變量
uchar shi,fen,nian,yue,ri,xin;//分別為:小時(shí)/分鐘/年/月/日/星期變量
uchar shin=12,fenn;//鬧鐘的小時(shí)與分鐘變量
bit dian;//主時(shí)間小數(shù)點(diǎn)位變量
bit shr,a,b,c,d,e,f,g,h,i;//按鍵對應(yīng)的10種功能位變量
bit flag;//主程序與調(diào)整時(shí)間切換變量,即進(jìn)入調(diào)整時(shí)間部分就不進(jìn)入主時(shí)間部分
bit flag1;//鬧鐘標(biāo)志位變量
bit clockbiao;//鬧鐘響鈴主標(biāo)志位
uchar BUF[19];//4組緩存數(shù)組以便動態(tài)更改數(shù)據(jù)
/******************************************************/
/**************點(diǎn)陣0-9代碼(8*6點(diǎn)陣)******************/
/******************************************************/
uchar code table[]={
0x00,0x0E,0x11,0x11,0x11,0x11,0x11,0x0E,//0
0x00,0x04,0x0C,0x04,0x04,0x04,0x04,0x0E,//1
0x00,0x0E,0x11,0x01,0x02,0x04,0x08,0x1F,//2
0x00,0x0E,0x11,0x01,0x06,0x03,0x11,0x0E,//3
0x00,0x06,0x06,0x0A,0x0A,0x12,0x1F,0x02,//4
0x00,0x1F,0x10,0x10,0x1E,0x01,0x01,0x1E,//5
0x00,0x0E,0x11,0x10,0x1E,0x11,0x11,0x0E,//6
0x00,0x1F,0x01,0x02,0x02,0x04,0x04,0x08,//7
0x00,0x0E,0x11,0x11,0x0E,0x11,0x11,0x0E,//8
0x00,0x0E,0x11,0x11,0x0F,0x01,0x01,0x1E,//9
};
/******************************************************/
/**********兩個(gè)小數(shù)黑屏及堅(jiān)線代碼8*6點(diǎn)陣)*************/
/******************************************************/
uchar code table1[]={
0x00,0x0C,0x0C,0x00,0x00,0x0C,0x0C,0x00,//為兩個(gè)小數(shù)點(diǎn)":"
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//為黑屏代碼
0x00,0x00,0x00,0x1E,0x1E,0x00,0x00,0x00//為兩堅(jiān)線"-"
};
/******************************************************/
/****此數(shù)組為74HC154譯碼器代碼(注也可以不用數(shù)組)*****/
/******************************************************/
uchar code table2[]={
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,//上半屏行代碼 0-7行
0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff//下半屏行代碼 8-15行
};
/******************************************************/
/*****************延時(shí)子程序1**************************/
/******************************************************/
void delaya(uint z)
{
 uint x;
 for(x=z;x>0;x--);   
}
/******************************************************/
/*****************延時(shí)子程序2**************************/
/******************************************************/
void delay(uint z)
{
 uint x,y;
 for(x=200;x>0;x--)
 for(y=z;y>0;y--);
}
/******************************************************/
/***************蜂鳴器響一聲子程序********************/
/******************************************************/
void bbtsoud()
{
 BBT=0;//打開蜂鳴器
 delay(50);//延時(shí)
 BBT=1;//關(guān)閉它
}
/**********************************/
//向1302寫一個(gè)字節(jié)數(shù)據(jù)//
//入口參數(shù):dat
/*********************************/
void write1302xei(uchar dat)
{
 uchar x;
 SCLK=0; delaya(2);
 for(x=0;x<8;x++)
 {
  DATA=dat&0x01;//取出最低位,從而實(shí)現(xiàn)一位位傳送
  delaya(2);
  SCLK=1;
  delaya(2);
  SCLK=0;
  dat>>=1;//等待傳送第二個(gè)字節(jié)
 }
}

/**************************************/
//根據(jù)控制字向1302寫一個(gè)字節(jié)數(shù)據(jù)//
//入口參數(shù):控制參數(shù)kong,實(shí)際參數(shù)can
/*************************************/
void write1302(uchar kong,uchar can)
{
 SCLK=0;
 RST=0;
 RST=1;
 delaya(2);
 write1302xei(kong);
 write1302xei(can);
 SCLK=1;
 RST=0;  
}
/**************************************/
//向1302讀一個(gè)字節(jié)數(shù)據(jù)//
//入口參數(shù):dat,x
/*************************************/
uchar read1302du()
{
 uchar dat,x;
 SCLK=0;
 for(x=0;x<8;x++)
 {
  dat>>=1;
  if(DATA==1)
  dat|=0x80;
  SCLK=1;
  delaya(2);
  SCLK=0;
  delaya(2); 
 }
 return dat;
}
/**************************************/
//根據(jù)控制字向1302讀一個(gè)字節(jié)數(shù)據(jù)//
//入口參數(shù):控制參數(shù)kong  實(shí)際參:dat
/*************************************/
uchar read1302(uchar kong)
{
 uchar dat;
 RST=0;
 SCLK=0;
 RST=1;
 write1302xei(kong);
 dat=read1302du();
 SCLK=1;
 RST=0;
 return dat;
}
/**************************************/
//根據(jù)控制字向1302讀一個(gè)字節(jié)數(shù)據(jù)//
//入口參數(shù):分別寫入:日期:2010-03-07 時(shí)間:23:59:54 星期天
/*************************************/
void init1302()
{
 /*以下是掉電保護(hù)函數(shù)通過判斷標(biāo)志位是否為1來判斷*/
  uchar flag;
 flag=read1302(0x81);//讀秒數(shù)據(jù)
 if(flag&0x80==1)//判斷最高位是否為1,若為1則說明芯片停止工作了,若為0則說明沒有停止
 {
 write1302(0x8e,0x00);//去掉保護(hù)
 write1302(0x80,((12/10)<<4)|(12%10));/*顯示54秒/*先將BCD碼求模得到高位,然后左移四位,
 得到了高四位,然后將BCD碼求余這樣就得到了低四位,然后相或就轉(zhuǎn)換成了二進(jìn)制代碼了*/
 write1302(0x82,((59/10)<<4)|(59%10));//顯示59分
 write1302(0x84,((23/10)<<4)|(23%10));//顯示23點(diǎn)
 write1302(0x86,((7/10)<<4)|(7%10));//顯示07日
 write1302(0x88,((3/10)<<4)|(3%10));//顯示03月
 write1302(0x8c,((10/10)<<4)|(10%10));//顯示10年
 write1302(0x8a,((7/10)<<4)|(7%10));//顯示星期天
 write1302(0x90,0xa5);//打開充電方式,選擇一個(gè)二極管2K電阻
 write1302(0x8e,0x80);//打開保護(hù)
 }

 /*以下是開機(jī)復(fù)位函數(shù)*/
 /*
 write1302(0x8e,0x00);//去掉保護(hù)
 write1302(0x80,((12/10)<<4)|(12%10));/*顯示54秒/*先將BCD碼求模得到高位,然后左移四位,
 //得到了高四位,然后將BCD碼求余這樣就得到了低四位,然后相或就轉(zhuǎn)換成了二進(jìn)制代碼了
 write1302(0x82,((59/10)<<4)|(59%10));//顯示59分
 write1302(0x84,((23/10)<<4)|(23%10));//顯示23點(diǎn)
 write1302(0x86,((7/10)<<4)|(7%10));//顯示07日
 write1302(0x88,((3/10)<<4)|(3%10));//顯示03月
 write1302(0x8c,((10/10)<<4)|(10%10));//顯示10年
 write1302(0x8a,((7/10)<<4)|(7%10));//顯示星期天
 write1302(0x90,0xa5);//打開充電方式,選擇一個(gè)二極管2K電阻
 write1302(0x8e,0x80);//打開保護(hù)
 */
}
/******************************************************/
/***************DS1302轉(zhuǎn)換結(jié)果子程序********************/
/******************************************************/
void value()
{
 readvalue=read1302(0x83);//讀入分地址
 fen=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//將分16進(jìn)制轉(zhuǎn)換成10進(jìn)制 
 readvalue=read1302(0x85);//讀入小時(shí)地址
 shi=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//將小時(shí)16進(jìn)制轉(zhuǎn)換成10進(jìn)制
 readvalue=read1302(0x87);//讀入日地址
 ri=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//將分日進(jìn)制轉(zhuǎn)換成10進(jìn)制 
 readvalue=read1302(0x89);//讀入月地址
 yue=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//將分月進(jìn)制轉(zhuǎn)換成10進(jìn)制 
 readvalue=read1302(0x8d);//讀入年地址
 nian=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//將分年進(jìn)制轉(zhuǎn)換成10進(jìn)制 
 readvalue=read1302(0x8b);//讀入星期地址
 xin=((readvalue&0x70)>>4)*10+(readvalue&0x0f);//將分星期進(jìn)制轉(zhuǎn)換成10進(jìn)制 
}
/********************************/
/**74HC595移位寄存器送數(shù)子函數(shù)***/
/********************************/
void song(uchar dat)//帶參數(shù)函數(shù)
{
 uchar num;//定義變量
 for(num=0;num<6;num++)//移動6次將數(shù)據(jù)發(fā)送完畢
 {
  dat>>=1;//將數(shù)移走一位
  DATA1=CY;//為1就將74HC595數(shù)據(jù)端置1
  CLK=0;//上升沿送走數(shù)據(jù)
  CLK=1;//高電平形成上升沿
 }
}
/******************************************************/
/***裝一線數(shù)據(jù)子函數(shù)(即一行數(shù)據(jù))主時(shí)間裝數(shù)函數(shù)********/
/******************************************************/
void yixian(uchar shi,uchar ge,uchar z)
{
 BUF[0]=table[(8*(shi/10))+line];//顯示小時(shí)十位
 BUF[1]=table[(8*(shi%10))+line];//顯示小時(shí)個(gè)位
 BUF[2]=table1[z*8+line];//顯示兩個(gè)小數(shù)點(diǎn),注意是不同的數(shù)組內(nèi)喲
 BUF[3]=table[(8*(ge/10))+line];//顯示分十位 
 BUF[4]=table[(8*(ge%10))+line];//顯示分個(gè)位
}
/******************************************************/
/***裝一線數(shù)據(jù)子函數(shù)(即一行數(shù)據(jù))顯示黑屏子程序********/
/******************************************************/
void yixianhei()
{
 uchar linee,i;
 if(line>8)//如果是顯示下半屏,就會大于8
 linee=line-8;
 else
 linee=line;//否則直接給數(shù)
 for(i=0;i<5;i++)//循環(huán)5次得到5個(gè)數(shù)組的數(shù)
 BUF[i]=table1[8+linee];//查表得到數(shù),注意是數(shù)組1中的數(shù)
}
/******************************************************/
/*******主程序顯示子程序(包括上半屏與下半屏)********/
/******************************************************/
void xianzhu(uchar nia,uchar ye,uchar rii,uchar xi)
{
 uchar temp;//左移數(shù)值變量
 char i;//有符號變量
 for(move=0;move<8;move++)//左移8次讓下半屏形成左移
 {
  for(line=0;line<8+lk;line++)//lk變量為選擇上半屏還是全屏變量,當(dāng)它等于0時(shí),只顯示上半屏?xí)r間,否則全屏顯示
  {
   if(line<8)//如果它小于8則說明lk變量為0,只讓它顯示上半屏的主時(shí)間
   {
    yixian(shi,fen,dian);//調(diào)用主時(shí)間一線數(shù)值裝載子函數(shù)
    for(i=4;i>=0;i--)
    song(~BUF[i]);//循環(huán)5次,將數(shù)組4-0的數(shù)全部發(fā)數(shù)到顯示屏上
   }
   else//如果大于16則就循環(huán)左移顯示下半屏的"年月日星期等信息"
   { 
    uchar movee;//局部變量
    movee=line-8;//line大于16,此時(shí)用它減去8就得到實(shí)際要顯示的值
    BUF[0]=table[16+movee];//顯示數(shù)字"2"字
    BUF[1]=table[movee];//顯示數(shù)字"0"字
    BUF[2]=table[(8*(nia/10))+movee];//顯示年十位
    BUF[3]=table[(8*(nia%10))+movee];//顯示年個(gè)位
    BUF[4]=table1[16+movee];//顯示橫線"-"
    BUF[5]=table[(8*(ye/10))+movee];//顯示月份十位
    BUF[6]=table[(8*(ye%10))+movee];//顯示月份個(gè)位
    BUF[7]=table1[16+movee];//顯示橫線"-"
    BUF[8]=table[(8*(rii/10))+movee];//顯示日十位 
    BUF[9]=table[(8*(rii%10))+movee];//顯示日個(gè)位
    BUF[10]=table1[16+movee];//顯示橫線"-"
    BUF[11]=table[(8*(xi%10))+movee];//顯示星期幾
    for(i=4;i>=0;i--)//循環(huán)5次將數(shù)發(fā)送給下半屏
    {
     temp=((BUF[i+mov]<<move)|(BUF[(i+1)+mov]>>(6-move)));//將左半屏數(shù)左移x位,然后將右
     //半屏數(shù)右移6-x位,然后或一下就得到在左移了,此句是左移關(guān)鍵!
     song(~temp);//送數(shù)出去
    }
    delaya(1000);//延時(shí)一下
   }
   LINE=table2[line];//打開行線,即174HC154行線端
   CLKR=1;//在74HC595處鎖存起來
   CLKR=0;
   CLKR=1;
   delaya(800);//延時(shí)一下
  }
 
 }
  mov++;//顯示完一屏后,將移1個(gè)字變量加1,這樣就完成下一字顯示。原理是:顯示下一個(gè)數(shù)組
  if(mov>13)//移完14次,就將它清0。原因是,程序全部定了19個(gè)數(shù)組,前面顯示數(shù)用了5個(gè)加現(xiàn)在14次,剛好19個(gè)數(shù)組
  mov=0;//清0,重新開始顯示
}
/******************************************************/
/**********閃爍間斷顯示子程序(包括下半屏)************/
/******************************************************/
void xianshan()
{
 char ii;//有符號變量
 for(line=0;line<8;line++)//掃描8次,即完成一個(gè)字的移動
 {
  if(flag1==0)//如果標(biāo)志位為0,則以0.5秒速度顯示時(shí)分鐘主界面
  yixian(shi,fen,dian);//調(diào)用時(shí)分秒主界面子程序
  if(flag1==1)//如果標(biāo)志位為1,則以0.5秒速度顯示黑屏界面,形成閃爍效果
  yixianhei();//調(diào)用黑屏子程序
  for(ii=4;ii>=0;ii--)//循環(huán)5次將數(shù)發(fā)往顯示屏
  song(~BUF[ii]);//送數(shù)
  LINE=table2[line];//打開行線,即174HC154行線端
  CLKR=1;//在74HC595處鎖存起來
  CLKR=0;
  CLKR=1;
  delaya(800);
 }  
}
/******************************************************/
/**********年調(diào)整界面顯示子程序(包括下半屏)************/
/******************************************************/
void xiannian(uchar nia)//變量年
{
 uchar movee;
 char ii;
 for(line=8;line<16;line++)//掃描8次,即完成一個(gè)字的移動,line等于8,表示在下半屏顯示
 {
  if(flag1==0)//如果標(biāo)志位為1,則執(zhí)行顯示部分
  {
   movee=line-8;
   BUF[0]=table[16+movee];//顯示數(shù)字2
   BUF[1]=table[movee];//顯示數(shù)字0
   BUF[2]=table[(8*(nia/10))+movee];//顯示年十位
   BUF[3]=table[(8*(nia%10))+movee];
   BUF[4]=table1[16+movee];//顯示橫線
  }
  if(flag1==1)
  yixianhei();//否則顯示黑屏
  for(ii=4;ii>=0;ii--)//循環(huán)5次將數(shù)發(fā)往顯示屏
  song(~BUF[ii]);//送數(shù)
  LINE=table2[line];//打開行線,即174HC154行線端
  CLKR=1;//在74HC595處鎖存起來
  CLKR=0;
  CLKR=1;
  delaya(800);
 }  
}
/******************************************************/
/*********月/日調(diào)整界面顯示子程序(包括下半屏)********/
/******************************************************/
void xianriyue(uchar ye,uchar rii)//月與日變量
{
 uchar movee;
 char ii;
 for(line=8;line<16;line++)//掃描8次,即完成一個(gè)字的移動,line等于8,表示在下半屏顯示
 {
  if(flag1==0)//同上如果為0就顯示,為1就黑屏,形成閃爍
  {
   movee=line-8;
   BUF[0]=table[(8*(ye/10))+movee];//顯示月十位
   BUF[1]=table[(8*(ye%10))+movee];//月個(gè)位
   BUF[2]=table1[16+movee];//顯示橫線
   BUF[3]=table[(8*(rii/10))+movee];//顯示日十位 
   BUF[4]=table[(8*(rii%10))+movee];//顯示橫線
  }
  if(flag1==1)//為1就黑屏顯示
  yixianhei();
  for(ii=4;ii>=0;ii--)//循環(huán)5次將數(shù)發(fā)往顯示屏
  song(~BUF[ii]);//送數(shù)
  LINE=table2[line];//打開行線,即174HC154行線端
  CLKR=1;//在74HC595處鎖存起來
  CLKR=0;
  CLKR=1;
  delaya(800);
 }  
}
/******************************************************/
/*********星期調(diào)整界面顯示子程序(包括下半屏)********/
/******************************************************/
void xi(uchar xi)
{
 uchar movee;
 char ii;
 for(line=8;line<16;line++)//掃描8次,即完成一個(gè)字的移動,line等于8,表示在下半屏顯示
 {
  if(flag1==0)//0.5秒顯示
  {
   movee=line-8;
   BUF[0]=table1[16+movee];//顯示橫線"-"
   BUF[1]=table1[16+movee];//顯示橫線"-"
   BUF[2]=table[(8*(xi%10))+movee];//顯示出星期個(gè)位
   BUF[3]=table1[16+movee];//顯示橫線"-"
   BUF[4]=table1[16+movee];//顯示橫線"-"
  }
  if(flag1==1)
  yixianhei();
  for(ii=4;ii>=0;ii--)//循環(huán)5次將數(shù)發(fā)往顯示屏
  song(~BUF[ii]);//送數(shù)
  LINE=table2[line];//打開行線,即174HC154行線端
  CLKR=1;//在74HC595處鎖存起來
  CLKR=0;
  CLKR=1;
  delaya(800);
 }  
}
/******************************************************/
/***************鬧鐘時(shí)間調(diào)整顯示子程序*****************/
/******************************************************/
void xianniao(uchar shi,uchar ge,uchar z)
{
 char ii;
 for(line=0;line<8;line++)//掃描8次,即完成一個(gè)字的移動
 {
  if(flag1==0)//同樣0.5秒顯示時(shí)間
  {
   BUF[0]=table[(8*(shi/10))+line];//顯示小時(shí)十位
   BUF[1]=table[(8*(shi%10))+line];
   BUF[2]=table1[z*8+line];//顯示橫線
   BUF[3]=table[(8*(ge/10))+line]; //顯示分鐘十位
   BUF[4]=table[(8*(ge%10))+line];
  }
  if(flag1==1)//同樣0.5秒顯示黑屏
  yixianhei();
  for(ii=4;ii>=0;ii--)//循環(huán)5次將數(shù)發(fā)往顯示屏
  song(~BUF[ii]);//送數(shù)
  LINE=table2[line];//打開行線,即174HC154行線端
  CLKR=1;//在74HC595處鎖存起來
  CLKR=0;
  CLKR=1;
  delaya(800);
 }  
}
/******************************************************/
/***************按鍵按下后處理子程序*******************/
/******************************************************/
void skey()
{
 if(shr!=0)//如果標(biāo)志位shr不為0,則執(zhí)行以下內(nèi)容------如果按下了加按鍵則程序復(fù)位
 {
  if(key1==0)
  {
   delay(10);
   if(key1==0)//如果加按鍵按下了,則全部復(fù)位
   {
    yin=0;//將按鍵計(jì)數(shù)器清0
    shr=0;//標(biāo)志位清0
    lk=0;//顯示上半屏,此變量是全屏與半屏控制變量,當(dāng)它為8時(shí),就執(zhí)行全屏,否則半屏
    clockbiao=~clockbiao;
    bbtsoud();//蜂鳴器響一聲子程序
    while(!key1);//按鍵釋放
   }   
  }
 }
 if(a!=0)//如果標(biāo)志位不為0,則執(zhí)行以下內(nèi)容-------閃爍進(jìn)入調(diào)整模式
 xianshan(); //閃爍 
 if(b!=0)//如果標(biāo)志位不為0,則執(zhí)行以下內(nèi)容,進(jìn)行主時(shí)間小時(shí)調(diào)整
 {
  xianshan();//調(diào)用主時(shí)間顯示子程序
  if(key1==0)
  {
   delay(10);
   if(key1==0)
   {
    xianshan();
    shi++;
    if(shi==24)//小時(shí)等于24?
    shi=0;//清0
    write1302(0x8e,0x00);//去掉保護(hù)
    write1302(0x84,((shi/10)<<4)|(shi%10));//時(shí)數(shù)據(jù)寫入
    write1302(0x8e,0x80);//打開保護(hù) 
    readvalue=read1302(0x85);
    shi=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//將小時(shí)轉(zhuǎn)換出來
    while(!key1);
   }   
  }
  if(key2==0)//以下是處理主時(shí)間小時(shí)減部分
  {
   delay(10);
   if(key2==0)
   {
    shi--;
    if(shi==(0-1))
    shi=23;
    write1302(0x8e,0x00);//去掉保護(hù)
    write1302(0x84,((shi/10)<<4)|(shi%10));//時(shí)數(shù)據(jù)寫入
    write1302(0x8e,0x80);//打開保護(hù) 
    readvalue=read1302(0x85);
    shi=((readvalue&0xf0)>>4)*10+(readvalue&0x0f); 
    while(!key2);
   }   
  }
 }
 if(c!=0)//如果標(biāo)志位不為0,則執(zhí)行以下內(nèi)容------以下是處理主時(shí)間分鐘調(diào)整部分
 {
  xianshan(); 
  if(key1==0)//加分鐘部分
  {
   delay(10);
   if(key1==0)
   {
    xianshan();//調(diào)用主時(shí)間顯示子程序
    fen++;
    if(fen==60)
    fen=00;
    write1302(0x8e,0x00);//去掉保護(hù)
    write1302(0x82,((fen/10)<<4)|(fen%10));//分?jǐn)?shù)據(jù)寫入
    write1302(0x8e,0x80);//打開保護(hù)
    readvalue=read1302(0x83);
    fen=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//將它轉(zhuǎn)換出來
    while(!key1);
   }
  }
  if(key2==0)//減分鐘部分
  {
   delay(10);
   if(key2==0)
   {
    xianshan(); 
    fen--;
    if(fen==(0-1))
    fen=59;
    write1302(0x8e,0x00);//去掉保護(hù)
    write1302(0x82,((fen/10)<<4)|(fen%10));//分?jǐn)?shù)據(jù)寫入
    write1302(0x8e,0x80);//打開保護(hù)
    readvalue=read1302(0x83);
    fen=((readvalue&0xf0)>>4)*10+(readvalue&0x0f); 
    while(!key2);
   }
  
  }
 }
 if(d!=0)//如果標(biāo)志位不為0,則執(zhí)行以下內(nèi)容-----調(diào)整年
 {
  xiannian(nian);//調(diào)用年顯示子程序
  if(key1==0)//年時(shí)間加部分處理
  {
   delay(10);
   if(key1==0)
   {
    xiannian(nian);
    nian++;
    if(nian==99)//年到了99嗎?
    nian=0;
    write1302(0x8e,0x00);//去掉保護(hù)
    write1302(0x8c,((nian/10)<<4)|(nian%10));//年數(shù)據(jù)寫入
    write1302(0x8e,0x80);//打開保護(hù)
    readvalue=read1302(0x8d);
    nian=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//年數(shù)據(jù)轉(zhuǎn)換
    while(!key1);
   }
  }
  if(key2==0)//年時(shí)間減部分處理
  {
   delay(10);
   if(key2==0)
   {
    xiannian(nian); 
    nian--;
    if(nian==(0-1))
    nian=99;
    write1302(0x8e,0x00);//去掉保護(hù)
    write1302(0x8c,((nian/10)<<4)|(nian%10));//年數(shù)據(jù)寫入
    write1302(0x8e,0x80);//打開保護(hù)
    readvalue=read1302(0x8d);
    nian=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//年數(shù)據(jù)轉(zhuǎn)換 
    while(!key2);
   }
  
  }
 }
 if(e!=0)//如果標(biāo)志位不為0,則執(zhí)行以下內(nèi)容-----處理月
 {
  xianriyue(yue,ri);
  if(key1==0)//月加部分處理
  {
   delay(10);
   if(key1==0)
   {
    xianriyue(yue,ri);
    yue++;
    if(yue==13)
    yue=1;
    write1302(0x8e,0x00);//去掉保護(hù)
    write1302(0x88,((yue/10)<<4)|(yue%10));//月數(shù)據(jù)寫入
    write1302(0x8e,0x80);//打開保護(hù)
    readvalue=read1302(0x89);
    yue=((readvalue&0xf0)>>4)*10+(readvalue&0x0f); 
    while(!key1);
   }
  }
  if(key2==0)//月減部分處理
  {
   delay(10);
   if(key2==0)
   {
    xianriyue(yue,ri);
    yue--;
    if(yue==(1-1))
    yue=12;
    write1302(0x8e,0x00);//去掉保護(hù)
    write1302(0x88,((yue/10)<<4)|(yue%10));//月數(shù)據(jù)寫入
    write1302(0x8e,0x80);//打開保護(hù)
    readvalue=read1302(0x89);
    yue=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//月轉(zhuǎn)換
    while(!key2);
   }
  
  }
 }
 if(f!=0)//如果標(biāo)志位不為0,則執(zhí)行以下內(nèi)容-------調(diào)整日
 {
  xianriyue(yue,ri);
  if(key1==0)//加日部分
  {
   delay(10);
   if(key1==0)
   {
    xianriyue(yue,ri);
    ri++;
    if(ri==32)
    ri=1;
    write1302(0x8e,0x00);//去掉保護(hù)
    write1302(0x86,((ri/10)<<4)|(ri%10));//日數(shù)據(jù)寫入
    write1302(0x8e,0x80);//打開保護(hù)
    readvalue=read1302(0x87);
    ri=((readvalue&0xf0)>>4)*10+(readvalue&0x0f); 
    while(!key1);
   }
  }
  if(key2==0)//減日部分
  {
   delay(10);
   if(key2==0)
   {
    xianriyue(yue,ri);
    ri--;
    if(ri==(1-1))
    ri=31;
    write1302(0x8e,0x00);//去掉保護(hù)
    write1302(0x86,((ri/10)<<4)|(ri%10));//日數(shù)據(jù)寫入
    write1302(0x8e,0x80);//打開保護(hù) 
    readvalue=read1302(0x87);
    ri=((readvalue&0xf0)>>4)*10+(readvalue&0x0f); 
    while(!key2);
   }
  
  }
 }
 if(g!=0)//如果標(biāo)志位不為0,則執(zhí)行以下內(nèi)容-----星期調(diào)整部分
 {
  xi(xin);
  if(key1==0)//星期加部分
  {
   delay(10);
   if(key1==0)
   {
    xi(xin);
    xin++;//將星期+1
    if(xin==8)//如果星期到了8就清它清1
    xin=1;//清1
    write1302(0x8e,0x00);//去掉保護(hù)
    write1302(0x8a,((xin/10)<<4)|(xin%10));//顯示星期天
    write1302(0x8e,0x80);//打開保護(hù)
    readvalue=read1302(0x8b);//讀星期
    xin=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//將星期值還原 
    while(!key1);
   }
  }
  if(key2==0)//星期減部分
  {
   delay(10);
   if(key2==0)
   {
    xi(xin);
    xin--;//減1 
    if(xin==(1-1))//如果到了(1-1)就給它7,因?yàn)樾瞧谥?---7
    xin=7;//將它給7
    write1302(0x8e,0x00);//去掉保護(hù)
    write1302(0x8a,((xin/10)<<4)|(xin%10));//顯示星期天
    write1302(0x8e,0x80);//打開保護(hù)
    readvalue=read1302(0x8b);
    xin=((readvalue&0xf0)>>4)*10+(readvalue&0x0f);//讀星期值  
    while(!key2);
   }
  
  }
 }
 if(h!=0)////如果標(biāo)志位不為0,則執(zhí)行以下內(nèi)容------------以下是鬧鐘小時(shí)調(diào)整部分
 {
  xianniao(shin,fenn,2);//調(diào)整鬧鐘小時(shí)與分鐘顯示子程序
  if(key1==0)//鬧鐘小時(shí)加處理
  {
   delay(10);
   if(key1==0)
   {
    xianniao(shin,fenn,2);
    shin++;//將星期+1
    if(shin==24)//如果星期到了8就清它清1
    shin=0;//清1
    while(!key1);
   }
  }
  if(key2==0)//鬧鐘小時(shí)減處理
  {
   delay(10);
   if(key2==0)
   {
    xianniao(shin,fenn,2);
    shin--;
    if(shin==(0-1))
    shin=23;  
    while(!key2);
   }
  
  }
 } 
 if(i!=0)//如果標(biāo)志位不為0,則執(zhí)行以下內(nèi)容----------鬧鐘分鐘調(diào)整
 {
  xianniao(shin,fenn,2);
  if(key1==0)//鬧鐘分鐘加處理
  {
   delay(10);
   if(key1==0)
   {
    xianniao(shin,fenn,2);
    fenn++;//將星期+1
    if(fenn==60)//如果星期到了8就清它清1
    fenn=0;//清1
    while(!key1);
   }
  }
  if(key2==0)//鬧鐘分鐘減處理
  {
   delay(10);
   if(key2==0)
   {
    xianniao(shin,fenn,2);
    fenn--;
    if(fenn==(0-1))
    fenn=59;  
    while(!key2);
   }
  
  }
 } 
}
/******************************************************/
/*******************響鬧子程序*************************/
/******************************************************/
void xiangniao()
{
 bit clock;//定義一個(gè)標(biāo)志位
 if(clockbiao==0)//鬧鐘總標(biāo)志為0時(shí)才可以執(zhí)行鬧鐘處理程序
 {
  if(clock==0)//如果標(biāo)志位為0,就執(zhí)行下面內(nèi)容
  {
   if(shin==shi)//主時(shí)間小時(shí)與鬧鐘小時(shí)相等嗎?
   {
    if(fenn==fen)//主時(shí)間分鐘與鬧鐘分鐘相等嗎?
    bbtsoud();//相等了就執(zhí)行鬧鐘響一聲子程序,即小時(shí)與分鐘都相等了就執(zhí)行鬧鈴
   }
  }
  if(fenn!=fen)//如果分鐘不等
  clock=0;//將標(biāo)志位清0,以便下次再響鈴
  if(key1==0)//判斷加"+"按鍵有沒有被按下,如果按下了,就讓鬧鈴?fù)V鬼?br />   {
   delay(10);
   if(key1==0)
   {
    clock=1;//將標(biāo)志位清0,讓鬧鐘在響鈴時(shí)立馬停下來
    while(!key1);
   }
  }
 }
 if(key2==0)//如果減按鍵按下了,則則關(guān)閉鬧鈴全部功能
 {
  delay(10);
  if(key2==0)//如果加按鍵按下了,則全部復(fù)位
  {
   clockbiao=~clockbiao;
   bbtsoud();//蜂鳴器響一聲子程序
   while(!key2);//按鍵釋放
  }   
 }   

/******************************************************/
/******************************************************/
/**********主程序(包括主顯示/鬧鐘/按鍵處理)************/
/******************************************************/
/******************************************************/ 
void main()
{
 init1302();
 TMOD=0X11;//寄存器工作方式
 EA=1;//開總中斷
 TR0=1;//開定時(shí)器
 ET0=1;//開定時(shí)器中斷
 TH0=(65536-20000)/256;//賦值給高位
 TL0=(65536-20000)%256;//賦值給低位
 TR1=1;//開定時(shí)器
 ET1=1;//開定時(shí)器中斷
 TH1=(65536-50000)/256;//賦值給高位
 TL1=(65536-50000)%256;//賦值給低位
 while(1)
 {
  if(flag==0)//如果標(biāo)志位為0,就讓它執(zhí)行主程序,不讓它讀按鍵處理部分,省資源
  {
   value();//調(diào)用DS1302時(shí)間轉(zhuǎn)換子程序
   xianzhu(nian,yue,ri,xin);//調(diào)用主顯示
   xiangniao();//調(diào)用響鬧子程序
  }
  skey();//調(diào)用按鍵處理子程序
 } 
}
/******************************************************/
/*******************定時(shí)中斷0子程序********************/
/******************************************************/
void zhong() interrupt 3
{
 uchar ding;
 TH1=(65536-50000)/256;
 TL1=(65536-50000)%256;
 ding++;
 if(ding>=10)//模擬普通鬧鐘小數(shù)閃爍處理部分
 {
  ding=0;
  dian=~dian;//0.5秒閃一次,它不參與具體計(jì)時(shí),具體計(jì)時(shí)只是DS1302內(nèi)部
 }
}
/******************************************************/
/*******************定時(shí)中斷1子程序********************/
/******************************************************/
void zhong1() interrupt 1//T1中斷服務(wù)程序
{  
 uchar ding1,ding2;
 TH0=(65536-10000)/256;//賦值給高位
 TL0=(65536-10000)%256;//賦值給低位
 ding1++;
 ding2++;
 if(ding2>=50)//進(jìn)入調(diào)整模式時(shí)閃爍標(biāo)志位處理
 {
  ding2=0;
  flag1=~flag1;
 }
 switch(yin)//以下是主功能按鍵處理子程序
 {
  case 0:if(ding1>=250)//長按功能按鍵進(jìn)入調(diào)整模式,否則怕誤按-------------進(jìn)入查看年月日功能
  {
   ding1=0;//將定時(shí)器清0
   if(key==0)
   {
    delay(100);
    if(key==0)
    {
     yin++;//將標(biāo)志位加1
     lk=8;//些句是調(diào)用"年月日星期"顯示的關(guān)鍵一步,即打開下屏顯示
     shr=1;//將標(biāo)志位置1
     bbtsoud();//蜂鳴器響一聲
     while(!key);//按鍵釋放
    }
   }
  }
  break;
  case 1:if(key==0)//-----------------------------進(jìn)入調(diào)整模式閃爍功能
  {
   delay(100);
   if(key==0)
   {
    yin++;//以便進(jìn)入一個(gè)功能
    a=1;//標(biāo)志位置1,以便進(jìn)入按鍵功能
    shr=0;//將上次標(biāo)志位清0,以免與現(xiàn)在的鍵值產(chǎn)生沖突
    lk=0;//將下半屏清掉
    flag=1;//將主程序中的標(biāo)志位置1
    bbtsoud();//蜂鳴器響一聲
    TR1=0;//將定時(shí)器關(guān)掉
    dian=0;//將主時(shí)間中的兩位小數(shù)點(diǎn)標(biāo)志位打開
    write1302(0x8e,0x00);//去掉DS1302保護(hù)
    write1302(0x80,0x80);//當(dāng)它等于0X80時(shí),讓DS1302時(shí)間停下來,以便調(diào)整
    write1302(0x8e,0x80);//讓DS1302保護(hù)
    while(!key);
   } 
  }
  break;
  case 2: if(key==0)//-----------------------------進(jìn)入主時(shí)間小時(shí)調(diào)整功能
  {
   delay(100);
   if(key==0)
   {
    yin++;//以下便進(jìn)行下一功能
    b=1;//標(biāo)志位置1
    a=0;
    bbtsoud();
    while(!key);
   } 
  }
  break;
  case 3: if(key==0)//---------------------------進(jìn)入主時(shí)間分鐘時(shí)調(diào)整功能
  {
   delay(100);
   if(key==0)
   {
    yin++;
    b=0;
    c=1;
    bbtsoud();
    while(!key);
   }
  }
  break;
  case 4: if(key==0)//---------------------------------進(jìn)入日期年調(diào)整功能
  {
   delay(100);
   if(key==0)
   {
    yin++;
    c=0;
    d=1;
    bbtsoud();
    while(!key);
   }
  }
  break; 
  case 5:if(key==0)//-----------------------------------進(jìn)入日期月調(diào)整功能
  {
   delay(100);
   if(key==0)
   {
    yin++;
    d=0;
    e=1;
    bbtsoud();
    while(!key);
   } 
  }
  break;
  case 6: if(key==0)//-----------------------------------進(jìn)入日期日調(diào)整功能
  {
   delay(100);
   if(key==0)
   {
    yin++;
    e=0;
    f=1;
    bbtsoud();
    while(!key);
   } 
  }
  break;
  case 7:if(key==0)//---------------------------------進(jìn)入日期星期調(diào)整功能
  {
   delay(100);
   if(key==0)
   {
    yin++;
    f=0;
    g=1;
    bbtsoud();
    while(!key);
   }
  }
  break;
  case 8: if(key==0)//------------------------------進(jìn)入鬧鐘小時(shí)調(diào)整功能
  {
   delay(100);
   if(key==0)
   {
    yin++;
    g=0;
    h=1;
    bbtsoud();
    while(!key);
   }
  }
  break; 
  case 9:if(key==0)//------------------------------進(jìn)入鬧鐘分鐘調(diào)整功能
  {
   delay(100);
   if(key==0)
   {
    yin++;
    h=0;
    i=1;
    bbtsoud();
    while(!key);
   } 
  }
  break;
  case 10:if(key==0)//----------------------將系統(tǒng)全部復(fù)位,即回到主程序
  {
   delay(100);
   if(key==0)
   {
    yin=0;//總計(jì)數(shù)器復(fù)位為0
    i=0;//上次功能標(biāo)志位清0
    flag=0;//主程序標(biāo)志位清0
    TR1=1;//打開定時(shí)器
    write1302(0x8e,0x00);//去掉DS1302保護(hù)
    write1302(0x80,0x00);//當(dāng)它等于0X00時(shí),讓時(shí)間就開始走 即0X00就讓時(shí)間開始走,0X80讓時(shí)停
    write1302(0x8e,0x80);//讓時(shí)間停下來
    bbtsoud();
    while(!key);
   } 
  }
  break;
 }
}  

關(guān)閉窗口

相關(guān)文章