|
本設(shè)計(jì)中,在按鍵處理方面,下了不少功夫,雖然只有三個(gè)按鍵,不同狀態(tài)下,實(shí)現(xiàn)不同的功能.
為了節(jié)省用電,設(shè)計(jì)背景燈有按鍵銨下才亮,延時(shí)5秒后滅.長(zhǎng)按K1進(jìn)入設(shè)置狀態(tài),按K2移位,K3數(shù)字加.依次設(shè)置年月日,星期,時(shí)分秒,鬧鐘1,鬧鐘2.
在走時(shí)狀態(tài)下,按K2顯示鬧鐘1,按K3顯示鬧鐘2,延時(shí)5秒后返回走時(shí).在顯示鬧鐘狀態(tài)下,按K1,開(kāi)關(guān)鬧鐘,顯示"*"為開(kāi).走時(shí)狀態(tài)下顯示"%"為只有一個(gè)鬧鐘開(kāi),顯示"@"為兩個(gè)鬧鐘開(kāi).在鬧鐘響鈴時(shí),按任意鍵關(guān)閉聲音.
制作出來(lái)的原理圖如下:
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機(jī)源程序如下:
- #include "Lcd1602.h"
- #include "KEY.h"
- #include "DS18B20.h"
- #include "DS1302.h"
- uchar T0RH,T0RL;
- bit flag1s = 1; //1秒標(biāo)志
- bit flag200ms = 1; //200毫秒標(biāo)志
- bit beeonoff1=0,beeonoff2=0; //鬧鐘1,2開(kāi)關(guān)標(biāo)志
- bit beeon = 0; //峰鳴開(kāi)關(guān)
- uchar keybee = 0; //按鍵鬧鐘1,2切換
- uchar hourbee1=0x08,minbee1=0x00,hourbee2=0x13,minbee2=0x30; //鬧鐘1,2存放值
- uchar flag = 0; //鬧鐘顯示時(shí)間
- uchar pos = 0; //設(shè)置時(shí)間引索
- sint buftemp; //溫度暫存
- struct sTime {
- uchar year;
- uchar mon;
- uchar day;
- uchar hour;
- uchar min;
- uchar sec;
- uchar week;
- };
- struct sTime buftime;
- void ConfigTimer0(uchar ms);
- void ShowTemp();
- void RefrTime();
- void main()
- {
- bit reg = 0;
- uchar bufsec = 0xaa;
-
- EA = 1;
- ConfigTimer0(2);
- LcdInit();
- DS1302Init();
- Start18B20();
- GainTime(&buftime);
- RefrTime();
- while(1)
- {
- KeyDriver();
- if (!pos)
- {
- if (flag200ms)
- {
- flag200ms = 0;
- GainTime(&buftime);
- if (bufsec != buftime.sec)
- {
- RefrTime();
- bufsec = buftime.sec;
- }
- if (((hourbee1==buftime.hour) && (minbee1==buftime.min) && beeonoff1) || (hourbee2==buftime.hour) && (minbee2==buftime.min) && beeonoff2)
- {
- beeon = 1;
- }
- else
- {
- beeon = 0;
- }
- }
- if (flag1s )
- {
- flag1s = 0;
- reg = Get18B20Temp(&buftemp);
- if (reg)
- {
- ShowTemp();
- }
- Start18B20();
- }
- }
- }
- }
- void ShowTemp() //溫度顯示
- {
- schar i = 0;
- uchar len=0;
- uchar tempint,tempdec; //溫度整數(shù)部分,小數(shù)部分存放
- uchar buf[4],str[6];
- tempint = (buftemp>>4) & 0x7f; //取出整數(shù)部分
- tempdec = buftemp & 0x0f; //取出小數(shù)部分
- do {
- buf[i++] = tempint%10;
- tempint = tempint/10;
- }while (tempint > 0);
- if (i < 2)
- {
- str[len++] = ' ';
- }
- while (i-- > 0)
- {
- str[len++] = buf[i] + '0';
- }
- str[len++] = '.';
- str[len++] = (tempdec*10/16) +'0';
-
- str[len] = '\0';
- LcdShowStr(11,1,str);
- }
- void NumToStr(uchar x,uchar y, uchar *str) //數(shù)據(jù)轉(zhuǎn)換字符
- {
- uchar buf[3];
- buf[0] = (*str>>4) + '0';
- buf[1] = (*str&0x0f) + '0';
- buf[2] = '\0';
- LcdShowStr(x,y,buf);
- }
- void RefrTime() //刷新時(shí)間
- {
- NumToStr(2,0,&buftime.year);
- NumToStr(5,0,&buftime.mon);
- NumToStr(8,0,&buftime.day);
- LcdShowStr(15,0,&buftime.week);
- if (((flag>0) && (keybee ==1)) || ((pos>=14) && (pos<=17))) //鬧鐘1顯示
- {
- NumToStr(2,1,&hourbee1);
- NumToStr(5,1,&minbee1);
- LcdShowStr(8,1,"-1");
- }
- else if (((flag>0) && (keybee ==2)) || ((pos>=18) && (pos<=21))) //鬧鐘2顯示
- {
- NumToStr(2,1,&hourbee2);
- NumToStr(5,1,&minbee2);
- LcdShowStr(8,1,"-2");
- }
- else
- {
- NumToStr(2,1,&buftime.hour);
- NumToStr(5,1,&buftime.min);
- NumToStr(8,1,&buftime.sec);
- if (beeonoff1 && beeonoff2) //如果兩個(gè)鬧鐘開(kāi),則顯示"@"
- LcdShowStr(0,1,"@");
- else if (!beeonoff1 && !beeonoff2) //如果兩個(gè)鬧鐘關(guān),則不顯示,
- LcdShowStr(0,1," ");
- else
- LcdShowStr(0,1,"%"); //如果其中一個(gè)鬧鐘開(kāi),則顯示"%"
- }
- }
- void BeeOnroOff() //鬧鐘開(kāi)關(guān)時(shí)顯示
- {
- if (keybee == 1) //鬧鐘1開(kāi)關(guān)
- {
- beeonoff1 = ~beeonoff1;
- if (beeonoff1)
- {
- LcdShowStr(0,1,"*"); //顯示"*",表示鬧鐘開(kāi)
- }
- else
- {
- LcdShowStr(0,1," ");
- }
- }
- else if (keybee == 2) //鬧鐘2開(kāi)關(guān)
- {
- beeonoff2 = ~beeonoff2;
- if (beeonoff1 || beeonoff2)
- {
- LcdShowStr(0,1,"*");
- }
- else
- {
- LcdShowStr(0,1," ");
- }
- }
- }
- void CurPosit() //光標(biāo)位置,設(shè)置修改的位置
- {
- switch(pos)
- {
- case 1: LcdSetCort(2,0); break; //日期
- case 2: LcdSetCort(3,0); break;
- case 3: LcdSetCort(5,0); break;
- case 4: LcdSetCort(6,0); break;
- case 5: LcdSetCort(8,0); break;
- case 6: LcdSetCort(9,0); break;
- case 7: LcdSetCort(15,0); break; //星期
- case 8: LcdSetCort(2,1); break; //時(shí)間
- case 9: LcdSetCort(3,1); break;
- case 10: LcdSetCort(5,1); break;
- case 11: LcdSetCort(6,1); break;
- case 12: LcdSetCort(8,1); break;
- case 13: LcdSetCort(9,1); break;
- case 14: LcdSetCort(2,1); break; //鬧鐘1
- case 15: LcdSetCort(3,1); break;
- case 16: LcdSetCort(5,1); break;
- case 17: LcdSetCort(6,1); break;
- case 18: LcdSetCort(2,1); break; //鬧鐘2
- case 19: LcdSetCort(3,1); break;
- case 20: LcdSetCort(5,1); break;
- case 21: LcdSetCort(6,1); break;
- default: break;
- }
- }
- void RightShift() //向右移動(dòng)
- {
- if (pos != 0)
- {
- if (pos < 21)
- pos++;
- else
- pos = 1;
- if ((pos==14) || (pos==18) || (pos==1))
- RefrTime();
- CurPosit();
- }
- }
- uchar IncBcdHigh(uchar dat, uchar n) //高位加
- {
- if ((dat&0xf0) < (n<<4))
- dat += 0x10;
- else
- dat &= 0x0f;
- return dat;
- }
- uchar IncBcdLow(uchar dat, uchar n) //低位加
- {
- if ((dat&0x0f) < n)
- dat += 0x01;
- else
- dat &= 0xf0;
- return dat;
- }
- uchar IncBcdWeek(uchar dat, uchar n) //星期加
- {
- if ((dat&0x0f) < n)
- dat += 0x01;
- else
- dat = 1;
- return dat;
- }
- void IncSetTime() //向上(加)
- {
- switch (pos)
- {
- case 1: buftime.year = IncBcdHigh(buftime.year,9); break;
- case 2: buftime.year = IncBcdLow(buftime.year,9); break;
- case 3: buftime.mon = IncBcdHigh(buftime.mon,1); break;
- case 4: buftime.mon = IncBcdLow(buftime.mon,9); break;
- case 5: buftime.day = IncBcdHigh(buftime.day,3); break;
- case 6: buftime.day = IncBcdLow(buftime.day,9); break;
- case 7: buftime.week = IncBcdWeek(buftime.week,7); break;
- case 8: buftime.hour = IncBcdHigh(buftime.hour,2); break;
- case 9: buftime.hour = IncBcdLow(buftime.hour,9); break;
- case 10: buftime.min = IncBcdHigh(buftime.min,5); break;
- case 11: buftime.min = IncBcdLow(buftime.min,9); break;
- case 12: buftime.sec = IncBcdHigh(buftime.sec,5); break;
- case 13: buftime.sec = IncBcdLow(buftime.sec,9); break;
- case 14: hourbee1 = IncBcdHigh(hourbee1,2); break;
- case 15: hourbee1 = IncBcdLow(hourbee1,9); break;
- case 16: minbee1 = IncBcdHigh(minbee1,5); break;
- case 17: minbee1 = IncBcdLow(minbee1,9); break;
- case 18: hourbee2 = IncBcdHigh(hourbee2,2); break;
- case 19: hourbee2 = IncBcdLow(hourbee2,9); break;
- case 20: minbee2 = IncBcdHigh(minbee2,5); break;
- case 21: minbee2 = IncBcdLow(minbee2,9); break;
- default: break;
- }
- RefrTime();
- CurPosit();
- }
- void EntertimeSet() //進(jìn)入時(shí)間設(shè)置
- {
- pos = 21;
- RightShift();
- LcdCoorTwin(); //光標(biāo)閃動(dòng)
- }
- void KeyAction(uchar cod,bit set) //按鍵動(dòng)作
- {
- switch(cod)
- {
- case 0: if (!set)
- {
- if (flag > 0) //鬧鐘延時(shí)顯示狀態(tài)下,則可以設(shè)置鬧鐘開(kāi)關(guān)
- BeeOnroOff();
- pos = 0;
- SetTime(&buftime);
- LcdClsCur(); //光標(biāo)閃動(dòng)清除
- }
- else //進(jìn)入設(shè)置
- {
- flag = 0; //延時(shí)顯示時(shí)間清零
- EntertimeSet();
- }
- break;
- case 1: if (!set && (pos==0)) //非設(shè)置狀態(tài),顯示鬧鐘1
- {
- keybee = 1;
- flag = 3; //延時(shí)6秒計(jì)算
- if (beeonoff1)
- {
- LcdShowStr(0,1,"*"); //顯示鬧鐘標(biāo)志
- }
- else
- {
- LcdShowStr(0,1," ");
- }
- RefrTime();
- }
- else if (pos!=0) //設(shè)置狀態(tài),數(shù)字移動(dòng)
- {
- RightShift();
- }
- break;
- case 2: if (!set && (pos==0)) //非設(shè)置狀態(tài),顯示鬧鐘2
- {
- keybee = 2;
- flag = 3; //延時(shí)6秒計(jì)算
- if (beeonoff2)
- {
- LcdShowStr(0,1,"*"); //顯示鬧鐘標(biāo)志
- }
- else
- {
- LcdShowStr(0,1," ");
- }
- RefrTime();
- }
- else if (pos!=0) //設(shè)置狀態(tài),數(shù)字加
- {
- IncSetTime();
- }
- break;
- }
- }
- void LedLigh(bit ledt) //背影燈開(kāi)啟
- {
- static bit ledflag = 0;
- static uint ledcou=0;
- if (ledt)
- {
- ledflag = 1;
- ledcou = 3000;
- LED = 0;
- }
- if (ledflag)
- {
- if (ledcou > 0)
- {
- ledcou--;
- }
- else
- {
- ledflag = 0;
- LED = 1;
- }
- }
- }
- void AlarmClock(bit on, bit beet) //鬧鐘發(fā)聲 on 鬧鐘觸發(fā)開(kāi)關(guān),beet為按鍵暫時(shí)關(guān)
- {
- static bit off = 0;
- static uchar alcou=0;
- if (on)
- {
- if (beet)
- off = 1;
- if (!off)
- {
- alcou++;
- if (alcou == 255)
- {
- alcou = 0;
- }
- if (alcou > 150)
- {
- BEE = ~BEE;
- }
- }
- else
- {
- BEE = 1;
- }
- }
- else
- {
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
所有資料51hei提供下載:
自制小型萬(wàn)年歷.zip
(440.2 KB, 下載次數(shù): 150)
2018-7-27 19:14 上傳
點(diǎn)擊文件名下載附件
|
評(píng)分
-
查看全部評(píng)分
|