|
- #include<reg51.h>
- #include<intrins.h>
- typedef unsigned char uchar;
- typedef unsigned int uint;
- sbit T_CLK=P1^2;
- sbit T_IO=P1^1;
- sbit T_RST=P1^0;
- sbit ACC0=ACC^0;
- sbit ACC7=ACC^7;
- sbit W1=P2^0;
- sbit W2=P2^1;
- sbit W3=P2^3;
- sbit W4=P2^4;
- sbit W5=P2^6;
- sbit W6=P2^7;
- sbit p22=P2^2;
- sbit p25=P2^5;
- uchar code table1[]={ //共陰數(shù)碼管
- 63,6,91,79,102,
- 109,125,7,127,
- 111,119,124,57,
- 94,121,113,118,
- 56,115,49,62,
- 110,64,128,0
- };
- #define sec 128//1302秒寄存器地址
- #define min 130//1302分寄存器地址
- #define hou 132//1302時寄存器地址
- #define read 1//讀操作,因?yàn)樽x的時候地址要加1,使最低位為1
- sbit SET=P3^5;
- sbit UP=P3^6;
- sbit DOWN=P3^7;
- //函數(shù)聲明
- void display();
- void Scan_Key();
- void id_case1_key();
- void Set_id(uchar,uchar);
- //變量定義
- uchar id=0,timecount,re_disp=0;//定義用到的變量,id為調(diào)整模式用,不為0時表示調(diào)整模式,調(diào)整哪個量由id值確定 //timecount用于500ms定時記數(shù),時間到取反flag標(biāo)志位,re_disp記數(shù)200次共10s,調(diào)整狀態(tài)下按鍵無操作10s自動返回正常顯示狀態(tài)
- bit hour,minute,second,flag; //定義位變量,hour,minute,second分別為調(diào)整時閃爍標(biāo)志位,flag 500ms取反一次,調(diào)整位閃爍及冒號閃爍用
- uchar inittime[7]={0,0,18,22,17,6,4}; //初始化1302時用到的初始化數(shù)據(jù)
- //秒 分鐘 小時 日 月 年 星期
- //DS1302讀寫程序
- /********************************************************************
- 函 數(shù)名:RTInputByte()
- 功 能:實(shí)時時鐘寫入一字節(jié)
- 說 明:往DS1302寫入1Byte數(shù)據(jù) (內(nèi)部函數(shù))
- 入口參數(shù):d 寫入的數(shù)據(jù)
- 返 回值:無
- ***********************************************************************/
- void RTInputByte(uchar d)
- {
- uchar i;
- ACC=d;
- for(i=8;i>0;i--)
- {
- T_IO=ACC0; //相當(dāng)于匯編中的 RRC
- T_CLK=1;
- T_CLK=0;
- ACC=ACC>>1;
- }
- }
- /********************************************************************
- 函 數(shù)名:RTOutputByte()
- 功 能:實(shí)時時鐘讀取一字節(jié)
- 說 明:從DS1302讀取1Byte數(shù)據(jù) (內(nèi)部函數(shù))
- 入口參數(shù):無
- 返 回值:ACC
- 設(shè) 計:欣輝電子 日 期:2015-01-01
- 修 改: 日 期:
- ***********************************************************************/
- uchar RTOutputByte()
- {
- uchar i;
- for(i=8;i>0;i--)
- {
- ACC=ACC>>1; //相當(dāng)于匯編中的 RRC
- ACC7=T_IO;
- T_CLK=1;
- T_CLK=0;
- }
- return(ACC);
- }
- /********************************************************************
- 函 數(shù)名:Write1302()
- 功 能:往DS1302寫入數(shù)據(jù)
- 說 明:先寫地址,后寫命令/數(shù)據(jù) (內(nèi)部函數(shù))
- 調(diào) 用:RTInputByte() , RTOutputByte()
- 入口參數(shù):ucAddr:DS1302地址, ucData: 要寫的數(shù)據(jù)
- 返 回值:無
- ***********************************************************************/
- void Write1302(uchar ucAddr,uchar ucDa)
- {
- T_RST=0;
- T_CLK=0;
- T_RST=1;
- RTInputByte(ucAddr); // 地址,命令
- RTInputByte(ucDa); // 寫1Byte數(shù)據(jù)
- T_CLK=1;
- T_RST=0;
- }
- /********************************************************************
- 函 數(shù)名:Read1302()
- 功 能:讀取DS1302某地址的數(shù)據(jù)
- 說 明:先寫地址,后讀命令/數(shù)據(jù) (內(nèi)部函數(shù))
- 調(diào) 用:RTInputByte() , RTOutputByte()
- 入口參數(shù):ucAddr:DS1302地址
- 返 回值:ucData :讀取的數(shù)據(jù)
- ***********************************************************************/
- uchar Read1302(uchar ucAddr)
- {
- uchar ucData;
- T_RST=0;
- T_CLK=0;
- T_RST=1;
- RTInputByte(ucAddr); // 地址,命令
- ucData=RTOutputByte(); // 讀1Byte數(shù)據(jù)
- T_CLK=1;
- T_RST=0;
- return(ucData);
- }
- /********************************************************************
- 函 數(shù)名:Set1302()
- 功 能:設(shè)置初始時間
- 說 明:先寫地址,后讀命令/數(shù)據(jù)(寄存器多字節(jié)方式)
- 調(diào) 用:Write1302()
- 入口參數(shù):pClock: 設(shè)置時鐘數(shù)據(jù)地址 格式為: 秒 分時 日 月 星期 年
- 7Byte (BCD碼)1B 1B 1B 1B 1B 1B 1B
- 返 回值:無
- ***********************************************************************/
- void Set1302(uchar *pClock)
- {
- uchar i;
- uchar ucAddr=128;
- Write1302(142,0); // 控制命令,WP=0,寫操作
- for(i=7;i>0;i--)
- {
- Write1302(ucAddr,*pClock); // 秒分 時 日 月 星期 年
- pClock++;
- ucAddr+=2;
- }
- Write1302(142,128); // 控制命令,WP=1,寫保護(hù)
- }
- void delay(uint z)
- {
- uintx,y;
- for(x=z;x>0;x--)
- for(y=110;y>0;y--);
- }
- void display() //顯示函數(shù)
- {
- if(flag&hour) //如hour為1表示調(diào)整時,flag為1時不顯示
- {
- P0=(0); //再傳段碼
- W1=0;
- delay(1); //延遲時間2ms以內(nèi)
- W1=1;
- P0=(0&~((uchar)~flag<<8)); //再傳段碼
- W2=0;
- delay(1); //延遲時間2ms以內(nèi)
- W2=1;
- }
- else //flag為0時顯示,產(chǎn)生閃爍效果,下同
- {
- P0=(table1[Read1302(hou|read)/16]); //再傳段碼
- W1=0;
- delay(1); //延遲時間2ms以內(nèi)
- W1=1;
- P0=(table1[Read1302(hou|read)%16]&~((uchar)~flag<<8)); //再傳段碼
- W2=0;
- delay(1); //延遲時間2ms以內(nèi)
- W2=1;
- }
- P0=64; //再傳段碼
- p22=0;
- delay(1); //延遲時間2ms以內(nèi)
- p22=1;
- if(flag&minute)
- {
- P0=(0&~((uchar)~flag<<8)); //再傳段碼
- W3=0;
- delay(1); //延遲時間2ms以內(nèi)
- W3=1;
- P0=(0&~((uchar)~flag<<8)); //再傳段碼
- W4=0;
- delay(1); //延遲時間2ms以內(nèi)
- W4=1;
- }
- else
- {
- P0=(table1[Read1302(min|read)/16]&~((uchar)~flag<<8)); //再傳段碼
- W3=0;
- delay(1); //延遲時間2ms以內(nèi)
- W3=1;
- P0=(table1[Read1302(min|read)%16]&~((uchar)~flag<<8)); //再傳段碼
- W4=0;
- delay(1); //延遲時間2ms以內(nèi)
- W4=1;
- }
- P0=64; //再傳段碼
- p25=0;
- delay(1); //延遲時間2ms以內(nèi)
- p25=1;
- if(flag&second)
- {
- P0=(0&~((uchar)~flag<<8)); //再傳段碼
- W5=0;
- delay(1); //延遲時間2ms以內(nèi)
- W5=1;
- P0=(0); //再傳段碼
- W6=0;
- delay(1); //延遲時間2ms以內(nèi)
- W6=1;
- }
- else
- {
- P0=(table1[Read1302(sec|read)/16]&~((uchar)~flag<<8)); //再傳段碼
- W5=0;
- delay(1); //延遲時間2ms以內(nèi)
- W5=1;
- P0=(table1[Read1302(sec|read)%16]); //再傳段碼
- W6=0;
- delay(1); //延遲時間2ms以內(nèi)
- W6=1;
- }
- }
- void Scan_Key() //鍵盤檢測函數(shù)
- {
- display(); //程序開頭調(diào)用顯示函數(shù)
- if(!SET)
- {
- while(!SET)
- display(); //等待按鍵釋放,如一直按下一直調(diào)用顯示函數(shù),防止顯示中斷
- re_disp=0; //清除記數(shù),重新開始10s定時
- id++;
- if(id>3)
- id=0; //id加1,后面根據(jù)id值對應(yīng)調(diào)整項(xiàng)目
- }
- if(id==0)
- {
- hour=0;
- minute=0;
- second=0;
- } //根據(jù)id值跳到相應(yīng)處理函數(shù)
- if(id==1)
- {
- hour=1;
- id_case1_key();
- } //id為1,選擇調(diào)整小時位,閃爍標(biāo)志位置1,然后跳到鍵盤處理函數(shù),下同
- if(id==2)
- {
- hour=0;
- minute=1;
- id_case1_key();
- }
- if(id==3)
- {
- minute=0;
- second=1;
- id_case1_key();
- }
- }
- void id_case1_key() //鍵盤處理函數(shù),只有按下set鍵時才會進(jìn)入,
- {
- display();
- if(!DOWN) //減少
- {
- while(!DOWN)
- display(); //等待按鍵釋放,如一直按下一直調(diào)用顯示函數(shù),防止顯示中斷
- re_disp=0; //清除記數(shù),重新開始10s定時
- Set_id(id,0); //跳到加減判斷函數(shù),下同,
- }
- if(!UP) //增加
- {
- while(!UP)
- display();
- re_disp=0;
- Set_id(id,1);
- }
- }
- //根據(jù)選擇調(diào)整相應(yīng)項(xiàng)目并寫入DS1302
- void Set_id(uchar sel,uchar sel_1) //執(zhí)行調(diào)整項(xiàng)目的函數(shù)
- {
- signed char max,mini,address,item;
- if(sel==1)
- {
- address=hou;
- max=23;
- mini=0;
- } //小時 //根據(jù)id值確定要調(diào)整的項(xiàng),并確定調(diào)整上下限,下同
- if(sel==2)
- {
- address=min;
- max=59;
- mini=0;
- } //分鐘
- if(sel==3)
- {
- address=sec;
- max=0;
- mini=0;
- } //秒
- item=Read1302(address|read)/16*10+Read1302(address|read)%16; //從相應(yīng)的地址讀取當(dāng)前數(shù)據(jù)并轉(zhuǎn)換為十進(jìn)制
- if(sel_1==0)
- item--;
- else
- item++; //確定是對項(xiàng)目加還是減,并對越限處理
- if(item>max)
- item=mini;
- if(item<mini)
- item=max;
- Write1302(142,0);//允許寫操作
- Write1302(address,item/10*16+item%10); //將調(diào)整結(jié)果轉(zhuǎn)換成壓縮BCD碼重新寫入1302
- Write1302(142,128);//寫保護(hù),禁止寫操作
- }
- //主函數(shù)
- void main()
- {
- TMOD=1;//初始化定時器
- TH0=60;
- TL0=176;
- EA=1;
- ET0=1;
- TR0=1;
- P2=255;
- Write1302(144,160);//關(guān)閉充電二級管,不能對后備電池進(jìn)行充電,防止發(fā)脹,原來的程序是打開的請關(guān)閉
- Write1302(142,128);//寫保護(hù),禁止寫操作
- if(!UP&!DOWN)
- Set1302(inittime); //如果同時按下UP和DOWN鍵則初始化1302,該語句在while(1)前,只執(zhí)行一次,需要復(fù)位,防止誤操作
- while(1)
- {
- Scan_Key(); //主程序一直調(diào)用鍵盤檢測函數(shù)即可
- }
- }
- //中斷處理程序,主要用于取反標(biāo)志位,返回正常顯示狀態(tài)
- void t0() interrupt 1 using 0
- {
- TH0=60; //50ms定時
- TL0=176;
- timecount++;
- re_disp++;
- if(timecount>9)
- {
- timecount=0;
- flag=~flag;
- }
- if(re_disp>200)
- {
- re_disp=0;
- if(id)
- id=0;
- }
- }
復(fù)制代碼
|
|