本設(shè)計能實現(xiàn)年月日的倒計時功能,
北京奧運會倒計時牌仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png (26.08 KB, 下載次數(shù): 40)
下載附件
2018-6-8 04:22 上傳
0.png (46.75 KB, 下載次數(shù): 52)
下載附件
2018-6-8 04:22 上傳
單片機源程序如下:
- /***************************************
- 名稱:2008奧運會倒計時
- ***************************************/
- #include<reg51.h>
- #include<absacc.h>
- #include<intrins.h>
- #include "delay.h"
- #define clock_segment XBYTE[0xBFFF] //時鐘段碼地址
- #define clock_sel XBYTE[0x7FFF] //時鐘位碼地址
- #define year_segment XBYTE[0xEFFF] //日歷段碼地址
- #define year_sel XBYTE[0xDFFF] //日歷位碼地址
- #define retime_segment XBYTE[0xFBFF]//倒計時段碼地址
- #define retime_sel XBYTE[0xF7FF] //倒計時位碼地址
- unsigned char time_num=0;//定時一秒次數(shù)
- unsigned char shi_num=24;//小時位計數(shù)
- unsigned char miao_ge=0; //秒個位
- unsigned char miao_shi=0;//秒十位
- unsigned char fen_ge=0;//分個位
- unsigned char fen_shi=4;//分十位
- unsigned char shi_ge=8;//時個位
- unsigned char shi_shi=0;//時十位
- unsigned char year_thousand=2;
- unsigned char year_hundred=0;
- unsigned char year_decade=0;
- unsigned char year_unit=7;
- unsigned char month_decade=0;
- unsigned char month_unit=6;
- unsigned char day_decade=2;
- unsigned char day_unit=6;
- unsigned char retime_unit=0;
- unsigned char retime_decade=1;
- unsigned char retime_hundred=4;
- unsigned char retime_thousand=0;
- unsigned char year_thoustore; //保存年千位數(shù)據(jù)
- unsigned char year_hundstore; //保存年百位數(shù)據(jù)
- unsigned char year_decastore; //保存年十位數(shù)據(jù)
- unsigned char year_unitstore; //保存年個位數(shù)據(jù)
- unsigned char month_unitstore;//保存月個位數(shù)據(jù)
- unsigned char month_decastore;//保存月十位數(shù)據(jù)
- unsigned char day_unitstore; //保存日個位數(shù)據(jù)
- unsigned char day_decastore; //保存日十位數(shù)據(jù)
- unsigned char year_unitstore2;//保存年各位數(shù)據(jù)
- unsigned char year_decastore2;//年位組合子程序用來保護數(shù)據(jù)用
- unsigned char year_hundstore2;
- unsigned char year_thoustore2;
- unsigned char retime_ustore; //保存倒計時各位數(shù)據(jù)
- unsigned char retime_dstore;
- unsigned char retime_hstore;
- unsigned char retime_tstore;
- unsigned char day_numj=31; //奇數(shù)月31天
- unsigned char day_numo=30; //偶數(shù)月30天
- unsigned char day_numooo=30;
- unsigned char day_numoo;
- unsigned char month_num=12;
- unsigned int year_jointed; //年各位組合在一起,以便進行閏年判斷
- unsigned int year_help1;
- unsigned int year_help2;
- unsigned char xiaoshi_ge;//閃爍時存小時個位
- unsigned char xiaoshi_shi;//閃爍時存小時十位
- unsigned char fenzhong_ge;//閃爍時存分鐘個位
- unsigned char fenzhong_shi;//閃爍時存分鐘十位
- unsigned char cort=0;//判斷第幾次按下確認鍵
- sbit key_sure=P1^0;//調(diào)時或確認鍵
- sbit key_dec=P1^2;//調(diào)時減鍵
- bit first_sure=0; //第一次按下確認鍵
- bit second_sure=0;//第二次按下確認鍵
- bit third_sure=0; //第三次按下確認鍵
- bit fourth_sure=0;//第四次按下確認鍵
- bit fifth_sure=0; //第五次按下確認鍵
- bit sixth_sure=0; //第六次按下確認鍵
- bit seventh_sure=0;//第七次按下確認鍵
- unsigned code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//段碼表
- /************函數(shù)聲明*************/
- void shannum_jian(void);
- void inc_key(void);
- void dec_key(void);
- void dis_dingshi(void);
- void hour_shanshuo(void);
- void min_shanshuo(void);
- void kbscan(void);
- void display(void);
- void year_joint(void);
- unsigned char judgement_leap(void);
- void retime_flash(void);
- /********************************
- 顯示子程序
- *********************************/
- void display(void)
- {
- clock_sel=0xdf;
- clock_segment=table[miao_ge]; //送秒個位段位碼
- delay(3);
- clock_sel=0xef;
- clock_segment=table[miao_shi]; //送秒十位段位碼
- delay(3);
- clock_sel=0xf7;
- clock_segment=table[fen_ge]|0x80; //送分個位段位碼
- delay(3);
- clock_sel=0xfb;
- clock_segment=table[fen_shi]; //送分十位段位碼
- delay(3);
- clock_sel=0xfd;
- clock_segment=table[shi_ge]|0x80; //送時個位段位碼
- delay(3);
- clock_sel=0xfe;
- clock_segment=table[shi_shi]; //送時十位段位碼
- delay(3);
- year_sel=0x7f;
- year_segment=table[day_unit]; //送日個位段位碼
- delay(3);
- year_sel=0xbf;
- year_segment=table[day_decade]; //送日十位段位碼
- delay(3);
- year_sel=0xdf;
- year_segment=table[month_unit]|0x80; //送月個位段位碼
- delay(3);
- year_sel=0xef;
- year_segment=table[month_decade]; //送月十位段位碼
- delay(3);
- year_sel=0xf7;
- year_segment=table[year_unit]|0x80; //送年個位段位碼
- delay(3);
- year_sel=0xfb;
- year_segment=table[year_decade]; //送年十位段位碼
- delay(3);
- year_sel=0xfd;
- year_segment=table[year_hundred]; //送年百位段位碼
- delay(3);
- year_sel=0xfe;
- year_segment=table[year_thousand]; //送年千位段位碼
- delay(3);
- retime_sel=0xf7;
- retime_segment=table[retime_unit]; //送倒計時個位段位碼
- delay(3);
- retime_sel=0xfb;
- retime_segment=table[retime_decade]; //送倒計時十位段位碼
- delay(3);
- retime_sel=0xfd;
- retime_segment=table[retime_hundred];//送倒計時百位段位碼
- delay(3);
- retime_sel=0xfe;
- retime_segment=table[retime_thousand];//送倒計時千位段位碼
- delay(3);
- }
- /**********************************
- 判斷閏年子程序
- ***********************************/
- unsigned char judgement_leap(void)
- {
- year_joint(); //調(diào)用年各位組合子程序
- if((year_jointed%4==0&&year_jointed%100!=0)||(year_jointed%100==0&&year_jointed%400==0))return(29); //是閏年二月29天
- else return(28); //是平年二月28天
- }
- /**********************************
- 按鍵掃描子程序
- ***********************************/
- void kbscan(void)
- {
- unsigned char sccode;
- P1=0xff;
- if((P1&0xff)!=0xff)
- {
- //delay(5);
- display();
- display();
- display();
-
- if((P1&0xff)!=0xff)
- {
- sccode=P1;
- //while((P1&0xff)!=0xff) //按鍵后消陡
- //{
- // ;
- // }
- switch(sccode)
- {
- case 0xfe:shannum_jian();break;
- case 0xfd:inc_key(); break;
- case 0xfb:dec_key(); break;
- default: break;
- }
- }
- }
- }
- /********************************
- 確認鍵按鍵次數(shù)子程序
- ********************************/
- void shannum_jian(void)
- {
- cort++;
- if(cort==1) //第一次按下確認鍵
- {
- first_sure=1;
- second_sure=0;
- third_sure=0;
- fourth_sure=0;
- fifth_sure=0;
- sixth_sure=0;
- seventh_sure=0;
-
- }
- else if(cort==2) //第二次按下確認鍵
- {
- first_sure=0;
- second_sure=1;
- third_sure=0;
- fourth_sure=0;
- fifth_sure=0;
- sixth_sure=0;
- seventh_sure=0;
-
- }
- else if(cort==3) //第三次按下確認鍵
- {
- first_sure=0;
- second_sure=0;
- third_sure=1;
- fourth_sure=0;
- fifth_sure=0;
- sixth_sure=0;
- seventh_sure=0;
-
- }
- else if(cort==4) //第四次按下確認鍵
- {
- first_sure=0;
- second_sure=0;
- third_sure=0;
- fourth_sure=1;
- fifth_sure=0;
- sixth_sure=0;
- seventh_sure=0;
-
- }
- else if(cort==5) //第五次按下確認鍵
- {
- first_sure=0;
- second_sure=0;
- third_sure=0;
- fourth_sure=0;
- fifth_sure=1;
- sixth_sure=0;
- seventh_sure=0;
-
- }
- else if(cort==6) //第六次按下確認鍵
- {
-
- first_sure=0;
- second_sure=0;
- third_sure=0;
- fourth_sure=0;
- fifth_sure=0;
- sixth_sure=1;
- seventh_sure=0;
-
- }
- else if(cort==7) //第七次按下確認鍵
- {
- cort=0;
- first_sure=0;
- second_sure=0;
- third_sure=0;
- fourth_sure=0;
- fifth_sure=0;
- sixth_sure=0;
- seventh_sure=1;
- }
- }
- /*******************************
- 減一鍵子程序
- *******************************/
- void dec_key(void)
- {
- if(first_sure) //第一次按下確認鍵,小時位減
- {
- if(shi_num!=24)
- {
- ++shi_num;
- if((--xiaoshi_ge)==255)
- {
- xiaoshi_ge=9;
- if((--xiaoshi_shi)==255)
- {
- xiaoshi_shi=2;
- xiaoshi_ge=3;
- }
- }
- }
- else if(shi_num==24)
- {
- shi_num=1;
- xiaoshi_ge=3;
- xiaoshi_shi=2;
- }
- }
- else if(second_sure) //第二次按下確認鍵,分鐘位減
- {
- if((--fenzhong_ge)==255)
- {
- fenzhong_ge=9;
- if((--fenzhong_shi)==255)
- {
- fenzhong_shi=5;
- }
- }
- }
- else if(third_sure) //第三次按下確認鍵,年位減
- {
- if((--year_unitstore)==255)
- {
- year_unitstore=9;
- if((--year_decastore)==255)
- {
- year_decastore=9;
- if((--year_hundstore)==255)
- {
- year_hundstore=9;
- if((--year_thoustore)==255)
- {
- year_thoustore=9;
- }
- }
- }
- }
- }
- else if(fourth_sure) //第四次按下確認鍵,月位減
- {
- if(month_num!=12)
- {
- ++month_num;
- if((--month_unitstore)==255)
- {
- month_unitstore=9;
- --month_decastore;
- }
- }
- else if(month_num==12)
- {
- month_num=1;
- month_unitstore=2;
- month_decastore=1;
- }
- }
- else if(fifth_sure) //第五次按下確認鍵,日位減
- {
- if((month_unitstore|0xfe)==0xff) //是奇數(shù)月,日為31天
- {
- if((day_numj)!=31)
- {
- ++day_numj;
- if((--day_unitstore)==255)
- {
- day_unitstore=9;
- --day_decastore;
- }
- }
- else if(day_numj==31)
- {
- day_numj=1;
- day_unitstore=1;
- day_decastore=3;
- }
- }
- else if((month_unitstore|0xfe)!=0xff) //是偶數(shù)月,日為30天
- {
-
- if(
-
- month_unitstore==2) //是二月
- {
- if(day_numo!=day_numoo)
- {
- ++day_numo;
- if((--day_unitstore)==255)
- {
- day_unitstore=9;
- --day_decastore;
- }
- }
-
- else if(day_numo==day_numoo)
- {
- if(day_numoo==28)
- {
- day_numo=1;
- day_unitstore=8;
- day_decastore=2;
- }
- else if(day_numoo==29)
- {
- day_numo=1;
- day_unitstore=9;
- day_decastore=2;
- }
-
- }
- }
- else if(month_unitstore!=2) //不是二月
- {
- if(day_numooo!=30)
- {
- ++day_numooo;
- day_numo=day_numooo;
- if((--day_unitstore)==255)
- {
- day_unitstore=9;
- --day_decastore;
- day_numo=day_numooo;
- }
- }
- else if(day_numooo==30)
- {
-
- day_numooo=1;
- day_unitstore=0;
- day_decastore=3;
- day_numo=day_numooo;
-
- }
- }
- }
- }
- else if(sixth_sure) //第六次按下確認鍵,倒計時位減
- {
- if((--retime_ustore)==255)
- {
- retime_ustore=9;
- if((--retime_dstore)==255)
- {
- retime_dstore=9;
- if((--retime_hstore)==255)
- {
- retime_hstore=9;
- if((--retime_tstore)==255)retime_tstore=9;
- }
- }
- }
- }
- }
- /*******************************
- 年位閃爍子程序
- *******************************/
- void year_flash(void)
- {
- unsigned char i;
- if(third_sure)
- {
- year_thoustore=year_thousand;
- year_hundstore=year_hundred;
- year_decastore=year_decade;
- year_unitstore=year_unit;
- while(third_sure)
- {
- for(i=0;i<18;i++) //年位不顯示,其它位都顯示
- {
- year_thousand=10;
- year_hundred=10;
- year_decade=10;
- year_unit=10;
- fen_ge=fenzhong_ge;
- fen_shi=fenzhong_shi;
- display();
- kbscan();
- if(!third_sure)i=51; //如果不滿足立即跳出
- }
- if(third_sure)
- {
- for(i=0;i<18;i++) //年位和其它位都顯示
- {
- year_thousand=year_thoustore;
- year_hundred=year_hundstore;
- year_decade=year_decastore;
- year_unit=year_unitstore;
- fen_ge=fenzhong_ge;
- fen_shi=fenzhong_shi;
- display();
- kbscan();
- if(!third_sure)i=51; //如果不滿足立即跳出
- }
- }
- }
- }
- }
- /*******************************
- 月位閃爍子程序
- *******************************/
- void month_flash(void)
- {
- unsigned char i;
- if(TR0==0) //為日位潤平年二月天數(shù)做準備
- {
- day_numo=judgement_leap();
- day_numoo=day_numo;
- }
- if(fourth_sure)
- {
- month_unitstore=month_unit;
- month_decastore=month_decade;
- while(fourth_sure)
- {
- for(i=0;i<18;i++)
- {
- month_unit=10;
- month_decade=10;
- year_thousand=year_thoustore; //送原始數(shù)據(jù)避免取到不顯示數(shù)據(jù)
- year_hundred=year_hundstore;
- year_decade=year_decastore;
- year_unit=year_unitstore;
- display();
- kbscan();
- if(!fourth_sure)i=51;
- }
- if(fourth_sure)
- {
- for(i=0;i<18;i++)
- {
- month_unit=month_unitstore;
- month_decade=month_decastore;//送原始數(shù)據(jù)避免取到不顯示數(shù)據(jù)
- year_thousand=year_thoustore;
- year_hundred=year_hundstore;
- year_decade=year_decastore;
- year_unit=year_unitstore;
- display();
- kbscan();
- if(!fourth_sure)i=51;
- }
- }
- }
- }
- }
- /*******************************
- 日位閃爍子程序
- ******************************/
- void day_flash(void)
- {
- unsigned char i;
- if(fifth_sure)
- {
- day_unitstore=day_unit;
- day_decastore=day_decade;
- while(fifth_sure)
- {
- for(i=0;i<18;i++)
- {
- day_unit=10;
- day_decade=10;
- month_unit=month_unitstore; //送原始數(shù)據(jù)避免取到不顯示數(shù)據(jù)
- month_decade=month_decastore;
- year_thousand=year_thoustore;
- year_hundred=year_hundstore;
- year_decade=year_decastore;
- year_unit=year_unitstore;
- display();
- kbscan();
- if(!fifth_sure)i=51;
- }
- if(fifth_sure)
- {
- for(i=0;i<18;i++)
- {
- day_unit=day_unitstore;
- day_decade=day_decastore;
- month_unit=month_unitstore; //送原始數(shù)據(jù)避免取到不顯示數(shù)據(jù)
- month_decade=month_decastore;
- year_thousand=year_thoustore;
- year_hundred=year_hundstore;
- year_decade=year_decastore;
- year_unit=year_unitstore;
- display();
- kbscan();
- if(!fifth_sure)i=51;
- }
- }
- }
- }
- }
- /*******************************
- 倒計時位閃爍子程序
- *******************************/
- void retime_flash(void)
- {
- unsigned char i;
- if(sixth_sure)
- {
- retime_ustore=retime_unit;
- retime_dstore=retime_decade;
- retime_hstore=retime_hundred;
- retime_tstore=retime_thousand;
- while(sixth_sure)
- {
- for(i=0;i<18;i++)
- {
- retime_unit=10;
- retime_decade=10;
- retime_hundred=10;
- retime_thousand=10;
- day_unit=day_unitstore;
- day_decade=day_decastore;
- display();
- kbscan();
- if(!sixth_sure)i=51;
- }
- if(sixth_sure)
- {
- for(i=0;i<18;i++)
- {
- retime_unit=retime_ustore;
- retime_decade=retime_dstore;
- retime_hundred=retime_hstore;
- retime_thousand=retime_tstore;
- day_unit=day_unitstore;
- day_decade=day_decastore;
- display();
- kbscan();
- if(!sixth_sure)i=51;
- }
- }
- }
- if(seventh_sure) //第八次確認鍵按下,啟動定時器,將各位的數(shù)據(jù)全部彈出,時鐘正常顯示
- {
- seventh_sure=0;
- fen_ge=fenzhong_ge;
- fen_shi=fenzhong_shi;
- shi_ge=xiaoshi_ge;
- shi_shi=xiaoshi_shi;
- year_unit=year_unitstore;
- year_decade=year_decastore;
- year_hundred=year_hundstore;
- year_thousand=year_thoustore;
- month_unit=month_unitstore;
- month_decade=month_decastore;
- day_unit=day_unitstore;
- day_decade=day_decastore;
- retime_unit=retime_ustore;
- retime_decade=retime_dstore;
- retime_hundred=retime_hstore;
- retime_thousand=retime_tstore;
- TR0=1;
- }
- }
- }
- /*******************************
- 小時位閃爍子程序
- *******************************/
- void hour_flash(void)
- {
- unsigned char i;
- if(first_sure)
- {
- TR0=0; //關(guān)定時器,進入閃爍
- xiaoshi_ge=shi_ge; //保存時個位顯示的數(shù)據(jù)
- xiaoshi_shi=shi_shi; //保存時十位顯示的數(shù)據(jù)
- while(first_sure) //第一次確認鍵按下,在小時位閃爍
- {
- for(i=0;i<18;i++) //小時位不顯示,其它位顯示
- {
- shi_ge=10;
- shi_shi=10;
- display();
- kbscan();
- if(!first_sure)i=51;
- }
- if(first_sure)
- {
- for(i=0;i<18;i++)//小時位和其它位都顯示
- {
- shi_ge=xiaoshi_ge;
- shi_shi=xiaoshi_shi;
- display();
- kbscan();
- if(!first_sure)i=51;
- }
- }
- }
- }
- }
- /******************************
- 分鐘位閃爍子程序
- *******************************/
- void min_flash(void)
- {
- unsigned char i;
- if(second_sure)
- {
- fenzhong_ge=fen_ge; //保存分個位顯示的數(shù)據(jù)
- fenzhong_shi=fen_shi; //保存分十位顯示的數(shù)據(jù)
- while(second_sure) //第二次確認鍵按下,在分鐘位閃爍
- {
- for(i=0;i<18;i++)//分鐘位不顯示,其它位都顯示
- {
- fen_ge=10;
- fen_shi=10;
- shi_ge=xiaoshi_ge; //送小時個位的原始數(shù)據(jù),避免調(diào)到小時個位不顯示時的數(shù)據(jù)
- shi_shi=xiaoshi_shi;//送小時十位的原始數(shù)據(jù),避免調(diào)到小時十位不顯示時的數(shù)據(jù)
- display();
- kbscan();
- if(!second_sure)i=51;
- }
- if(second_sure)
- {
- for(i=0;i<18;i++) //分鐘位和其它位都顯示
- {
- fen_ge=fenzhong_ge;
- fen_shi=fenzhong_shi;
- shi_ge=xiaoshi_ge; //送小時個位的原始數(shù)據(jù),避免調(diào)到小時個位不顯示時的數(shù)據(jù)
- shi_shi=xiaoshi_shi;//送小時十位的原始數(shù)據(jù),避免調(diào)到小時十位不顯示時的數(shù)據(jù)
- display();
- kbscan();
- if(!second_sure)i=51;
- }
- }
- }
- }
- }
- /******************************
- 年位組合子程序
- ********************************/
- void year_joint(void)
- {
- year_unitstore2=year_unitstore; //保存年各位數(shù)據(jù)
- year_decastore2=year_decastore;
- year_hundstore2=year_hundstore;
- year_thoustore2=year_thoustore;
- year_jointed=year_unitstore;
- year_decastore=year_decastore<<4;
- year_decastore=year_decastore&0xf0;
- year_jointed=year_jointed+year_decastore; //得到年的抵8位
- year_jointed=year_jointed<<8; //將年的低8和高8互換
- year_jointed=year_jointed+year_hundstore;
- year_thoustore=year_thoustore<<4;
- year_thoustore=year_thoustore&0xf0;
- year_jointed=year_jointed+year_thoustore; //得到年,需將其進行高8與低8互換
- year_help1=year_jointed&0xff00;
- year_help1=year_help1>>8; //得到年低8位
- year_help2=year_jointed&0x00ff;
- year_help2=year_help2<<8; //得到年高8位
- year_jointed=year_help1+year_help2; // 得到年位
- year_unitstore=year_unitstore2;
- year_decastore=year_decastore2;
- year_hundstore=year_hundstore2;
- year_thoustore=year_thoustore2; //彈出年各位數(shù)據(jù)
- }
- /*******************************
- 定時器0中斷子程序
- ********************************/
- void timer0(void) interrupt 1 using 1
- {
- TH0=0x3c;
- TL0=0xb0;
- if((++time_num)==20)
- {
- time_num=0;
- ++miao_ge; //定時一秒到,秒個位加一
- }
- }
- /******************************
- 當秒個位加到9時進一,
- ……
- *******************************/
- void dis_dingshi(void)
- {
- if(miao_ge==10)
- {
- miao_ge=0;
- if((++miao_shi)==6)
- {
- miao_shi=0;
- if((++fen_ge)==10)
- {
- fen_ge=0;
- if((++fen_shi)==6)
- {
- fen_shi=0;
- if((--shi_num)!=0)
- {
- if((++shi_ge)==10)
- {
- shi_ge=0;
- ++shi_shi;
- }
- }
- else if(shi_num==0)
- {
- shi_num=24;
- shi_ge=0;
- shi_shi=0;
- if(retime_unit==0&retime_decade==0&retime_hundred==0&retime_thousand==0)//倒計時減一
- {
- ;
- }
- else
- {
- if((--retime_unit)==10)
- {
- retime_unit=0;
- if((--retime_decade)==10)
- {
- retime_decade=0;
- if((--retime_hundred)==10)
- {
- retime_hundred=0;
- if((--retime_thousand)==10)
- {
- retime_thousand=0;
- }
- }
- }
- }
- }
- if((month_unit|0xfe)==0xff) //是奇數(shù)月,日為31天
- {
- if((--day_numj)!=0) //31天沒到
- {
- if((++day_unit)==10)
- {
- day_unit=0;
- ++day_decade;
- }
- }
- else if(day_numj==0) //31天到了
- {
- day_numj=31;
- day_unit=1;
- day_decade=0;
-
- if((--month_num)!=0) //12個月沒到
- {
- if((++month_unit)==10)
- {
- month_unit=0;
- ++month_decade;
- }
- }
- else if(month_num==0) //12個月到了
- {
- month_num=12;
- month_unit=1;
- month_decade=0;
- if((++year_unit)==10) //年個位是否到9
- {
- year_unit=0;
- if((++year_decade)==10)
- {
- year_decade=0;
- if((++year_hundred)==10)
- {
- year_hundred=0;
- if((++year_thousand)==10)year_thousand=0;
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
單片機設(shè)計2008奧運會.rar
(178.65 KB, 下載次數(shù): 18)
2018-6-7 17:05 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|