要求
顯示當(dāng)前時(shí)間與日期。
手動(dòng)修改時(shí)間、日期信息,修改該位信息時(shí)該數(shù)碼管閃爍。
手動(dòng)開啟/關(guān)閉鬧鐘功能,而且有鬧鐘狀態(tài)指示燈。
手動(dòng)設(shè)置鬧鐘,而且當(dāng)達(dá)到設(shè)置好的時(shí)間點(diǎn)時(shí)報(bào)警,報(bào)警時(shí)長(zhǎng)為5s。
分析
萬年歷的整體設(shè)計(jì)如圖所示:
0.png (16.94 KB, 下載次數(shù): 45)
下載附件
2019-1-20 01:22 上傳
51單片機(jī)核心模塊包括51單片機(jī)最小系統(tǒng)模塊,是設(shè)計(jì)應(yīng)用的控制核心;顯示模塊用于顯示時(shí)間與日期、設(shè)計(jì)鬧鐘時(shí)間等信息;指示燈包括時(shí)間日期暫停計(jì)數(shù)指示燈和鬧鐘開啟或關(guān)閉狀態(tài)指示燈;鬧鐘采用蜂鳴器發(fā)出聲音警報(bào);鍵盤輸入模塊用來設(shè)置和切換時(shí)間、日期,開啟或關(guān)閉鬧鐘,設(shè)置鬧鐘時(shí)間等。
制作出來的實(shí)物圖如下:
0.jpg (55.31 KB, 下載次數(shù): 38)
下載附件
2019-1-20 01:24 上傳
可用安卓接口5V供電,也可接學(xué)生電源或兩個(gè)3.7V的電池通過LM7805穩(wěn)壓管供電。
功能介紹: 程序初始化處于時(shí)間計(jì)數(shù)狀態(tài)(已設(shè)置初始值為12:12:00),按下Key2選擇位校準(zhǔn)位,按下第一次選中秒鐘,第二次選中分鐘,第三次選中時(shí)鐘,第四次退出校時(shí)功能,被選中位不斷閃爍,并且按下Key3可進(jìn)行被選擇位逐漸加一,實(shí)現(xiàn)校時(shí)。按下Key4,數(shù)碼管顯示界面跳轉(zhuǎn)為日期顯示,按下按鍵Key2和Key3 可實(shí)現(xiàn)與時(shí)間同一校準(zhǔn)時(shí)間的功能,再次按下Key4切換為時(shí)間界面。在時(shí)間顯示或者日期顯示狀態(tài)下,按下按鍵Key1可獨(dú)立暫停時(shí)間計(jì)數(shù)或日期的增加,并且LED1指示燈亮。 按下按鍵K3開啟鬧鐘功能,LED2亮,再次按下則關(guān)閉鬧鐘,LED2滅。按下K4切換為鬧鐘設(shè)置狀態(tài)(已設(shè)置鬧鐘初始值為12:12:00),按下K1進(jìn)行分鐘位加一,按下Key2切換為時(shí)鐘位調(diào)時(shí),按下K1進(jìn)行時(shí)鐘位加一,在鬧鐘狀態(tài)下秒鐘不可調(diào)。在進(jìn)入鬧鐘設(shè)置功能前,需先開啟鬧鐘功能,否則鬧鐘不會(huì)到點(diǎn)鬧鈴。按下K2退出鬧鐘設(shè)置界面,等到實(shí)時(shí)時(shí)間與所設(shè)置鬧鐘時(shí)間一致時(shí),蜂鳴器響5s鐘,中途可按下K3關(guān)閉蜂鳴器,并且關(guān)閉鬧鐘功能。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
截圖20190119195459.png (111.88 KB, 下載次數(shù): 55)
下載附件
2019-1-19 20:14 上傳
0.png (9.67 KB, 下載次數(shù): 53)
下載附件
2019-1-20 01:03 上傳
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
0.png (56 KB, 下載次數(shù): 45)
下載附件
2019-1-20 01:17 上傳
0.png (54.17 KB, 下載次數(shù): 39)
下載附件
2019-1-20 01:17 上傳
0.png (5.41 KB, 下載次數(shù): 39)
下載附件
2019-1-20 01:17 上傳
程序流程圖:
0.png (24.29 KB, 下載次數(shù): 42)
下載附件
2019-1-20 01:25 上傳
單片機(jī)源程序如下:
- #include<reg51.h>
- #define uChar unsigned char
- #define uInt unsigned int
- uChar a[]={~0x3f,~0x06,~0x5b,~0x4f,~0x66,~0x6d,~0x7d,~0x07,~0x7f,~0x6f}; //數(shù)碼管段選碼,0——9
- uChar b[]={~0xfe,~0xfd,~0xfb,~0xf7,~0xef,~0xdf,~0xbf,~0x7f}; //數(shù)碼管位選碼,高——低
- uChar second=0,minute=12,hour=12,month=1,day=13,count; uInt year=2019;
- uChar f_nao=12,s_nao=12; //鬧鐘分計(jì)數(shù),鬧鐘時(shí)計(jì)數(shù)
- uChar wave=0; //定時(shí)器1對(duì)0.1ms定時(shí)時(shí)間進(jìn)行計(jì)數(shù),控制蜂鳴器響的頻率
- bit flag_nao; //控制鬧鐘開關(guān)變量 flag_nao= 0-off;1--on
- sbit K1 = P3^0; //設(shè)置鬧鐘分/時(shí)位加一
- sbit K2 = P3^1; //退出設(shè)置鬧鐘
- sbit K3 = P3^2; //鬧鐘開關(guān)
- sbit K4 = P3^3; //進(jìn)入設(shè)置鬧鐘狀態(tài)
- sbit Key1 = P3^4; //計(jì)時(shí)停止
- sbit Key2 = P3^5; //調(diào)位(校準(zhǔn))
- sbit Key3 = P3^6; //所調(diào)位加一
- sbit Key4 = P3^7; //切換時(shí)-分-秒、年-月-日
- sbit BEEP = P2^2; //蜂鳴器端口
- sbit LED1 = P2^0; //計(jì)時(shí)停止時(shí)LED1亮
- sbit LED2 = P2^1; //鬧鐘開啟時(shí)LED2亮
-
- //函數(shù)聲明
- void Delayms(uInt t); //長(zhǎng)延時(shí)函數(shù)
- void Dispaly1(uChar second,uChar minute,uChar hour); //時(shí)-分-秒顯示
- void Dispaly2(uChar day,uChar month,uInt year); //年-月-日顯示
- void Keyscan1(); //按鍵Key4按下次數(shù)為雙數(shù)時(shí)(按鍵Key1~3控制時(shí)-分-秒)
- void Keyscan2(); //按鍵Key4按下次數(shù)為單數(shù)時(shí)(按鍵Key1~3控制年-月-日)
- void nao_judge(); //判斷鬧鐘
-
- /*************時(shí)-分-秒、年-月-日閃爍函數(shù)聲明*********************/
- void delay(uInt t); /***/
- void Bright1(uChar second,uChar minute,uChar hour); /***/
- void Hour_flicker(uChar second,uChar minute,uChar hour); /***/
- void Minute_flicker(uChar second,uChar minute,uChar hour); /***/
- void Second_flicker(uChar second,uChar minute,uChar hour); /***/
- void Bright2(uChar day,uChar month,uInt year); /***/
- void Year_flicker(uChar day,uChar month,uInt year); /***/
- void Month_flicker(uChar day,uChar month,uInt year); /***/
- void Day_flicker(uChar day,uChar month,uInt year); /***/
- /*************時(shí)-分-秒、年-月-日閃爍函數(shù)聲明*********************/
- //主函數(shù)
- void main()
- {
- TMOD=0x11; //置T0、T1都為工作方式1
- TH0=(65536-10000)/256;
- TL0=(65536-10000)%256;
- TR0=1; //開啟T0
- ET0=1; //打開T0中斷允許位
- IT1=1; //設(shè)置外部中斷1為下降沿觸發(fā)
- IT0=0; //設(shè)置外部中斷0為低電平觸發(fā)
- EX1=1; //打開外部中斷1允許位
- EX0=1; //打開外部中斷0允許位
- PT0=1; //設(shè)置內(nèi)部定時(shí)中斷優(yōu)先級(jí)大于外部中斷優(yōu)先級(jí)
- EA=1; //打開中斷總允許位
- BEEP=1;
- flag_nao=0;
- while(1)
- {
- static uChar h=0;
- nao_judge();
- if(Key4==0)
- {
- Delayms(10);
- if(Key4==0)
- while(!Key4); //空操作,等待按鍵釋放
- h++;
- }
- if(h%2==1)
- {
- Dispaly2(day,month,year);
- Keyscan2();
- }
- if(h%2==0)
- {
- Dispaly1(second,minute,hour);
- nao_judge();
- Keyscan1();
- }
- }
- }
- //長(zhǎng)延時(shí)函數(shù)
- void Delayms(uInt t)
- {
- uInt i,j;
- for(i=0;i<t;i++)
- for(j=0;j<125;j++)
- ;
- }
- //時(shí)-分-秒顯示
- void Dispaly1(uChar second,uChar minute,uChar hour)
- {
- P0=b[0];
- P1=a[hour/10];
- Delayms(1);
- P1=0xff;
- P0=b[1];
- P1=a[hour%10];
- Delayms(1);
- P1=0xff;
- P0=b[2];
- P1=0xbf;
- Delayms(1);
- P1=0xff;
- P0=b[3];
- P1=a[minute/10];
- Delayms(1);
- P1=0xff;
- P0=b[4];
- P1=a[minute%10];
- Delayms(1);
- P1=0xff;
- P0=b[5];
- P1=0xbf;
- Delayms(1);
- P1=0xff;
- P0=b[6];
- P1=a[second/10];
- Delayms(1);
- P1=0xff;
- P0=b[7];
- P1=a[second%10];
- Delayms(1);
- P1=0xff;
- }
- //年-月-日顯示
- void Dispaly2(uChar day,uChar month,uInt year)
- {
- P0=b[7];
- P1=a[day%10];
- Delayms(1);
- P1=0xff;
- P0=b[6];
- P1=a[day/10];
- Delayms(1);
- P1=0xff;
- P0=b[5];
- P1=a[month%10]&0x7f;
- Delayms(1);
- P1=0xff;
- P0=b[4];
- P1=a[month/10];
- Delayms(1);
- P1=0xff;
- P0=b[3];
- P1=a[year%10]&0x7f;
- Delayms(1);
- P1=0xff;
- P0=b[2];
- P1=a[(year%100)/10];
- Delayms(1);
- P1=0xff;
- P0=b[1];
- P1=a[(year/100)%10];
- Delayms(1);
- P1=0xff;
- P0=b[0];
- P1=a[(year/1000)];
- Delayms(1);
- P1=0xff;
- }
- //按鍵Key4按下次數(shù)為雙數(shù)時(shí)(控制時(shí)-分-秒),按鍵Key1~3的控制
- void Keyscan1()
- {
- static uChar i=0,j=0; //static-保存變量數(shù)據(jù),不會(huì)清零
- if(Key1==0)
- {
- Delayms(10); //消抖
- if(Key1==0)
- while(!Key1); //等待按鍵彈起
- i++;
- }
- if(i%2==1) //若Key1按下次數(shù)為單數(shù)時(shí),停止計(jì)數(shù)
- {
- LED1=0;
- TR0=0;
- }
- if(i%2==0) //若Key1按下次數(shù)為雙數(shù)時(shí),開始計(jì)數(shù)
- {
- LED1=1;
- TR0=1;
- }
-
- if(Key2==0) //按鍵Key2選擇調(diào)位
- {
- Delayms(10);
- if(Key2==0)
- while(!Key2);
- j++;
- }
- if(j%4==1) //按鍵按下一次
- {
- Second_flicker(second,minute,hour); //秒顯示位閃爍
- if(Key3==0)
- {
- Delayms(10);
- if(Key3==0) //按鍵Key3進(jìn)行選定位加一
- while(!Key3);
- second++;
- if(second==60)
- second=0;
- }
- }
- if(j%4==2)//按鍵按下兩次
- {
- Minute_flicker(second,minute,hour); //分顯示位閃爍
- if(Key3==0)
- {
- Delayms(10);
- if(Key3==0)
- while(!Key3);
- minute++;
- if(minute==60)
- minute=0;
- }
- }
- if(j%4==3)//按鍵按下三次
- {
- Hour_flicker(second,minute,hour); //時(shí)顯示位閃爍
- if(Key3==0)
- {
- Delayms(10);
- if(Key3==0)
- while(!Key3);
- hour++;
- if(hour==24)
- hour=0;
- }
- }
- }
- //按鍵Key4按下次數(shù)為單數(shù)時(shí)(控制年-月-日),按鍵Key1~3的控制
- void Keyscan2()
- {
- static uChar m=0,n=0;
- if(Key1==0)
- {
- Delayms(10);
- if(Key1==0)
- while(!Key3);
- m++;
- }
- if(m%2==1)
- {
- LED1=0;
- TR0=0;
- }
- if(m%2==0)
- {
- LED1=1;
- TR0=1;
- }
- if(Key2==0)
- {
- Delayms(10);
- if(Key2==0)
- while(!Key2);
- n++;
- }
- if(n%4==1)
- {
- Day_flicker(day,month,year); //日顯示位閃爍
- if(Key3==0)
- {
- Delayms(10);
- if(Key3==0)
- while(!Key3);
- day++;
- if(day==32)
- day=1;
- }
- }
- if(n%4==2)
- {
- Month_flicker(day,month,year); //月顯示位閃爍
- if(Key3==0)
- {
- Delayms(10);
- if(Key3==0)
- while(!Key3);
- month++;
- if(month==13)
- month=1;
- }
- }
- if(n%4==3)
- {
- Year_flicker(day,month,year); //年顯示位閃爍
- if(Key3==0)
- {
- Delayms(10);
- if(Key3==0)
- while(!Key3);
- year++;
- if(year==10000)
- year=0;
- }
- }
- }
- //判斷鬧鐘,當(dāng)時(shí)間和設(shè)置鬧鐘時(shí)間相等時(shí),鬧鈴響5S
- void nao_judge()
- {
- if(flag_nao==1) //如果flag_nao為真,鬧鐘開啟
- {
- if((minute==f_nao)&&(hour==s_nao)) //判斷實(shí)時(shí)時(shí)間和鬧鐘時(shí)間的分、時(shí)是否同時(shí)相等
- {
- while(second<5&&flag_nao) //如果second<=5和flag_nao都為真,鬧鈴響5s
- {
- BEEP=0; //TR1=1; //開啟T0
- Dispaly1(second,minute,hour);
- }
- }
- }
- BEEP=1;
- }
- //定時(shí)器中斷0,時(shí)鐘計(jì)數(shù)(不斷執(zhí)行)
- void time0_int(void) interrupt 1
- {
- TH0=(65536-10000)/256;
- TL0=(65536-10000)%256;
- count++;
- if(count==100)
- {
- count=0;
- second++;
- if(second==60)
- {
- second=0;
- minute++;
- if(minute==60)
- {
- minute=0;
- hour++;
- if(hour==24)
- {
- hour=0;
- day++;
- if(day==32)
- {
- day=1;
- month++;
- if(month==13)
- {
- month=1;
- year++;
- if(year==10000)
- {
- year=0;
- }
- }
- }
- }
- }
- }
- }
- }
- //外部中斷0,鬧鐘開關(guān),控制flag_nao,按下K3關(guān)閉鬧鐘
- void guan_naozhong() interrupt 0
- {
- flag_nao=~flag_nao;
- LED2=~LED2;
- TR1 = 0; //K3按下,開啟外部中斷0,關(guān)閉定時(shí)器中斷1,鬧鐘停止響鈴
- while(!K3)
- Dispaly1(second,minute,hour);
- }
- //外部中斷1,調(diào)節(jié)鬧鐘時(shí)間
- void naozhong() interrupt 2
- {
- static uChar n=0;
- // s_nao=12; //設(shè)置鬧鐘時(shí)鐘初始值
- // f_nao=31; //設(shè)置鬧鐘分鐘初始值
- while(K2) //等待按下K2退出,否則循環(huán)執(zhí)行鬧鐘時(shí)間設(shè)置
- {
- Dispaly1(0,f_nao,s_nao); //顯示鬧鐘設(shè)置
- if(Key2==0) //鬧鐘調(diào)位調(diào)時(shí)鐘、分鐘
- {
- Delayms(10);
- if(Key2==0)
- while(!Key2);
- n++;
- }
- if(n%2==1) //調(diào)節(jié)鬧鐘時(shí)鐘
- {
- if(K1==0)
- {
- Dispaly1(0,f_nao,s_nao);
- if(K1==0)
- {
- if(s_nao==23)
- s_nao=0;
- else s_nao++;
- }
- while(!K1)
- Dispaly1(0,f_nao,s_nao);
- }
- }
- if(n%2==0) //調(diào)節(jié)鬧鐘分鐘
- {
- if(K1==0)
- {
- Dispaly1(0,f_nao,s_nao);
- if(K1==0)
- {
- if(f_nao==59)
- f_nao=0;
- else f_nao++;
- }
- while(!K1)
- Dispaly1(0,f_nao,s_nao);
- }
- }
- }
- }
-
- /************************************************/
- /****************調(diào)位時(shí)選擇位閃爍****************/
- /************************************************/
- //短延時(shí)
- void delay(uInt t)
- {
- uInt i;
- for(i=0;i<t;i++)
- ;
- }
- //數(shù)碼管0~7位分別顯示時(shí)-分-秒
- void Bright1(uChar second,uChar minute,uChar hour)
- {
- uChar p,k=10;
- for(p=0;p<50;p++)
- {
- P0=b[0];
- P1=a[hour/10];
- delay(k);
- P1=0xff;
- P0=b[1];
- P1=a[hour%10];
- delay(k);
- P1=0xff;
- P0=b[2];
- P1=0xbf;
- delay(k);
- P1=0xff;
- P0=b[3];
- P1=a[minute/10];
- delay(k);
- P1=0xff;
- P0=b[4];
- P1=a[minute%10];
- delay(k);
- P1=0xff;
- P0=b[5];
- P1=0xbf;
- delay(k);
- P1=0xff;
- P0=b[6];
- P1=a[second/10];
- delay(k);
- P1=0xff;
- P0=b[7];
- P1=a[second%10];
- delay(k);
- P1=0xff;
- }
- }
- //秒顯示位閃爍
- void Second_flicker(uChar second,uChar minute,uChar hour)
- {
- uChar p,k=10;
- Bright1(second,minute,hour);
- for(p=0;p<50;p++)
- {
- P0=b[0];
- P1=a[hour/10];
- delay(k);
- P1=0xff;
- P0=b[1];
- P1=a[hour%10];
- delay(k);
- P1=0xff;
- P0=b[2];
- P1=0xbf;
- delay(k);
- P1=0xff;
- P0=b[3];
- P1=a[minute/10];
- delay(k);
- P1=0xff;
- P0=b[4];
- P1=a[minute%10];
- delay(k);
- P1=0xff;
- P0=b[5];
- P1=0xbf;
- delay(k);
- P1=0xff;
- P0=b[6]; //該位數(shù)碼管滅
- P1=0xff;
- delay(k);
- P0=b[7]; //該位數(shù)碼管滅
- P1=0xff;
- delay(k);
- }
- }
- //分顯示位閃爍
- void Minute_flicker(uChar second,uChar minute,uChar hour)
- {
- uChar p,k=10;
- Bright1(second,minute,hour);
- for(p=0;p<50;p++)
- {
- P0=b[0];
- P1=a[hour/10];
- delay(k);
- P1=0xff;
- P0=b[1];
- P1=a[hour%10];
- delay(k);
- P1=0xff;
- P0=b[2];
- P1=0xbf;
- delay(k);
- P1=0xff;
- P0=b[3]; ////熄滅
- P1=0xff;
- delay(k);
- P0=b[4]; ////熄滅
- P1=0xff;
- delay(k);
- P0=b[5];
- P1=0xbf;
- delay(k);
- P1=0xff;
- P0=b[6];
- P1=a[second/10];
- delay(k);
- P1=0xff;
- P0=b[7];
- P1=a[second%10];
- delay(k);
- P1=0xff;
- }
- }
- //時(shí)顯示位閃爍
- void Hour_flicker(uChar second,uChar minute,uChar hour)
- {
- uChar p,k=10;
- Bright1(second,minute,hour);
- for(p=0;p<50;p++)
- {
- P0=b[0]; ////熄滅
- P1=0xff;
- delay(k);
- P0=b[1]; ////熄滅
- P1=0xff;
- delay(k);
- P0=b[2];
- P1=0xbf;
- delay(k);
- P1=0xff;
- P0=b[3];
- P1=a[minute/10];
- delay(k);
- P1=0xff;
- P0=b[4];
- P1=a[minute%10];
- delay(k);
- P1=0xff;
- P0=b[5];
- P1=0xbf;
- delay(k);
- P1=0xff;
- P0=b[6];
- P1=a[second/10];
- delay(k);
- P1=0xff;
- P0=b[7];
- P1=a[second%10];
- delay(k);
- P1=0xff;
- }
- }
- //數(shù)碼管0~7位分別顯示年-月-日
- void Bright2(uChar day,uChar month,uInt year)
- {
- uChar p,k=10;
- for(p=0;p<50;p++)
- {
- P0=b[7];
- P1=a[day%10];
- delay(k);
- P1=0xff;
- P0=b[6];
- P1=a[day/10];
- delay(k);
- P1=0xff;
- P0=b[5];
- P1=a[month%10]&0x7f;
- delay(k);
- P1=0xff;
- P0=b[4];
- P1=a[month/10];
- delay(k);
- P1=0xff;
- P0=b[3];
- P1=a[year%10]&0x7f;
- delay(k);
- P1=0xff;
- P0=b[2];
- P1=a[(year%100)/10];
- delay(k);
- P1=0xff;
- P0=b[1];
- P1=a[(year/100)%10];
- delay(k);
- P1=0xff;
- P0=b[0];
- P1=a[(year/1000)];
- delay(k);
- P1=0xff;
- }
- }
- //日顯示位閃爍
- void Day_flicker(uChar day,uChar month,uInt year)
- {
- uChar p,k=10;
- Bright2(day,month,year);
- for(p=0;p<50;p++)
- {
- P0=b[7]; ////熄滅
- P1=0xff;
- delay(k);
- P0=b[6]; ////熄滅
- P1=0xff;
- delay(k);
- P0=b[5];
- P1=a[month%10]&0x7f;
- delay(k);
- P1=0xff;
- P0=b[4];
- P1=a[month/10];
- delay(k);
- P1=0xff;
- P0=b[3];
- P1=a[year%10]&0x7f;
- delay(k);
- P1=0xff;
- P0=b[2];
- P1=a[(year%100)/10];
- delay(k);
- P1=0xff;
- P0=b[1];
- P1=a[(year/100)%10];
- delay(k);
- P1=0xff;
- P0=b[0];
- P1=a[(year/1000)];
- delay(k);
- P1=0xff;
- }
- }
- //月顯示位閃爍
- void Month_flicker(uChar day,uChar month,uInt year)
- {
- uChar p,k=10;
- Bright2(day,month,year);
- for(p=0;p<50;p++)
- {
- P0=b[7];
- P1=a[day%10];
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
萬年歷-原理圖 功能介紹 程序 PCB.zip
(14.17 MB, 下載次數(shù): 158)
2019-1-19 20:18 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|