課程設計(論文)以AT89S51單片機為核心的數(shù)字電子鐘控制器_第1頁
課程設計(論文)以AT89S51單片機為核心的數(shù)字電子鐘控制器_第2頁
課程設計(論文)以AT89S51單片機為核心的數(shù)字電子鐘控制器_第3頁
課程設計(論文)以AT89S51單片機為核心的數(shù)字電子鐘控制器_第4頁
課程設計(論文)以AT89S51單片機為核心的數(shù)字電子鐘控制器_第5頁
已閱讀5頁,還剩13頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、一、設計題目:設計一個以at89s51單片機為核心的數(shù)字電子鐘控制器,實現(xiàn)電子鐘的時間、日期交替顯示、鬧鐘功能,并可通過按鈕開關或鍵盤切換顯示內容、調整參數(shù)、設置鬧鐘,在單片機實驗板上模擬調試實現(xiàn)控制器的功能。二、設計目的:通過單片機應用產品的設計與調試過程,鞏固課程所學理論知識,初步了解單片機應用系統(tǒng)設計與調試的方法。三、設計要求:1開機自檢,檢查相關接口及數(shù)碼管顯示器、指示燈、蜂鳴器等外設是否正常。28位數(shù)碼管顯示器平常以一定的時間間隔、合適的格式顯示時間和日期信息,時間顯示時、分、秒;日期顯示年(20002099)、月、日;設置鬧鐘功能時顯示時、分、開/關狀態(tài)。3可通過按鍵設定時間、日期

2、、鬧鐘等參數(shù)、手動切換顯示。按鍵可用獨立式按鍵或行列式鍵盤實現(xiàn)。設定參數(shù)過程有合適的方式指示當前可修改的內容。4對開關量輸入進行軟件消抖動處理,參數(shù)的設定有容錯處理,如:小時不能超過23,日期中每月最大天數(shù)、閏年等。5用protel設計可實現(xiàn)上述功能的控制器的原理圖(最小應用系統(tǒng))。四、總體方案設計及說明:本設計電子時鐘系統(tǒng),主控芯片采用at89s51芯片。配合軟件延時實現(xiàn)時、分、秒的計時。本系統(tǒng)設計采用此種軟件控制方法來實現(xiàn)計時,通過定時器定時中斷,使時間緩存單元數(shù)據(jù)加一,提供系統(tǒng)時間。同時可以通過獨立鍵盤對電子時鐘開始計時,暫停計時和結束計時的控制。單片機內的數(shù)據(jù)通過并行i/o接口輸入輸出

3、。并驅動八位led數(shù)碼管(時、分、秒分別用2位數(shù)碼管顯示),動態(tài)顯示數(shù)據(jù)。晶振及復位電路為單片機提供工作脈沖及復位信號。 五、系統(tǒng)資源分配說明:接口電路邏輯圖:使用定時計數(shù)器0,tmod設置為0x01;晶振頻率11.0592mhz下,定時50ms的計數(shù)初值經過計算為4c00h(216-46080=4c00h),th0設置為0x4c,tl0設置為0x00。五、軟件流程圖及說明:1.鬧鐘顯示開 始鬧鐘是否打開后6位數(shù)碼管分別顯示“-”、小時的2位、“-”分鐘的2位前2位數(shù)碼管顯示op前2位數(shù)碼管顯示cl是否按鍵掃描,判斷有沒有按鍵,若有按鍵則退出鬧鐘顯示退 出鬧鐘顯示子程序,8個數(shù)碼管顯示已經設置

4、好的鬧鐘時間,進行按鍵掃描,判斷有沒有按鍵,若有就去執(zhí)行相應的功能,日期顯示子程序和時間顯示子程序和鬧鐘顯示子程序類似。2.鍵盤子程序按鍵掃描: 功能掃描:開 始設置pc3pc0為輸入,pc7pc4為輸出,所有行(pc7pc4)置0,讀取列值設置pc3pc0為輸出,pc7pc4為輸入,所有列(pc3pc0)置0,讀取行值keyin=keyin_j|keyin_i;形成行列組合結 束開 始設置pc3pc0為輸入,pc7pc4為輸出,所有行(pc7pc4)置0,讀取鍵盤無鍵按下,返回0 有鍵按下,返回1結 束3.中斷子程序開 始設置定時50ms的初值為4c00h中斷20次,秒單元加160秒到?秒單

5、元清零,分單元加160分鐘到?分單元清零,時單元加124小時到?時單元清零,日單元加11個月到?日單元清零,月單元加11年到?月單元清零,年單元加1將小時(time.hour)除以10,商賦給77h(動態(tài)顯示對應的小時十位),余數(shù)賦給78h(動態(tài)顯示對應的小時個位)將分鐘(time.minute)除以10,商賦給7ah(動態(tài)顯示對應的小時十位),余數(shù)賦給7bh(動態(tài)顯示對應的小時個位)將秒(time.second)除以10,商賦給7dh(動態(tài)顯示對應的小時十位),余數(shù)賦給7eh(動態(tài)顯示對應的小時個位)int0輸入低電平,打開鬧鐘結 束六、系統(tǒng)功能與操作說明:數(shù)字時鐘能顯示實時時間(hh-mm

6、-ss)、日期(20yy.mm.dd)于led數(shù)碼管,并可以修改時間、日期。可以設置鬧鐘,時間到時,蜂鳴器會響起。按切換鍵可以在時間、日期、鬧鐘時間中切換。時間、日期、鬧鐘時間可調,按外部中斷鍵時間暫停,進入時間、日期、鬧鐘時間設置,此時可以矩陣鍵盤輸入時間日期,輸入完后確認鍵時間按照設置的值接著走。鍵盤用行列式鍵盤,按鍵定義如下圖所示。主要的按鍵有:(1)數(shù)字鍵“0”“9”,用于設置時輸入時間和日期,正常工作時無效。(2)“時間設置”、“日期設置”、“鬧鐘設置”,用于進入相應功能的設置狀態(tài)。(3)“鬧鐘開關”在鬧鐘設置狀態(tài)時,用于設置鬧鐘開或關,正常工作時,用于手動關鬧鈴的聲音。(4)“確認

7、”用于設置參數(shù)的確認,并檢查參數(shù)是否合理,如果符合要求,則參數(shù)有效;否則本次修改無效,保持原值。正常工作情況下按該鍵無操作。(5)“顯示切換”用于正常工作時手動切換時間、日期的顯示。七、調試記錄:1、確定課程設計課題為數(shù)字電子鐘,并查找相關資料。2、熟悉實驗板數(shù)碼管、兩個8255、鍵盤、led等硬件資源的使用,弄清楚其對應的地址。3、調試出可以掃描矩陣鍵盤輸入的數(shù)的程序,并在數(shù)碼管上顯示出來當前按下的鍵值。4、調試出可以顯示時分秒和日期的時鐘程序,并可以通過4個按鍵進行控制(分別為進入退出時間設置、時增1、分增1、秒增1),并可以切換時間和日期。5、調試鬧鐘的顯示和設置程序,時間到了所設置的時

8、間時蜂鳴器響起。6、時間可以走,但只能通過在程序中給對應時間日期字節(jié)地址預先設置初始值,時鐘根據(jù)該初始時間接著走,不能通過矩陣鍵盤輸入時間日期。最后查閱資料并詢問同學終于解決了這個問題。7、對整個程序做進一步優(yōu)化處理,使其更穩(wěn)定,修改其中的一些瑕疵,加上注釋,方便以后讀程序。八、實驗設計總結:通過努力終于設計出一個以at89s51單片機為核心的數(shù)字電子鐘控制器,實現(xiàn)電子鐘的時間、日期交替顯示、鬧鐘功能,并可通過按鈕開關或鍵盤切換顯示內容、調整參數(shù)、設置鬧鐘。 這次實驗我收獲了許多,得到了許多書本上學不到的知識。1、單片機的軟件設計通常要考慮以下幾個方面的問題:(1)根據(jù)軟件功能要求,將系統(tǒng)軟件

9、劃分為若干個相對獨立的部分,設計出合理的總體結構,使軟件開發(fā)清晰、簡潔和流程合理;(2)培養(yǎng)良好的編程風格,如考慮結構化程序設計、實行模塊化、子程序化。既便于調試、鏈接,又便于移植和修改;(3)繪制程序流程圖,再根據(jù)流程圖寫程序;(4)合理分配系統(tǒng)資源;(5)為程序加入注釋,提高可讀性,便于以后修改移植復用;2、關于程序的調試問題:(1)軟件程序的調試應先分模塊調試,統(tǒng)調是最后一環(huán)。通過各個模塊程序的調試,使程序逐漸趨于完整、正確,最后將各個模塊組合起來,統(tǒng)調程序。(2)充分利用實驗板上的其他空余硬件資源來協(xié)助調試程序,比如,可以用cpl p1.x 來設置指示燈,用來指示有沒有調用鍵盤掃描子程

10、序、用來指示有沒有掃描到鍵值、用來指示外部中斷、定時器0和定時器1有沒有工作等等。附錄:#include #include #define pa xbyte0x0fefc#define pb xbyte0x0fefd#define pc xbyte0x0fefe#define ctl xbyte0x0feff#define uchar unsigned charuchar ms20;sbit sound=p32;uchar open1=-1;/鬧鐘關閉code led19=0x0c0,0x0f9,0x0a4,0x0b0,0x99,0x92,0x82,0x0f8,0x80,0x90,0x88,0

11、x83,0x0c6,0x0a1,0x86,0x8e,0x0bf,0x8c,0x0c7;code table16=0x7e,0x0ee,0x0ed,0x0eb,0x0de,0x0dd,0x0db,0x0be,0x0bd,0x0bb,0x0e7,0x0d7,0x0b7,0x77,0x7b,0x7d; struct uchar hour; uchar minute; uchar second; uchar hour1;/鬧鐘小時 uchar minute1;/鬧鐘分鐘 int year; uchar month; uchar day;time=23,59,55,00,00,2011,11,11;vo

12、id delay() uchar i; for(i=0;i200;i+); /*200個時鐘周期*/ void scan(uchar x) uchar i,tb,tc=0x80; for(i=0;i=1; /*右移一位*/ delay(); int fastfound()uchar keyin; ctl=0x81; /pc3pc0為輸入,pc7pc4為輸出pc=0x0f; /所有行(pc7pc4)置0 keyin=pc; /讀取鍵盤 if(keyin=0x0f) return 0;/無鍵按下,返回0 else return 1; /有鍵按下,返回1int keyfound() uchar ke

13、yvalue,keyin_i,keyin_j,keyin; uchar i; ctl=0x81;/pc3pc0為輸入,pc7pc4為輸出 pc=0x0f; keyin_j=pc;/讀取列值 ctl=0x88;/pc3pc0為輸出,pc7pc4(所有行)為輸入 pc=0x0f0; keyin_i=pc;/讀取行值 keyin=keyin_j|keyin_i; /形成行列組合 for(i=0;i16;i+) if(tablei=keyin) keyvalue=i; break; return keyvalue;void showclock() /顯示鬧鐘 int a; uchar key=1; w

14、hile(key=1) key=fastfound();/消除按功能鍵時產生的影響 for(a=0;a800;a+) if(open1=1) dbyte0x57=0; dbyte0x58=17;/顯示p,與前一個單元組合成op,表示鬧鐘已經打開 else dbyte0x57=0x0c; dbyte0x58=18;/顯示l,與前一個單元組合成cl,表示鬧鐘已經關閉 dbyte0x59=0x10; dbyte0x5a=time.hour1/10; dbyte0x5b=time.hour1%10; dbyte0x5c=0x10; dbyte0x5d=time.minute1/10; dbyte0x5

15、e=time.minute1%10; scan(0x57);if(fastfound()=1) key=keyfound(); if(key=0x0a) break; void rq() /顯示日期int a; uchar key=1; while(key=1) key=fastfound();/消除按功能鍵時產生的影響 for(a=0;a800;a+) dbyte0x47=time.year/1000; dbyte0x48=time.year%1000/100; dbyte0x49=time.year%100/10; dbyte0x4a=time.year%10; dbyte0x4b=tim

16、e.month/10; dbyte0x4c=time.month%10; dbyte0x4d=time.day/10; dbyte0x4e=time.day%10;x scan(0x47); if(fastfound()=1)/有鍵按下 key=keyfound();/獲得鍵值 if(key=0x0a) /如果又按了顯示切換鍵,則顯示鬧鐘時間 showclock(); break; uchar isleap(int x) /判斷閏年if(x%4=0 & x%100!=0) | (x%400=0) return 1; else return 0;void datechange() while(1

17、) if(time.month=1 & time.day31) time.day+;break; if(time.month=1 & time.day=31) time.month+;time.day=1;break; if(isleap(time.year) /是閏年 if(time.month=2 & time.day29) time.day+;break; if(time.month=2 & time.day=29) time.month+;time.day=1;break; else /不是閏年 if(time.month=2 & time.day28) time.day+;break

18、; if(time.month=2 & time.day=28) time.month+;time.day=1;break; if(time.month=3 & time.day31) time.day+;break; if(time.month=3 & time.day=31) time.month+;time.day=1;break; if(time.month=4 & time.day30) time.day+;break; if(time.month=4 & time.day=30) time.month+;time.day=1;break; if(time.month=5 & tim

19、e.day31) time.day+;break; if(time.month=5 & time.day=31) time.month+;time.day=1;break; if(time.month=6 & time.day30) time.day+;break; if(time.month=6 & time.day=30) time.month+;time.day=1;break; if(time.month=7 & time.day31) time.day+;break; if(time.month=7 & time.day=31) time.month+;time.day=1;brea

20、k; if(time.month=8 & time.day31) time.day+;break; if(time.month=8 & time.day=31) time.month+;time.day=1;break; if(time.month=9 & time.day30) time.day+;break; if(time.month=9 & time.day=30) time.month+;time.day=1;break; if(time.month=10 & time.day31) time.day+;break; if(time.month=10 & time.day=31) t

21、ime.month+;time.day=1;break; if(time.month=11 & time.day30) time.day+;break; if(time.month=11 & time.day=30) time.month+;time.day=1;break; if(time.month=12 & time.day31) time.day+;break; if(time.month=12 & time.day=31) time.month=1;if(time.year!=2099) time.year+;break; uchar checkall(uchar x)uchar i

22、,h,m,s,month,d; int y; if(x=0x0c)/對鬧鐘設置進行判斷 for(i=3;i24 | (h=24 & (h!=0 | s!=0) return 0; if(m=60) return 0; return 1;/按鍵合法返回1 if(x=0x0f)/對時間設置進行判斷 for(i=0;i24 | (h=24 & (h!=0 | s!=0) return 0; if(m=60) return 0; if(s=60) return 0; return 1;/按鍵合法返回1 if(x=0x0e)/對日期設置進行判斷 for(i=0;i8;i+) if(dbyte0x57+i

23、=0x10) return 0;/如果按鍵不是數(shù)字,結束 y=dbyte0x57*1000+dbyte0x58*100+dbyte0x59*10+dbyte0x5a; month=dbyte0x5b*10+dbyte0x5c; d=dbyte0x5d*10+dbyte0x5e; if(y2099) return 0; if(month=0 | month12) return 0; if(d=0 | d31) return 0;if(month=1 & d31) return 0; if(month=3 & d31) return 0; if(month=4 & d30) return 0; i

24、f(month=5 & d31) return 0; if(month=6 & d30) return 0; if(month=7 & d31) return 0; if(month=8 & d31) return 0; if(month=9 & d30) return 0; if(month=10 & d31) return 0; if(month=11 & d30) return 0; if(month=12 & d31) return 0; if(isleap(y) /是閏年 if(month=2 & d29) return 0; else /不是閏年 if(month=2 & d28)

25、 return 0; return 1; void setclock() uchar i,j,k,key,keyin; k=1;key=1; while(key=1) key=fastfound();/消除按功能鍵時產生的影響 dbyte0x57=0x10; dbyte0x58=0x10; dbyte0x59=0x10; dbyte0x5a=0; dbyte0x5b=0; dbyte0x5c=0x10;dbyte0x5d=0; dbyte0x5e=0; for (i=0;i2;i+) for(j=0;j2;j+) while(k) key=fastfound(); if(key=1) keyi

26、n=keyfound();k=0;/*如果有鍵按下,則退出while;否則,等待按鍵*/ scan(0x57);/顯示按鍵 if(keyin9 ) keyin=0x10;/如果按鍵的值非法,置為- dbyte0x5a+i*3+j=keyin; while(key=1) key=fastfound();/*判斷按鍵以后,手是否已放開;如果沒放開,等待*/ k=1; /用于進入下一次按鍵狀態(tài) dbyte0x5a+i*3+j=0x10; /設置該單元顯示- while(1) /設置時間完成后,判斷是否按了確認鍵 key=fastfound(); scan(0x57); if(key=1) keyin

27、=keyfound(); if(keyin=0x0d)/*判斷按鍵是否為確認鍵,如果是,則進行按鍵的判斷;如果不是,則等待*/ if(checkall(0x0c)=0) break;/如果按鍵非法,退出,保持原來的值 time.hour1=dbyte0x5a*10+dbyte0x5b; time.minute1=dbyte0x5d*10+dbyte0x5e; break; void setdate() uchar i,k,key,keyin; k=1;key=1; while(key=1) key=fastfound();/消除按功能鍵時產生的影響 dbyte0x57=time.year/10

28、00; dbyte0x58=time.year%1000/100; dbyte0x59=time.year%100/10; dbyte0x5a=time.year%10; dbyte0x5b=time.month/10; dbyte0x5c=time.month%10; dbyte0x5d=time.day/10; dbyte0x5e=time.day%10; for (i=0;i8;i+) while(k) key=fastfound(); if(key=1) keyin=keyfound();k=0;/如果有鍵按下,則退出while;否則,等待按鍵 scan(0x57);/顯示按鍵 if(

29、keyin9 ) keyin=0x10;/如果按鍵的值非法,置為- dbyte0x57+i=keyin; while(key=1) key=fastfound();/*判斷按鍵以后,手是否已放開;如果沒放開,等待*/ k=1; /用于進入下一次按鍵狀態(tài) while(1) /設置時間完成后,判斷是否按了確認鍵 key=fastfound(); scan(0x57); if(key=1) keyin=keyfound(); if(keyin=0x0d)/*判斷按鍵是否為確認鍵,如果是,則進行按鍵的判斷;如果不是,則等待*/ if(checkall(0x0e)=0) break;/如果按鍵非法,退出

30、,保持原來的值 time.year=dbyte0x57*1000+dbyte0x58*100+dbyte0x59*10+dbyte0x5a; time.month=dbyte0x5b*10+dbyte0x5c; time.day=dbyte0x5d*10+dbyte0x5e; break; void settime() uchar i,j,k,key,keyin; k=1;key=1; while(key=1) key=fastfound();/消除按功能鍵時產生的影響 dbyte0x57=0; dbyte0x58=0; dbyte0x59=0x10; dbyte0x5a=0; dbyte0x

31、5b=0; dbyte0x5c=0x10; dbyte0x5d=0; dbyte0x5e=0; for (i=0;i3;i+) for(j=0;j2;j+) while(k) key=fastfound(); if(key=1) keyin=keyfound();k=0;/*如果有鍵按下,則退出while;否則,等待按鍵*/ scan(0x57);/顯示按鍵 if(keyin9 ) keyin=0x10;/如果按鍵的值非法,置為- dbyte0x57+i*3+j=keyin; while(key=1) key=fastfound();/*判斷按鍵以后,手是否已放開;如果沒放開,等待*/ k=1

32、; /用于進入下一次按鍵狀態(tài) dbyte0x57+i*3+j=0x10; /設置該單元顯示- while(1) /設置時間完成后,判斷是否按了確認鍵 key=fastfound(); scan(0x57); if(key=1) keyin=keyfound(); if(keyin=0x0d)/*判斷按鍵是否為確認鍵,如果是,則進行按鍵的判斷;如果不是,則等待*/ if(checkall(0x0f)=0) break;/如果按鍵非法,退出,保持原來的值 time.hour=dbyte0x57*10+dbyte0x58; time.minute=dbyte0x5a*10+dbyte0x5b; ti

33、me.second=dbyte0x5d*10+dbyte0x5e; break; void timechange() interrupt 1 /秒加1int i; th0=0x4c; /晶振頻率11.0592mhz下,定時50ms的計數(shù)初值 tl0=0x00; /216-46080=4c00hms20+; if( ms20=20) time.second+; ms20=0;if(time.second=60)time.minute+;time.second=0; if(time.minute=60)time.hour+;time. minute =0; if(time.hour=24)time.hour=0;datechange(); dbyte0x77=time.hour/10; dbyte0x78=time.hour%10; dbyte0x79=0x10; dbyte0x7a

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論