這是一個采用實時時鐘芯片DS1302和AT89C51單片機的LED時鐘,使用C語言編寫的程序,可以實現以24小時計時,格式為23-59-59,能夠顯示和調整年月日和星期,并且能夠進行整點報時和設定鬧鐘。文件內含keil程序源碼和proteus仿真電路。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (16.09 KB, 下載次數: 46)
下載附件
2018-9-17 18:22 上傳
單片機源程序如下:
- /*--------------------------------------
- Real-Time Clock DS1302 program V9.1
- MCU STC89C52RC XAL 12MHz
- --------------------------------------*/
- #include <reg51.h>
- //
- #define uchar unsigned char
- #define uint unsigned int
- #define ulong unsigned long
- sbit BUZZ=P3^7;
- sbit KEY1=P1^0;//調整
- sbit KEY2=P1^1;//加1
- sbit KEY3=P1^2;//減1
- sbit KEY4=P1^3;//顯示轉換
- sbit CE = P3^2;
- sbit SCLK = P3^4;
- sbit IO = P3^3;
- uchar hour_reg, minute_reg, second_reg,day_reg,month_reg,year_reg,week_reg,NZ_hour=0,NZ_minute=0;
- uint display_flag=0,bs_flag=0,NZ_flag=0;
- /***************************************************************************/
- /* Prototypes */
- /***************************************************************************/
- uchar rbyte_3w();
- void reset_3w();
- void wbyte_3w(uchar);
- void read_time();
- void delay(uint);
- void display(uchar*);
- void time2str(uchar*);
- void time_set(void);
- /*--------------------------------------
- main function
- --------------------------------------*/
- void main(void)
- {
- uchar dispram[32];
- uchar s;
- uint bs_flag=0;
- reset_3w();
- wbyte_3w(0x8E); //開啟寄存器寫模式
- wbyte_3w(0x00);
- reset_3w();
- wbyte_3w(0x90); //開啟涓流充電
- wbyte_3w(0xAB);
- reset_3w();
- wbyte_3w(0x81);
- s = rbyte_3w();
- reset_3w();
- if (s&0x80)
- {
- wbyte_3w(0x80);
- wbyte_3w(s&0x7f);
- reset_3w();
- }
- wbyte_3w(0x85);
- s = rbyte_3w();
- reset_3w();
- if (s&0x80)
- {
- wbyte_3w(0x84);
- wbyte_3w(s&0x7f);
- reset_3w();
- }
- while (1)
- {
- if(KEY4==0)
- {
- do { switch(display_flag)
- {
- case 0 : {display(dispram); break; }
- case 1 : {display(dispram+8); break; }
- case 2 : {display(dispram+16); break; }
- case 3 : {display(dispram+24); break; }
- default : break;
- }
- } while (KEY4==0);
- display_flag++;
- }
- if(display_flag>3) display_flag=0;
- read_time();
- if(NZ_flag==1&&hour_reg==NZ_hour&&minute_reg==NZ_minute&&second_reg==0)
- {
- bs_flag=1; //關整點報時
- BUZZ=0;
- delay(2);
- BUZZ=1;
- }
- if(bs_flag==0&&minute_reg==0&&second_reg==0) {BUZZ=0;delay(20); BUZZ=1; delay(2);}
- time2str(dispram);
- switch(display_flag)
- {
- case 0 : {display(dispram); break; }
- case 1 : {display(dispram+8); break; }
- case 2 : {display(dispram+16); break; }
- case 3 : {display(dispram+24); break; }
- default : break;
- }
- if (KEY1==0) time_set();
- bs_flag=0;
- }
- }
- /*--------------------------------------
- Time data to display string function
- Parameter:pointer of string
- --------------------------------------*/
- void time2str(uchar*ch)
- {
- //時分秒
- ch[0]=hour_reg>>4;
- ch[1]=hour_reg&0x0f;
- ch[2]=16;
- ch[3]=minute_reg>>4;
- ch[4]=minute_reg&0x0f;
- ch[5]=16;
- ch[6]=second_reg>>4;
- ch[7]=second_reg&0x0f;
- //年月日
- ch[8]=year_reg>>4;
- ch[9]=year_reg&0x0f;
- ch[10]=16;
- ch[11]=month_reg>>4;
- ch[12]=month_reg&0x0f;
- ch[13]=16;
- ch[14]=day_reg>>4;
- ch[15]=day_reg&0x0f;
- //星期
- ch[16]=16;
- ch[17]=16;
- ch[18]=16;
- ch[19]=16;
- ch[20]=16;
- ch[21]=16;
- ch[22]=16;
- ch[23]=week_reg&0x0f;
- //鬧鐘
- ch[24]=NZ_hour>>4;
- ch[25]=NZ_hour&0x0f;
- ch[26]=16;
- ch[27]=NZ_minute>>4;
- ch[28]=NZ_minute&0x0f;
- ch[29]=16;
- ch[30]=16;
- ch[31]=NZ_flag&0x0f;
- }
- /*--------------------------------------
- Set time function
- --------------------------------------*/
- void time_set(void)
- {
- uchar ch[32];
- uchar i, change_flag=9;
- reset_3w();
- wbyte_3w(0x80);
- wbyte_3w(0x80);
- reset_3w();
- second_reg=0;
- time2str(ch);
- bs_flag=1;
- do {
- display(ch);
- } while (KEY1==0);
- while (change_flag)
- {
- time2str(ch);
- switch (change_flag)
- {
- case 9: {ch[0]|=0x80;ch[1]|=0x80;break;} //時
- case 8: {ch[3]|=0x80;ch[4]|=0x80;break;} //分
- case 7: {ch[8]|=0x80;ch[9]|=0x80;break;} //年
- case 6: {ch[11]|=0x80;ch[12]|=0x80;break;} //月
- case 5: {ch[14]|=0x80;ch[15]|=0x80;break;} //日
- case 4: {ch[23]|=0x80;break;} //星期
- case 3: {ch[24]|=0x80;ch[25]|=0x80;break;} //鬧鐘時
- case 2: {ch[27]|=0x80;ch[28]|=0x80;break;} //鬧鐘分
- case 1: {ch[31]|=0x80;break;} //鬧鐘標志
- default : break;
- }
- switch(change_flag)
- {
- case 9 :
- case 8 : {display(ch); break; }
- case 7 :
- case 6 :
- case 5 : {display(ch+8); break; }
- case 4 : {display(ch+16); break; }
- case 3 :
- case 2 :
- case 1 : {display(ch+24); break; }
- default : break;
- }
- if (KEY1==0) //按鍵按下
- {
- change_flag--;
- do {
- switch(change_flag)
- {
- case 9 :
- case 8 : {display(ch); break; }
- case 7 :
- case 6 :
- case 5 : {display(ch+8); break; }
- case 4 : {display(ch+16); break; }
- case 3 :
- case 2 :
- case 1 : {display(ch+24); break; }
- default : break;
- }
- } while (KEY1==0);
- }
- /*-----------------------------
- 加1功能
- ----------------------------*/
- if(KEY2==0)
- {
- switch (change_flag)
- {
- case 9:
- {
- hour_reg++;
- if ((hour_reg&0x0f)>9) hour_reg=(hour_reg&0xf0)+0x10;
- if (hour_reg>0x23) hour_reg=0;
- break;
- }
- case 8:
- {
- minute_reg++;
- if ((minute_reg&0x0f)>9) minute_reg=(minute_reg&0xf0)+0x10;
- if (minute_reg>0x59) minute_reg=0;
- break;
- }
- case 7:
- {
- year_reg++;
- if ((year_reg&0x0f)>9) year_reg=(year_reg&0xf0)+0x10;
- if (year_reg>0x99) year_reg=0;
- break;
- }
- case 6:
- {
- month_reg++;
- if ((month_reg&0x0f)>9) month_reg=(month_reg&0xf0)+0x10;
- if (month_reg>0x12) month_reg=0;
- break;
- }
- case 5:
- {
- day_reg++;
- if ((day_reg&0x0f)>9) day_reg=(day_reg&0xf0)+0x10;
- if (day_reg>0x31) day_reg=0;
- break;
- }
- case 4:
- {
- week_reg++;
- if (week_reg>0x07) week_reg=1;
- break;
- }
- case 3:
- {
- NZ_hour++;
- if ((NZ_hour&0x0f)>9) NZ_hour=(NZ_hour&0xf0)+0x10;
- if (NZ_hour>0x23) NZ_hour=0;
- break;
- }
- case 2:
- {
- NZ_minute++;
- if ((NZ_minute&0x0f)>9) NZ_minute=(NZ_minute&0xf0)+0x10;
- if (NZ_minute>0x59) NZ_minute=0;
- break;
- }
- case 1:
- {
- NZ_flag++;
- if (NZ_flag>1) NZ_flag=0;
- break;
- }
- default : break;
- }
- for (i=0;i<50;i++)
- switch(change_flag)
- {
- case 9 :
- case 8 : {display(ch); break; }
- case 7 :
- case 6 :
- case 5 : {display(ch+8); break; }
- case 4 : {display(ch+16); break; }
- case 3 :
- case 2 :
- case 1 : {display(ch+24); break; }
- default : break;
- }
-
- }
- /*---------------------------------------------------
- 減1功能
- -----------------------------------------------------*/
- if(KEY3==0)
- {
- switch (change_flag)
- {
- case 9:
- {
- hour_reg--;
- if ((hour_reg&0x0f)==0x0f) hour_reg=hour_reg&0xf9;
- if (hour_reg==0xf9) hour_reg=0x23;
- break;
- }
- case 8:
- {
- minute_reg--;
- if ((minute_reg&0x0f)==0x0f) minute_reg=minute_reg&0xf9;
- if (minute_reg==0xf9) minute_reg=0x59;
- break;
- }
- case 7:
- {
- year_reg--;
- if ((year_reg&0x0f)==0x0f) year_reg=year_reg&0xf9;
- if (year_reg==0xf9) year_reg=0x99;
- break;
- }
- case 6:
- {
- month_reg--;
- if ((month_reg&0x0f)==0x0f) month_reg=month_reg&0xf9;
- if (month_reg==0xf9) month_reg=0x12;
- break;
- }
- case 5:
- {
- day_reg--;
- if ((day_reg&0x0f)==0x0f) day_reg=day_reg&0xf9;
- if (day_reg==0xf9) day_reg=0x31;
- break;
- }
- case 4:
- {
- week_reg--;
- if (week_reg==0x00) week_reg=0x07;
- break;
- }
- case 3:
- {
- NZ_hour--;
- if ((NZ_hour&0x0f)==0x0f) NZ_hour=NZ_hour&0xf9;
- if (NZ_hour==0xf9) NZ_hour=0x23;
- break;
- }
- case 2:
- {
- NZ_minute--;
- if ((NZ_minute&0x0f)==0x0f) NZ_minute=NZ_minute&0xf9;
- if (NZ_minute==0xf9) NZ_minute=0x59;
- break;
- }
- case 1:
- {
- NZ_flag--;
- if (NZ_flag==0xff) NZ_flag=1;
- break;
- }
- default : break;
- }
- for (i=0;i<50;i++)
- switch(change_flag)
- {
- case 9 :
- case 8 : {display(ch); break; }
- case 7 :
- case 6 :
- case 5 : {display(ch+8); break; }
- case 4 : {display(ch+16); break; }
- case 3 :
- case 2 :
- case 1 : {display(ch+24); break; }
- default : break;
- }
-
- }
- }
- /*---------------------------------
- 將改好的數據寫進1302中
- -----------------------------*/
- reset_3w();
- wbyte_3w(0x8C);
- wbyte_3w(year_reg);
- reset_3w();
- wbyte_3w(0x8A);
- wbyte_3w(week_reg);
- reset_3w();
- wbyte_3w(0x88);
- wbyte_3w(month_reg);
- reset_3w();
- wbyte_3w(0x86);
- wbyte_3w(day_reg);
- reset_3w();
- wbyte_3w(0x84);
- wbyte_3w(hour_reg);
- reset_3w();
- wbyte_3w(0x82);
- wbyte_3w(minute_reg);
- reset_3w();
- wbyte_3w(0x80);
- wbyte_3w(second_reg);
- reset_3w();
- }
- /*--------------------------------------
- Delay function
- Parameter: unsigned int dt
- Delay time=dt(ms)
- --------------------------------------*/
- void delay(unsigned int dt)
- {
- register unsigned char bt,ct;
- for (; dt; dt--)
- for (ct=2;ct;ct--)
- for (bt=248; --bt; );
- }
- /*--------------------------------------
- 8 LED digital tubes display function
- Parameter: sting pointer to display
- --------------------------------------*/
- void display(uchar*disp_ram)
- {
- static uchar disp_count;
- unsigned char i,j;
- unsigned char code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xbf,0xff};
- disp_count=(disp_count+1)&0x7f;
- for (i=0;i<8;i++)
- {
- j =disp_ram[i];
- if (j&0x80) P0 =(disp_count>32)?table[j&0x7f]:0xff;
- else P0 =table[j];
- P2 =0x01<<i;
- delay(1);
- P0 =0xff;
- P2 =0;
- }
- }
- /*--------------------------------------
- Read time function
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載:
ds1302時鐘.rar
(63.96 KB, 下載次數: 113)
2018-9-17 11:37 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|