電子時(shí)鐘實(shí)訓(xùn)報(bào)告
一, 實(shí)訓(xùn)目的 二,實(shí)訓(xùn)要求 三,實(shí)訓(xùn)基本原理 四,實(shí)訓(xùn)設(shè)計(jì)分析 五,實(shí)訓(xùn)要求實(shí)現(xiàn) A.電路設(shè)計(jì) 1. 整體設(shè)計(jì) 2. 分塊設(shè)計(jì) B.程序設(shè)計(jì) 1 程序總體設(shè)計(jì) 2全部完整代碼: 六.實(shí)訓(xùn)總結(jié)及感想
一,實(shí)訓(xùn)目的 20世紀(jì)末,電子技術(shù)獲得了飛速的發(fā)展,在其推動(dòng)下,現(xiàn)代電子產(chǎn)品幾乎滲透了社會(huì)的各個(gè)領(lǐng)域,有力地推動(dòng)了社會(huì)生產(chǎn)力的發(fā)展和社會(huì)信息化程度的提高,同時(shí)也使現(xiàn)代電子產(chǎn)品性能進(jìn)一步提高,產(chǎn)品更新?lián)Q代的節(jié)奏也越來越快。 現(xiàn)代生活的人們?cè)絹碓街匾暺鹆藭r(shí)間觀念,可以說是時(shí)間和金錢劃上了等號(hào)。對(duì)于那些對(duì)時(shí)間把握非常嚴(yán)格和準(zhǔn)確的人或事來說,時(shí)間的不準(zhǔn)確會(huì)帶來非常大的麻煩,所以電子鐘是以其小巧,價(jià)格低廉,走時(shí)精度高,使用方便,功能多,便于集成化而受廣大消費(fèi)的喜愛,得到了廣泛的使用。 1. 學(xué)習(xí)8051定時(shí)器時(shí)間計(jì)時(shí)處理、按鍵掃描及LCD液晶顯示的設(shè)計(jì)方法。 2. 設(shè)計(jì)任務(wù)及要求 利用實(shí)訓(xùn)平臺(tái)上LCD1602液晶顯示屏, 設(shè)計(jì)帶有鬧鈴功能的數(shù)字時(shí)鐘
二,實(shí)訓(xùn)要求
A.基本要求: 1. 在LCD1602液晶顯示屏上顯示當(dāng)前日期,時(shí)間。 2. 利用按鍵可對(duì)時(shí)間及鬧玲進(jìn)行設(shè)置,并可顯示設(shè)置鬧玲的時(shí)間。鬧玲時(shí)間到蜂鳴器發(fā)出聲響,一分鐘后鬧鈴?fù)V埂?/div>
B.擴(kuò)展部分: 1.日歷功能(能對(duì)年,月,日,星期進(jìn)行顯示,分辨平年,閏年以及各月天數(shù),并調(diào)整)實(shí)現(xiàn)年月日時(shí)分秒的調(diào)整,星期準(zhǔn)確的隨著日期改變而改變進(jìn)行顯示。 2.定時(shí)功能(設(shè)定一段時(shí)間長(zhǎng)度,定時(shí)到后,鬧鈴提示)
C.可擴(kuò)展部分: 1.鬧鈴重響功能(鬧鈴被停止后,以停止時(shí)刻開始,一段時(shí)間后鬧鈴重響,且重響時(shí)間的間隔可調(diào)) 2.可進(jìn)行備忘錄提示,按照年月日,可在設(shè)定的某年某月進(jìn)行鬧鈴提示。
三,實(shí)訓(xùn)基本原理
四,實(shí)訓(xùn)設(shè)計(jì)分析 針對(duì)要實(shí)現(xiàn)的功能,采用AT89S52單片機(jī)進(jìn)行設(shè)計(jì),AT89S52 單片機(jī)是一款低功耗,高性能CMOS8位單片機(jī),片內(nèi)含4KB在線可編程(ISP)的可反復(fù)擦寫1000次的Flash只讀程序存儲(chǔ)器,器件采用高密度、非易失性存儲(chǔ)技術(shù)制造,兼容標(biāo)準(zhǔn)MCS- 51指令系統(tǒng)及80C51引腳結(jié)構(gòu)。這樣,既能做到經(jīng)濟(jì)合理又能實(shí)現(xiàn)預(yù)期的功能。 在程序方面,采用分塊設(shè)計(jì)的方法,這樣既減小了編程難度、使程序易于理解,又能便于添加各項(xiàng)功能。程序可分為鬧鐘的聲音程序、時(shí)間顯示程序、日期顯示程序,秒表顯示程序,時(shí)間調(diào)整程序、鬧鐘調(diào)整程序、定時(shí)調(diào)整程序,延時(shí)程序等。運(yùn)用這種方法,關(guān)鍵在于各模塊的兼容和配合,若各模塊不匹配會(huì)出現(xiàn)意想不到的錯(cuò)誤。 首先,在編程之前必須了解硬件結(jié)構(gòu)尤其是各引腳的用法,以及內(nèi)部寄存器、存儲(chǔ)單元的用法,否則,編程無從下手,電路也無法設(shè)計(jì)。這是前期準(zhǔn)備工作。第二部分是硬件部分:依據(jù)想要的功能分塊設(shè)計(jì)設(shè)計(jì),比如輸入需要開關(guān)電路,輸出需要顯示驅(qū)動(dòng)電路和數(shù)碼管電路等。第三部分是軟件部分:先學(xué)習(xí)理解C語言的編程方法再根據(jù)設(shè)計(jì)的硬件電路進(jìn)行分塊的編程調(diào)試,最終完成程序設(shè)計(jì)。第四部分是軟件畫圖部分:設(shè)計(jì)好電路后進(jìn)行畫圖,包括電路圖和仿真圖的繪制。第五部分是軟件仿真部分:軟硬件設(shè)計(jì)好后將軟件載入芯片中進(jìn)行仿真,仿真無法完成時(shí)檢查軟件程序和硬件電路并進(jìn)行修改直到仿真成功。第六部分是硬件實(shí)現(xiàn)部分:連接電路并導(dǎo)入程序檢查電路,若與設(shè)計(jì)的完全一樣一般能實(shí)現(xiàn)想要的功能。最后進(jìn)行功能擴(kuò)展,在已經(jīng)正確的設(shè)計(jì)基礎(chǔ)上,添加額外的功能! 五,實(shí)訓(xùn)要求實(shí)現(xiàn) A.電路設(shè)計(jì) 1. 整體設(shè)計(jì) 此次設(shè)計(jì)主要是應(yīng)用單片機(jī)來設(shè)計(jì)電子時(shí)鐘,硬件部分主要分以下電路模塊:顯示電路用lcd1602顯示,年份,月份,星期,小時(shí)、分鐘和秒(日),使電路更加簡(jiǎn)單。單片機(jī)采用AT89S51系列,這種單片機(jī)應(yīng)用簡(jiǎn)單,適合電子鐘設(shè)計(jì)。 電路的總體設(shè)計(jì)框架如下: 
2. 分塊設(shè)計(jì) 模塊電路主要分為:復(fù)位電路、按鍵、LCD和時(shí)鐘芯片。 2.1 按鍵處理模塊 
按鍵處理設(shè)置為:如沒有按鍵,則時(shí)鐘正常走時(shí)。當(dāng)按K0鍵一次,時(shí)鐘暫停走動(dòng)進(jìn)入調(diào)小時(shí)狀態(tài),再按K0鍵一次,進(jìn)入調(diào)分狀態(tài),再按K0鍵一次,回到正常走時(shí);對(duì)于K1和K2按鍵,如果是正常走時(shí),按K1和K2不起作用,如果進(jìn)入調(diào)時(shí)或調(diào)分狀態(tài),按K1可對(duì)時(shí)或分進(jìn)行加1操作,小時(shí)加到24則回到0,分加到60則回到0;按K2可對(duì)時(shí)或分進(jìn)行減1操作,小時(shí)減到負(fù)則回到23,分減到負(fù)則回到59。按鍵處理模塊流程如圖所示。  2.2 輸出部分 本電路的輸出信號(hào)LCD的寫入命令和寫入數(shù)據(jù),鬧鈴脈沖信號(hào)。 鬧鈴由P1.5端輸出,模塊如下: 
日期時(shí)間由LCD1602輸出,模塊如下: 
2.3 晶振與復(fù)位電路 本實(shí)訓(xùn)單片機(jī)時(shí)鐘用內(nèi)部時(shí)鐘,模塊如下: 
復(fù)位電路為手動(dòng)復(fù)位構(gòu)成,模塊如下: 
B.程序設(shè)計(jì) B.1 程序總體設(shè)計(jì) 軟件程序劃分為以下幾個(gè)部分:系統(tǒng)主程序、DS1302驅(qū)動(dòng)程序、LCD驅(qū)動(dòng)程序。在主程序中調(diào)用DS1302驅(qū)動(dòng)程序和LCD驅(qū)動(dòng)程序,另外在主程序中還包含按鍵處理。 主程序先是將LCD初始化,其次在LCD顯示日期和時(shí)間的提示信息,然后進(jìn)入死循環(huán),在循環(huán)中先判斷是否有鍵按下,如按下K0鍵,則功能單元加1;如按下K1鍵,則根據(jù)功能單元的內(nèi)容把日期時(shí)間相應(yīng)位加1;如按下K2鍵,則根據(jù)功能單元的內(nèi)容把日期時(shí)間相應(yīng)位減1;并把修改后的日期時(shí)間寫入1302(在這個(gè)過程中注意日期時(shí)間的數(shù)據(jù)格式的轉(zhuǎn)換)。其次讀DS1302日歷時(shí)鐘寄存器,讀出的內(nèi)容存入日期、時(shí)間緩沖區(qū);最后把日期、時(shí)間緩沖區(qū)數(shù)轉(zhuǎn)化為ASCII碼放入LCD顯示緩沖區(qū)并調(diào)用LCD顯示程序顯示。 程序總的流程圖如下: 
C.硬件定時(shí)液晶顯示時(shí)鐘硬件電路
2.全部完整代碼: 基于STC89S51單片機(jī)以及液晶1602顯示的萬年歷項(xiàng)目
六.實(shí)訓(xùn)總結(jié)及感想 時(shí)光飛逝,一轉(zhuǎn)眼,一個(gè)學(xué)期又進(jìn)尾聲了,本學(xué)期的單片機(jī)綜合課程設(shè)計(jì)也在三周內(nèi)完成了。
俗話說“好的開始是成功的一半”。說起課程設(shè)計(jì),我認(rèn)為最重要的就是做好設(shè)計(jì)的預(yù)習(xí),認(rèn)真的研究老師給的題目。其次,老師對(duì)實(shí)驗(yàn)的講解要認(rèn)真聽講,把資料認(rèn)真看懂,因?yàn)橹挥卸济靼琢耍銎鹪O(shè)計(jì)就會(huì)事半功倍,如果沒弄明白,就迷迷糊糊的去做設(shè)計(jì),到頭來一點(diǎn)收獲也沒有。最后,最重要的是要重視程序的模塊化,能看懂程序,在此基礎(chǔ)上擴(kuò)展功能,也要注重程序的調(diào)試,掌握其方法。
雖然這次的課程設(shè)計(jì)算起來在實(shí)驗(yàn)室的時(shí)間只有六個(gè)課時(shí),不過在宿舍里查資料,看資料,做實(shí)驗(yàn)的時(shí)間一定不止六個(gè)課時(shí)。
硬件的設(shè)計(jì)跟焊接都要我們自己動(dòng)手去焊,軟件的編程也要我們不斷的調(diào)試,最終一個(gè)能完成課程設(shè)計(jì)的勞動(dòng)成果出來了,很高興它能按著設(shè)計(jì)的思想與要求運(yùn)動(dòng)起來。
當(dāng)然,這其中也有很多問題,第一、不夠細(xì)心比如由于粗心大意焊錯(cuò)了線,由于對(duì)課本理論的不熟悉導(dǎo)致編程出現(xiàn)錯(cuò)誤。第二,是在學(xué)習(xí)態(tài)度上,這次課設(shè)是對(duì)我的學(xué)習(xí)態(tài)度的一次檢驗(yàn)。對(duì)于這次單片機(jī)綜合課程實(shí)習(xí),我的第一大心得體會(huì)就是作為一名工程技術(shù)人員,要求具備的首要素質(zhì)絕對(duì)應(yīng)該是嚴(yán)謹(jǐn)。我們這次實(shí)習(xí)所遇到的多半問題多數(shù)都是由于我們不夠嚴(yán)謹(jǐn)。第三,在做人上,我認(rèn)識(shí)到,無論做什么事情,只要你足夠堅(jiān)強(qiáng),有足夠的毅力與決心,有足夠的挑戰(zhàn)困難的勇氣,就沒有什么辦不到的。 我們組一起完成了這次單片機(jī)課程設(shè)計(jì)課題中的電子時(shí)鐘設(shè)計(jì),從中學(xué)到很多東西,如何從理論到實(shí)踐中的轉(zhuǎn)化,怎樣將所學(xué)的知識(shí)運(yùn)用到實(shí)踐當(dāng)中,運(yùn)用到現(xiàn)實(shí)生活當(dāng)中,此次的課堂設(shè)計(jì)給我奠定了基礎(chǔ),我會(huì)在以后的工作學(xué)習(xí)中磨練自己,使自己適合于以后的競(jìng)爭(zhēng),同時(shí)在查找資料的過程中學(xué)到許多新的知識(shí), 在和同學(xué)合作的過程中增進(jìn)友誼,一個(gè)團(tuán)隊(duì)合作的重要性,也是使我對(duì)團(tuán)隊(duì)精神的積極進(jìn)取性與重要性有了更加充分的理解。 最后,感謝老師的一個(gè)學(xué)期對(duì)我們的教育,正是老師的精彩課程和對(duì)我們嚴(yán)格的要求,老師熱心的幫助,使得我們課程設(shè)計(jì)能夠順利的完成,同時(shí)在課程設(shè)計(jì)的過程中鞏固我們的單片機(jī)知識(shí),相信對(duì)我以后的工作會(huì)有很大的幫助!
單片機(jī)源程序如下: - #include <reg51.h>
- #include <absacc.h> //定義絕對(duì)地址訪問
- #include <intrins.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit T_CLK = P1^3; //DS1302時(shí)鐘線引腳
- sbit T_IO = P1^4; //DS1302數(shù)據(jù)線引腳
- sbit T_RST = P1^2; //DS1302復(fù)位線引腳
- sbit RS=P1^7; //定義LCD的控制線
- sbit RW=P1^6;
- sbit EN=P1^5;
- sbit key0=P3^0; //定義按鍵
- sbit key1=P3^1;
- sbit key2=P3^2;
- sbit ACC7 =ACC^7;
- sbit ACC0 =ACC^0;
- char line1[]="LCD test program";
- char line2[]="Everything is OK";
- char line3[]="Welcome to you ";
- char line4[]="Welcome to using";
- void init_LCD(void);
- void write_inst(char); // 寫入指令函數(shù)
- void write_char(char); // 寫入字元函數(shù)
- void check_BF(void); // 檢查忙碌函數(shù)
- void delay1ms(int);
- uchar datechar[]={"DATE:"};
- uchar timechar[]={"TIME:"};
- uchar datebuffer[8]={0,0,0x2d,0,0,0x2d,0,0}; //定義日歷顯示緩沖區(qū)
- uchar timebuffer[8]={0,0,0x3a,0,0,0x3a,0,0}; //定義時(shí)間顯示緩沖區(qū)
- uchar data ttime[3]={0x00,0x00,0x00}; //分別為秒、分和小時(shí)的值
- uchar data tdata[3]={0x00,0x00,0x00}; //分別為年、月、日
- //往DS1302寫入1Byte數(shù)據(jù)
- void WriteB(uchar ucDa)
- {
- uchar i;
- ACC = ucDa;
- for(i=8; i>0; i--)
- {
- T_IO = ACC0; //相當(dāng)于匯編中的 RRC
- T_CLK = 1;
- T_CLK = 0;
- ACC = ACC >> 1;
- }
- }
- //從DS1302讀取1Byte數(shù)據(jù)
- uchar ReadB(void)
- {
- uchar i;
- for(i=8; i>0; i--)
- {
- ACC = ACC >>1;
- ACC7 = T_IO;T_CLK = 1;T_CLK = 0; //相當(dāng)于匯編中的 RRC
- }
- return(ACC);
- }
- //DS1302單字節(jié)寫,向指定單元寫命令/數(shù)據(jù),ucAddr: DS1302地址, ucDa: 要寫的命令/數(shù)據(jù)
- void v_W1302(uchar ucAddr,uchar ucDa)
- {
- T_RST = 0;
- T_CLK = 0;
- _nop_();_nop_();
- T_RST = 1;
- _nop_();_nop_();
- WriteB(ucAddr); /* 地址,命令 */
- WriteB(ucDa); /* 寫1Byte數(shù)據(jù)*/
- T_CLK = 1;
- T_RST =0;
- }
- //DS1302單字節(jié)讀,從指定地址單元讀出的數(shù)據(jù)
- uchar uc_R1302(uchar ucAddr)
- {
- uchar ucDa=0;
- T_RST = 0;T_CLK = 0;
- T_RST = 1;
- WriteB(ucAddr); /*寫地址*/
- ucDa = ReadB(); /*讀1Byte命令/數(shù)據(jù) */
- T_CLK = 1;T_RST =0;
- return(ucDa);
- }
- //LCD檢查忙函數(shù)
- void fbusy()
- {
- P2 = 0xff;
- RS = 0;
- RW = 1;
- EN = 1;
- EN = 0;
- while((P2 & 0x80))
- {
- EN = 0;
- EN = 1;
- }
- }
- //LCD寫命令函數(shù)
- void wc51r(uchar j)
- {
- fbusy();
- EN = 0;
- RS = 0;
- RW = 0;
- EN = 1;
- P2 = j;
- EN = 0;
- }
- //LCD寫數(shù)據(jù)函數(shù)
- void wc51ddr(uchar j)
- {
- fbusy(); //讀狀態(tài);
- EN = 0;
- RS = 1;
- RW = 0;
- EN = 1;
- P2 = j;
- EN = 0;
- }
- void init() //LCD1602初始化
- {
- while(1)
- { //指定第一行位置
- write_inst(0x80);
- for(j=0;j<16;j++)
- write_char(line1[j]); //循環(huán)顯示16個(gè)字符
- write_inst(0xc0); //指定第二行位置
- for(j=0;j<16;j++)
- write_char(line2[j]); //循環(huán)顯示16個(gè)字符
- delay1ms(2000); //延時(shí)2s (STC89C51:2000)(MPC82G516:20000)
- write_inst(0x80);
- for(j=0;j<16;j++)
- write_char(line3[j]);
- write_inst(0xc0);
- for(j=0;j<16;j++)
- write_char(line4[j]);
- delay1ms(2000);
- }
- }
- void init_LCD(void)
- {
- write_inst(0x38); //指令6:設(shè)定兩行
- //write_inst(0x08); //指令4:關(guān)閉顯示
- wc51r(0x01); //清屏
- wc51r(0x38); //使用8位數(shù)據(jù),顯示兩行,使用5*7的字型
- wc51r(0x0c); //顯示器開,光標(biāo)開,字符不閃爍
- wc51r(0x06); //字符不動(dòng),光標(biāo)自動(dòng)右移一格
- }
- //************延時(shí)函數(shù)************
- void delay(uint i) //延時(shí)函數(shù)
- {uint y,j;
- for (j=0;j<i;j++){
- for (y=0;y<0xff;y++){;}}
- }
- void main(void)
- {
- uchar i,set;
- uchar data temp;
- SP=0X50;
- delay(10);
- init();
- wc51r(0x80);
-
- for (i=0;i<5;i++) wc51ddr(datechar[i]); //第一行開始顯示DATA:
- wc51r(0xc0);
- for (i=0;i<5;i++) wc51ddr(timechar[i]); //第二行開始顯示TIME:
- while(1)
- {P3=0XFF;
- if(key0==0) { delay(10);if (key0==0) { while (key0==0); set++; if
- (set==6) set=0;}}
- if(key1==0) { delay(10); //如果是加1鍵,則日歷、時(shí)鐘相應(yīng)位加1
- if (key1==0) { while (key1==0);
- switch(set)
- {
- case 1: tdata[0]++;if (tdata[0]==100) tdata[0]=0;
- temp=(tdata[0]/10)*16+tdata[0]%10;
- v_W1302(0x8e,0);
- v_W1302(0x8c,temp);
- v_W1302(0x8e,0x80);
- break;
- case 2: tdata[1]++;if (tdata[1]==13) tdata[1]=1;
- temp=(tdata[1]/10)*16+tdata[1]%10;
- v_W1302(0x8e,0);
- v_W1302(0x88,temp);
- v_W1302(0x8e,0x80);
- break;
- case 3: tdata[2]++;if (tdata[2]==32) tdata[2]=1;
- temp=(tdata[2]/10)*16+tdata[2]%10;
- v_W1302(0x8e,0);
- v_W1302(0x86,temp);
- v_W1302(0x8e,0x80);
- break;
- case 4: ttime[2]++;if (ttime[2]==24) ttime[2]=0;
- temp=(ttime[2]/10)*16+ttime[2]%10;
- v_W1302(0x8e,0);
- v_W1302(0x84,temp);
- v_W1302(0x8e,0x80);
- break;
- case 5: ttime[1]++;if (ttime[1]==60) ttime[1]=0;
- temp=(ttime[1]/10)*16+ttime[1]%10;
- v_W1302(0x8e,0);
- v_W1302(0x82,temp);
- v_W1302(0x8e,0x80);
- break;
- }
- }
- }
- if(key2==0) { delay(10); //如果是減1鍵,則日歷、時(shí)鐘相應(yīng)位減1
- if (key2==0) { while (key2==0);
- switch(set)
- {
- case 1: tdata[0]--;if (tdata[0]==0xff) tdata[0]=99;
- temp=(tdata[0]/10)*16+tdata[0]%10;
- v_W1302(0x8e,0);
- v_W1302(0x8c,temp);
- v_W1302(0x8e,0x80);
- break;
- case 2: tdata[1]--;if (tdata[1]==0x00) tdata[1]=12;
- temp=(tdata[1]/10)*16+tdata[1]%10;
- v_W1302(0x8e,0);
- v_W1302(0x88,temp);
- v_W1302(0x8e,0x80);
- break;
- case 3: tdata[2]--;if (tdata[2]==0x00) tdata[2]=31;
- temp=(tdata[2]/10)*16+tdata[2]%10;
- v_W1302(0x8e,0);
- v_W1302(0x86,temp);
- v_W1302(0x8e,0x80);
- break;
- case 4: ttime[2]--;if (ttime[2]==0xff) ttime[2]=23;
- temp=(ttime[2]/10)*16+ttime[2]%10;
- v_W1302(0x8e,0);
- v_W1302(0x84,temp);
- v_W1302(0x8e,0x80);
- break;
- case 5: ttime[1]--;if (ttime[1]==0xff) ttime[1]=59;
- temp=(ttime[1]/10)*16+ttime[1]%10;
- v_W1302(0x8e,0);
- v_W1302(0x82,temp);
- v_W1302(0x8e,0x80);
- ……………………
- …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼
0.png (47.03 KB, 下載次數(shù): 41)
下載附件
2018-9-21 17:13 上傳
|