|
本作品采用STC15W1K16S單片機和DS1302設計,配合B站上傳的視頻更佳。
B站搜索基于DS1302的數字時鐘設計(UP凌凈清河)即可查到相關視頻(預計2018年6月30日下午會審核完畢)。
主要亮點:
1.時間按位設置
2.周數自動計算
3.對輸入的日期有嚴格的合法性判斷
4.數碼管單個位閃爍效果
次要亮點:
1.較少的單片機IO口占用
2.38譯碼器轉24線譯碼使用
請注意!為防止低成本盜用(雖然寫的不怎么樣),展示出的代碼刪去部分函數(和語句),在附件中有完整版。
- /*##############################################################################################
- 設計名稱:基于DS1302的數字時鐘
- 設計者:清河
- 平臺:STC15W1K16S
- 硬件部分
- 數碼管顯示:位選使用74HC138改為2-4線譯碼、段選使用74HC573提高帶載能力
- 74HC595靜態顯示:使用74HC595驅動一位共陰極數碼管靜態顯示當前星期
- 獨立按鍵:共4個,用于進行各項調整
- DS1302:配電池,實現斷電走時
- LED指示燈:指示當前所處狀態和鬧鐘開啟與否
- 蜂鳴器:使用5V有源蜂鳴器,提供鬧鐘功能
- 軟件部分
- 使用定時器0實現對DS1302數據的定時讀取,間隔500ms,以便更新當前的顯示值,讀取到的值以全局變量形式儲存
- 可以考慮使用定時器1實現數碼管中間秒指示的閃爍
- ##############################################################################################*/
- #include<STC15.H>
- #include<intrins.h>
- sbit SCLK=P1^6;
- sbit RST=P5^4;
- sbit DSIO=P1^7;
- sbit SER=P1^2;
- sbit RCLK=P1^3;
- sbit SRCLK=P1^4;
- sbit S1=P1^0;
- sbit S2=P1^1;
- sbit bell=P3^7;
- sbit SET=P3^6;
- sbit UP=P3^5;
- sbit DOWN=P3^4;
- sbit SHOW=P3^3;
- sbit setled=P3^1;
- sbit clkled=P3^0;
- unsigned char code smgduan[11]={0x3f,0x0a,0x57,0x4f,0x6a,0x6d,0x7d,0x0b,0x7f,0x6f,0x00};
- unsigned char code smgduan_dp[12]={0xbf,0x8a,0xd7,0xcf,0xea,0xed,0xfd,0x8b,0xff,0xef,0x00,0x80};
- unsigned char code hcwei[8]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07};
- unsigned char code READ_RTC_ADDR[7]={0x81,0x83,0x85,0x87,0x89,0x8b,0x8d};
- unsigned char code WRITE_RTC_ADDR[7]={0x80,0x82,0x84,0x86,0x88,0x8a,0x8c};
- unsigned char TIME[7]={0,0x34,0x19,0x17,0x06,0x07,0x18};
- unsigned int time_trans[7]={0,0,0,0,0,0,0};
- unsigned char display_time[4]={0,0,0,0};
- unsigned char display_monthday[4]={1,1,1,1};
- unsigned char display_year[4]={2,2,2,2};
- unsigned char display_second[4]={0,0,9,9};
- unsigned char display_week=0;
- unsigned char clock[4]={0,8,3,0};
- unsigned char set_time[4]={0,0,0,1};
- unsigned char set_monthday[4]={0,0,0,2};
- unsigned char set_year[4]={0,0,0,3};
- unsigned char set_clock[4]={0,8,3,0};
- unsigned char set_write[7]={0,0,0,0,0,0,0};
- bit flag_display=1;
- bit flag_SET=0;
- bit flag_clock=0;
- bit flag_clock_arrive=0;
- bit flag_exit=0;
- unsigned char display_mod=0;
- unsigned char set_mod=0;
- unsigned char flashbit=0;
- unsigned char t0_cnt=0
- unsigned int year_temp;
- void Ds1302Write(unsigned char addr, unsigned char dat)
- {
- unsigned char n;RST = 0;_nop_();SCLK = 0;_nop_();RST = 1; _nop_();
- for (n=0; n<8; n++){DSIO = addr & 0x01;addr >>= 1;SCLK = 1;_nop_();SCLK = 0;_nop_();}
- for (n=0; n<8; n++){DSIO = dat & 0x01;dat >>= 1;SCLK = 1;_nop_();SCLK = 0;_nop_();} RST = 0;_nop_();
- }
- unsigned char Ds1302Read(unsigned char addr)
- {
- unsigned char n,dat,dat1;RST = 0;_nop_();SCLK = 0;_nop_();RST = 1;_nop_();
- for(n=0; n<8; n++){DSIO = addr & 0x01;addr >>= 1;SCLK = 1;_nop_();SCLK = 0;_nop_();}_nop_();
- for(n=0; n<8; n++){dat1 = DSIO;dat = (dat>>1) | (dat1<<7);SCLK = 1;_nop_();SCLK = 0;_nop_();}
- RST = 0;_nop_(); SCLK = 1;_nop_();DSIO = 0;_nop_();DSIO = 1;_nop_();return dat;
- }
- void Ds1302Init()
- {unsigned char n;Ds1302Write(0x8E,0X00);for(n=0;n<7;n++){Ds1302Write(WRITE_RTC_ADDR[n],TIME[n]);}Ds1302Write(0x8E,0x80);}
- void Ds1302ReadTime()
- {unsigned char n;for(n=0;n<7;n++){TIME[n]=Ds1302Read(READ_RTC_ADDR[n]);}}
- void TimeReset()
- {
- unsigned char n;TR0=0;
- Ds1302Write(0x8E,0X00);for (n=0; n<7; n++){Ds1302Write(WRITE_RTC_ADDR[n],set_write[n]);}
- Ds1302Write(0x8E,0x80);for(n=0;n<4;n++){clock[n]=set_clock[n];}TR0=1;
- }
- void delay(unsigned int cnt)
- {while(cnt--);}
- void hc595send(unsigned char dat)
- {unsigned char a;SRCLK=0;RCLK=0;for(a=0;a<8;a++){SER=dat>>7;dat<<=1;SRCLK=1;_nop_();_nop_();SRCLK=0;}RCLK=1;_nop_();_nop_();RCLK=0;}
- void time_assign()
- {
- display_time[0]=time_trans[2]/10;display_time[1]=time_trans[2]%10;display_time[2]=time_trans[1]/10;display_time[3]=time_trans[1]%10;
- display_monthday[0]=time_trans[4]/10;display_monthday[1]=time_trans[4]%10;display_monthday[2]=time_trans[3]/10;display_monthday[3]=time_trans[3]%10;
- display_year[0]=2;display_year[1]=0;display_year[2]=(time_trans[6]%100)/10;display_year[3]=time_trans[6]%10;
- display_week=time_trans[5];display_second[0]=10;display_second[1]=11;display_second[2]=time_trans[0]/10;display_second[3]=time_trans[0]%10;
- if(flag_display){hc595send(hcwei[display_week]);}else{hc595send(0x00);}
- if(display_time[0]==clock[0]&&display_time[1]==clock[1]&&display_time[2]==clock[2]&&display_time[3]==clock[3]){flag_clock_arrive=1;}else{flag_clock_arrive=0;}
- }
- void smgdisplay(unsigned char smg_temp[])
- {
- unsigned char i;
- for(i=0;i<4;i++)
- {
- switch(i)
- {
- case(0):S1=0;S2=1; break;
- case(1):S1=0;S2=0; break;
- case(2): S1=1;S2=0; break;
- case(3):S1=1;S2=1; break;
- }
- if(flag_SET)
- {
- switch(set_mod)
- {
- case 0:P2=smgduan_dp[smg_temp[i]];break;
- case 1:P2=smgduan[smg_temp[i]];break;
- case 2:P2=smgduan[smg_temp[i]];break;
- case 3:P2=smgduan_dp[smg_temp[i]];break;
- }
- }
- else
- {
- switch(display_mod)
- {
- case 0:P2=smgduan_dp[smg_temp[i]];break;
- case 1:P2=smgduan[smg_temp[i]];break;
- case 2:P2=smgduan[smg_temp[i]];break;
- case 3:P2=smgduan_dp[smg_temp[i]];break;
- case 4:P2=smgduan_dp[smg_temp[i]];break;
- }
- }
- delay(100);
- P2=0x00;
- }
- }
- void clockoo()
- {
- if(flag_clock&&flag_clock_arrive&&t0_cnt==9){bell=~bell;}else{bell=0;}
- }
- unsigned char Leap(unsigned int year)
- {
- if(year%100==0){if(year%400==0)return 1;else return 0;}else{if(year%4==0)return 1;else return 0;}
- }
- void sys_init()
- {
- setled=1;clkled=1;bell=0;hc595send(0x76);TMOD=0x11;TL0=(65536-50000)/256;TH0=(65536-50000)%256;ET0=1;EA=1;TR0=1
- }
- void main()
- {
- sys_init();
- while(1)
- {
- if(flag_display)
- {
- switch(display_mod)
- {
- case 0:smgdisplay(display_time);break;
- case 1:smgdisplay(display_monthday);break;
- case 2:smgdisplay(display_year);break;
- case 3:smgdisplay(display_second);break;
- case 4:smgdisplay(clock);break;
- default :display_mod=0;break;
- }
- }
- if(SET==0){delay(150);if(SET==0){flag_SET=1;setled=0;}while(!SET);}
- if(!flag_SET)
- {
- if(UP==0){delay(200);if(UP==0){flag_display=~flag_display;}while(!UP);}
- if(DOWN==0){delay(250);if(DOWN==0){flag_clock=!flag_clock;clkled=!flag_clock;}while(!DOWN);}
- if(SHOW==0&&flag_display){delay(200);if(SHOW==0){display_mod++;if(display_mod>4)display_mod=0;}while(!SHOW);}
- }
- else
- {
- while(flag_SET)
- {
- switch(set_mod)
- {
- case 0:smgdisplay(set_time);break;
- case 1:smgdisplay(set_monthday);break;
- case 2:smgdisplay(set_year);break;
- case 3:smgdisplay(set_clock);break;
- default:set_mod=0;break;
- }
- if(UP==0)
- {
- delay(200);
- if(UP==0)
- {
- switch(set_mod)
- {
- case 0:if(t1_temp==10){if(set_time[flashbit]<9)set_time[flashbit]++;}else{if(t1_temp<9)t1_temp++;}break;
- case 1:if(t1_temp==10){if(set_monthday[flashbit]<9)set_monthday[flashbit]++;}else{if(t1_temp<9)t1_temp++;}break;
- case 2:if(t1_temp==10){if(set_year[flashbit]<9)set_year[flashbit]++;}else{if(t1_temp<9)t1_temp++;}break;
- case 3:if(t1_temp==10){if(set_clock[flashbit]<9)set_clock[flashbit]++;}else{if(t1_temp<9)t1_temp++;}break;
- }
- }while(!UP);
- }
- if(DOWN==0)
- {
- delay(200);
- if(DOWN==0)
- {
- switch(set_mod)
- {
- case 0:if(t1_temp==10){if(set_time[flashbit]>0)set_time[flashbit]--;}else{if(t1_temp>0)t1_temp--;}break;
- case 1:if(t1_temp==10){if(set_monthday[flashbit]>0)set_monthday[flashbit]--;}else{if(t1_temp>0)t1_temp--;}break;
- case 2:if(t1_temp==10){if(set_year[flashbit]>0)set_year[flashbit]--;}else{if(t1_temp>0)t1_temp--;}break;
- case 3:if(t1_temp==10){if(set_clock[flashbit]>0)set_clock[flashbit]--;}else{if(t1_temp>0)t1_temp--;}break;
- }
- }while(!DOWN);
- }
- if(SHOW==0)
- {
- delay(200);
- if(SHOW==0)
- {
- if(t1_temp!=10)
- {
- switch(set_mod)
- {
- case 0:set_time[flashbit]=t1_temp;t1_temp=10;break;
- case 1:set_monthday[flashbit]=t1_temp;t1_temp=10;break;
- case 2:set_year[flashbit]=t1_temp;t1_temp=10;break;
- case 3:set_clock[flashbit]=t1_temp;t1_temp=10;break;
- }
- }
- flashbit++;
- if(flashbit>3)flashbit=0;
- }while(!SHOW);
- }
- if(SET==0)
- {
- delay(200);
- if(SET==0)
- {
- if(t1_temp!=10)
- {
- switch(set_mod)
- {
- case 0:set_time[flashbit]=t1_temp;t1_temp=10;break;
- case 1:set_monthday[flashbit]=t1_temp;t1_temp=10;break;
- case 2:set_year[flashbit]=t1_temp;t1_temp=10;break;
- case 3:set_clock[flashbit]=t1_temp;t1_temp=10;break;
- }
- }
- switch(set_mod)
- {case 0:
- if((set_time[0]*10+set_time[1])>24||set_time[0]>2){flag_exit=1;}else{if(set_time[0]==2&&set_time[1]>4){flag_exit=1;}}
- if((set_time[2]*10+set_time[3])>60||set_time[2]>5){flag_exit=1;}break;
- case 1:
- if((set_monthday[0]*10+set_monthday[1])>12||set_monthday[0]>1){flag_exit=1;}
- else{if(set_monthday[0]==1&&set_monthday[1]>2){flag_exit=1;}if(set_monthday[0]==0&&set_monthday[1]==0){flag_exit=1;}}
- if((set_monthday[2]*10+set_monthday[3])>31||set_monthday[0]>3){flag_exit=1;}break;
- case 2:
- if(set_year[0]!=2||set_year[1]!=0){flag_exit=1;}
- year_temp=set_year[0]*1000+set_year[1]*100+set_year[2]*10+set_year[3];
- if(!Leap(year_temp)){if(set_monthday[0]==0&&set_monthday[1]==2&&set_monthday[2]==2&&set_monthday[3]==9){flag_exit=1;}}break;
- case 3:
- if((set_clock[0]*10+set_clock[1])>24||set_clock[0]>2){flag_exit=1;}else{if(set_clock[0]==2&&set_clock[1]>4){flag_exit=1;}}
- if((set_clock[2]*10+set_clock[3])>60||set_clock[2]>5){flag_exit=1;}break;
- }set_mod++;flashbit=0;
- }
- while(!SET);
- if(flag_exit){flag_exit=0;set_mod=0;flag_SET=0;setled=1;flashbit=0;goto OUT;}else{if(set_mod==4){display_week=week_calculation(set_year,set_monthday);time_transmission();TimeReset();flag_exit=0;set_mod=0;flag_SET=0;setled=1;flashbit=0;goto OUT;}
- }
- }
- }
- OUT: _nop_();
- }clockoo();
- }
- }
- void GetTime() interrupt 1
- {
- TL0=(65536-50000)/256;TH0=(65536-50000)%256;t0_cnt++;
- if(t0_cnt==10){Ds1302ReadTime();time_procressing();time_assign();t0_cnt=0;}
- }
復制代碼
帶注釋版在附件中,上面的為無注釋緊縮版,代碼排版嚴謹,分級之間使用TAB件,無多余空格,復制到Notpad++中以*.c文件保存可以正常觀看。
新礦城學習基地 凌凈清河
基于DS1302的數字時鐘設計 凌凈清河.zip
(59.37 KB, 下載次數: 258)
2018-6-30 00:02 上傳
點擊文件名下載附件
|
評分
-
查看全部評分
|