注:獲取全套設計資源,請見文末說明~
設計要求
1.顯示公歷年、月、日、星期、時、分、秒;
2.可隨時調校年、月、日、時、分、秒;
3.能顯示農(nóng)歷時間,并能標明平潤年;
4.具有鬧鐘設定提醒功能;
5.能夠顯示當前環(huán)境溫度;
系統(tǒng)概述
電子萬年歷系統(tǒng)以AT89C52單片機為核心,構成單片機控制電路,結合DS1302時鐘芯片和DS18B20溫度傳感器,完成時間和溫度的讀取,全部信息由LCD1602液晶實時顯示。
日歷時間的校準和鬧鐘的設定均由四個獨立按鍵來實現(xiàn),日歷能顯示公歷和農(nóng)歷的年、月、日以及星期、時、分、秒,在顯示農(nóng)歷年時,還能標明平潤年。
整個系統(tǒng)的由以下幾個模塊組成,如下圖所示。

原理圖

仿真電路圖


仿真分析
打開Proteus仿真文件,文件后綴名為DSN。雙擊單片機,加載WanNianLi.hex文件(位于Keil C程序文件夾中),運行仿真,結果如下圖所示。

上圖可以看出,LCD顯示的時間信息與DS1302 Clock-U3窗口完全一致,表明單片機成功讀取DS1302芯片數(shù)據(jù)。當前日期為2020年10月9日星期五,時間為21點30分39秒,溫度為31.0℃。
設置時間的操作為:點擊“設置”鍵,秒針閃爍,此時可以通過“加鍵”和“減鍵”進行增減調整,秒針設置如下所示。

秒針設置完成后,再次點擊“設置”鍵,分針閃爍,繼續(xù)通過加減鍵進行設置,以此類推,來設置小時、日、月和年,年(范圍可到2099年)設置完成后,再次按下“設置”鍵,退出時間的設置,回到LCD正常顯示界面。
點擊“農(nóng)歷/鬧鐘”按鍵,顯示當前日期的農(nóng)歷日期,以及平潤年(平年:PING 閏年:RUN),如下圖所示,公歷2020年10月9日所對應的農(nóng)歷日為8月23,且2020年為閏年,公歷農(nóng)歷轉換信息準確無誤。

再次點擊“農(nóng)歷/鬧鐘”鍵,顯示鬧鐘時間,以及鬧鐘的開關狀態(tài)(ON:表示鬧鐘開,OFF:表示鬧鐘關),圖中系統(tǒng)默認鬧鐘時間為01:01,鬧鐘處于打開狀態(tài)ON。

設置鬧鐘操作為:在當前鬧鐘顯示界面下,點擊“設置”鍵,鬧鐘的小時數(shù)閃爍,通過“加鍵”和“減鍵”調整小時數(shù),小時數(shù)設置好后,再次點擊“設置”鍵,分鐘閃爍,進入分鐘數(shù)的設置。
同理,分鐘數(shù)設置好后,再次點擊“設置”鍵,需要注意的是,在設定鬧鐘開關時,沒有光標閃爍。點擊“加鍵”或“減鍵”,設置鬧鐘的打開與關閉,ON與OFF之間切換。
以上都設置好后,再點擊“設置”鍵,ON或OFF閃爍一下,表示鬧鐘設定完成。此時按下“農(nóng)歷/鬧鐘”鍵退出鬧鐘界面,回到時間正常顯示的界面。
例如,設置鬧鐘時間為早上8:30,鬧鐘打開,狀態(tài)為ON,結果如下。

鬧鐘定時到后,蜂鳴器發(fā)聲,鬧鐘響;鬧鐘可以通過點擊“加鍵”或“減鍵”或“農(nóng)歷/鬧鐘”鍵來關閉。
通過點擊DS18B20模塊的紅色向上、向下箭頭,可以模擬溫度的改變,LCD液晶實時顯示當前溫度值。例如設定溫度22.0℃,如圖所示。

綜上所述,電子萬年歷Proteus仿真設計運行效果滿足設計要求。
部分C代碼
void main()
{
init_eeprom(); //開始初始化保存的數(shù)據(jù)
P1=0xff;
// flag=ReadTemperature();
// delay(2000);
lcd_init(); //調用液晶屏初始化子函數(shù)
ds1302_init(); //調用DS1302時鐘的初始化子函數(shù)
init(); //調用定時計數(shù)器的設置子函數(shù)
led1=0; //打開LCD的背光電源
buzzer=0; //蜂鳴器長響一次
delay(100);
buzzer=1;
init_eeprom();
while(1) //無限循環(huán)下面的語句:
{
keyscan(); //調用鍵盤掃描子函數(shù)
led=led1;
if(timerOn==1)
alarm(); //鬧鐘輸出
if((fen==0)&&(miao==0))
{
if(shi>12)
temp_hour=shi-12;
else
{
if(shi==0)
temp_hour=12;
else
temp_hour=shi;
}
shangyimiao=miao;
baoshi=1;
}
if(baoshi==1)
{
ZD_baoshi();
do
keyscan();
while(shangyimiao==miao);
shangyimiao=miao;
}
}
}
void timer0() interrupt 1 //取得并顯示日歷和時間
{
//Init_DS18B20();//溫度傳感器DS18b2初始化子函數(shù),在頭文件中
// flag=ReadTemperature();//將18b2頭文件運行返回的函數(shù)結果送到變量FLAG中,用于顯示
//讀取秒時分周日月年七個數(shù)據(jù)(DS1302的讀寄存器與寫寄存器不一樣):
miao = BCD_Decimal(read_1302(0x81));
fen = BCD_Decimal(read_1302(0x83));
shi = BCD_Decimal(read_1302(0x85));
ri = BCD_Decimal(read_1302(0x87));
yue = BCD_Decimal(read_1302(0x89));
nian=BCD_Decimal(read_1302(0x8d));
//week=BCD_Decimal(read_1302(0x8b)); //不讀取,直接通過日期計算得到
if((led1==0))
{
if(temp_miao!=miao)
{
temp_miao=miao;
bltime++;
}
if(bltime==10)
{
led1=1;
bltime=0;
}
}
if(T_NL_NZ==1) //顯示農(nóng)歷
{
uint nian_temp,temp12;
temp12=nian;
nian_temp=2000+(temp12&0xF0)*10+temp12&0x0F;
if((nian_temp%400==0)||((nian_temp%100!=0)&&(nian_temp%4==0))) //判斷是否為閏年
p_r=1;
else
p_r=0;
Conversion(0,nian,yue,ri);
write_1602com(er);//時間顯示固定符號寫入位置?
for(a=0;a<16;a++)
{
if(p_r==0)
write_1602dat(nlp[a]);//寫顯示時間固定符號,兩個冒號
else
write_1602dat(nlr[a]);
}
write_nl(3,year_moon);//農(nóng)歷 年
write_nl(6,month_moon);//農(nóng)歷 月
write_nl(9,day_moon);//農(nóng)歷 日
do
keyscan();
while(T_NL_NZ==1);
write_1602com(er);//時間顯示固定符號寫入位置,從第2個位置后開始顯示
for(a=0;a<16;a++)
{
write_1602dat(qk[a]);//寫顯示時間固定符號,兩個冒號
}
write_1602com(er);//時間顯示固定符號寫入位置,從第2個位置后開始顯示
for(a=0;a<8;a++)
{
write_1602dat(tab2[a]);//寫顯示時間固定符號,兩個冒號
}
}
分享的資源有
(1)基于51單片機的電子萬年歷設計論文完整版;
(2)Altium Designer原理圖文件;
(3)Keil C程序;
(4)Proteus仿真文件;
(5)Visio程序設計流程圖;
(6)畢設任務書;
(7)芯片技術手冊;
(8)元器件清單;
(9)元器件知識介紹;
資源截圖如下






資源獲取方法
資源獲取方法
資源獲取方法
重要的事情說三遍!?。。。。。。。。?!
電子萬年歷設計是我的原創(chuàng)設計,獲取以上所有設計資料,請搜索關注我的公眾號:交院小智