這是我在“2020年7月初學校組織的時長一周的項目”中做的項目,提前一周的周三開始從咱論壇里參考了幾個單獨分開的項目來做的。由于是提前自己做的,第一天上午講解軟件安裝的的時候就完成了所需要做的項目。但硬件方面只用到了C51和LCD12864,講解項目的時候又加了一些其他的一些諸如管理時間的DS1302,管理溫度的DS18B20。又把項目重做了一遍,做完之后還有點時間順便做了做其他的幾個功能。分享之前先對個人的項目進行說明:
- 由于特殊原因,上的是網課,不在學校,所以并沒有在開發板上測試,只是在仿真里可以運行。
- 項目所用到的知識點:矩陣鍵盤、T0中斷、LCD12864的使用(顯示屏,無字庫)、DS1302的使用(讀寫當前時間)。(DS18B20只是一個溫度的數值,所以交給輔助去做了,嗯,然后就沒加)。
- 個人認為:適合拿來簡單參考了解一下功能是如何實現的,不適用于研究或鉆研細節方面的東西。
- 一開始源文件只是一個.c文件,只用到了T0中斷來控制秒表、鬧鐘以及時間,并用四個直接連在C51引腳上的按鈕來實現功能。
但是后來聽課了解了一丁點#include命令后,將項目拆分成了各個頭文件,并加入了控制時間的DS1302來代替T0管理時間模塊。
按鈕也從單獨的直接連接C51的引腳,換為了一個3*3的矩陣鍵盤。由于矩陣鍵盤沒有辦法檢測按下兩個鍵以上的情況,所以在功能多的前提下按鍵的安排(哪個按鍵管什么功能)就開始“放飛自我”:出于做學校項目的目標是及格,所以并沒有仔細去規劃哪個按鈕控制哪個功能,使用方法詳見附件內的"說明.docx"或"說明.pdf",這里面簡要介紹了功能如何使用。 - 有關代碼的解釋只有項目文件的注釋。
- 仿真圖我用的是:ISIS7 Professional,項目文件是Keil uVision4
- 我覺得這個不難實現。做之前啥也不會,慢慢了解了LCD12864是如何輸出的,DS1802是如何讀出時間、寫入時間的;以及矩陣鍵盤的原理后,很快很容易的就能夠做出來項目,詳細請百度或參考書籍文獻或自行研究別人的項目。
一、功能:
二、代碼:
main.c:
- #include<reg52.h>
- #include"dingyi.h" //引腳以及宏定義
- #include"key.h" //檢測按鍵,以及根據按鍵去做什么。
- #include"clock.h" //DS1302的使用
- #include"LCD12864.h" //包含LCD12864的最基本的使用函數。
- #include"LCD12864_use.h" //這里面包含了對LCD12864.h中寫的函數的使用的函數,例如:調用kaifazhe()就能再LCD12864上輸出開發者;調用ShowTime(...)可以根據參數輸出時間等。
- #include"music.h" //這個用來播放音樂以及鬧鐘播放
- #include"show.h" //這個用來配合按鍵輸出的,還未寫入,所以沒用
- unsigned char nowkey; //檢測到的當前按下的值
- unsigned char state_key[3]={0,0,0}; //當前模塊,按鈕4可切換的最大值,按鈕4當前狀態(切換更改的數值)
- unsigned char clock_time[6]={0,0,0,0x31,1,0x20}; //秒、分、時、日、月、年
- unsigned char alarm[4]={1,10,45,23}; //鬧鐘啟動狀態,秒、分、時
- unsigned char chronograph[6]={0,0,0,0,0,0}; //百分秒、秒、分鐘、小時、開啟狀態、暫停狀態
- unsigned char music[4]={0,0,0,0}; //音樂開關狀態、當前音樂、高八位、低八位
- unsigned int pwd; //按鍵檢測模式計數用
- /************************************************************************
- *函數名:initT0()
- *函數功能:初始化T0,讓T0處于一開就能使用的狀態
- *形式參數:無
- *返回值:
- *用途:初始化
- *************************************************************************/
- void initT0()
- {
- TMOD=0x01; //定時器T0工作在方式1,定時模式
- TH0=(65536-10000)/256; //一次中斷10ms
- TL0=(65536-10000)%256;
- EA=1; //開總中斷
- ET0=1; //定時器T0允許中斷
- TR0=0; //定時器初始處于關閉狀態
- }
- /************************************************************************
- *函數名:initMain()
- *函數功能:初始化T0,lcd,時鐘,讓T0處于一開就能使用的狀態
- *形式參數:無
- *返回值:
- *用途:初始化
- *************************************************************************/
- void initMain()
- {
- init_lcd();
- Clock_Fresh(clock_time);
- Clock_Initial(clock_time);
- initT0();
- state_key[0]=0; //按鍵狀態初始化
- state_key[1]=0;
- state_key[2]=0;
- alarm[0]=1; //alarm初值這樣賦只是方便演示,當然這么寫很不嚴謹!!!。鬧鐘設定開啟
- alarm[1]=0; //秒→0
- alarm[2]=clock_time[1]/16*10+clock_time[1]%16+1; //分→系統時間下一分,如果此時是59分很明顯59+1就溢出了
- alarm[3]=clock_time[2]/16*10+clock_time[2]%16; //時→當前時
- chronograph[0]=0;
- chronograph[1]=0;
- chronograph[2]=0;
- chronograph[3]=0;
- chronograph[4]=0;
- chronograph[5]=0;
- music[0]=0;
- music[1]=1; //初始化鬧鐘的鈴聲是第二首歌曲“夢中的婚禮”
- music[2]=0;
- music[3]=0;
- }
- /************************************************************************
- *函數名:main()
- *函數功能:執行主函數
- *形式參數:無
- *返回值:
- *用途:順序執行編寫好的程序,中間有可能被T0中斷
- *************************************************************************/
- void main()
- {
- REBEGIN: //恢復出場設置時用
- initMain();
- Clr_Scr();
- kaifazhe(); //這個加到這里之后刪不掉了。。。刪除掉反而提示內存溢出。。。
- while(1)
- {
- if(alarm[0]==1) //檢查鬧鐘
- if(clock_time[2]%16+clock_time[2]/16*10==alarm[3]&&
- clock_time[1]%16+clock_time[1]/16*10==alarm[2]&&
- clock_time[0]%16+clock_time[0]/16*10==alarm[1]
- )
- {
- Clr_Scr();
- music[0]=1;
- while(~puzi(music)); //如果按下了7鍵返回1才能往下執行
- music[0]=0;
- TR0=0;
- alarm[0]=0;
- Clr_Scr();
- }
- nowkey=keyyyy(); //檢測當前鍵
- dosomething(nowkey,state_key,clock_time,alarm,chronograph,music); //根據當前鍵對數值進行改變
- //下面本來想也封裝個函數,寫到show.h中,但是沒時間了,就不寫封裝了。
- if(state_key[0]==0) //0.顯示模式
- {
- Clock_Fresh(clock_time); //時間刷新
- ShowTime(10,alarm[0],clock_time,7); //輸出時間
- }
- else if(state_key[0]==1) //1.秒表
- {
- if(chronograph[state_Chronograph_Show_Pause]==0) //如果此時處于不處于暫停狀態才播放,
- //這里會導致換個模式后如果還是處于暫停狀態
- MiaoBiao(chronograph[3],chronograph[2],chronograph[1],chronograph[0]); //秒表模式顯示
- }
- else if(state_key[0]==2) //2.編輯時間
- {
- Clock_Fresh(clock_time); //時間刷新
- ShowTime(state_key[2],alarm[0],clock_time,7); //狀態2輸出編輯模式時間
- }
- else if(state_key[0]==3) //3.編輯鬧鐘
- {
- ShowAlarm(alarm[0],state_key[2],alarm[3],alarm[2],alarm[1]); //鬧鐘狀態顯示
- }
- else if(state_key[0]==4) //4.音樂盒
- {
- showmusic(music[1]); //音樂模式顯示
- }
- else if(state_key[0]==5) //5.電子琴
- {
- while(1)
- {
- TR0=0;
- pwd=0;
- nowkey=keyyyy(); //檢查按下的哪個鍵
- music[2]=FREQH[nowkey+7]; //高八位賦初值
- music[3]=FREQL[nowkey+7]; //低八位賦初值
- showkey(nowkey);
- TR0=1; //啟動T0中斷
- music[0]=1; //允許播放音樂
- while(nowkey!=0&&nowkey==keyyyy())
- {
- delay(1); //當有鍵按下,每1ms左右pwd+1(1s=1000ms)
- pwd++;
- if(pwd>3000&&nowkey==9) //9鍵按下了3s左右,關閉T0中斷(不再響),進入內部函數
- {
- TR0=0;
- kaifazhe2();
- }
- }
- TR0=0;
- music[0]=0;
-
- if(pwd>3000)goto NEXT; //while內部結束后檢測按鍵按下了幾秒,如果超過了3s,跳轉到NEXT
-
- }
- NEXT:
- Clr_Scr();
- state_key[0]=0;
- }
- else ;
- if(nowkey==9) //檢查按下的按鍵是否是9,是的話需要按下3s左右,恢復出廠設置
- {
- pwd=0;
- for(pwd=0;pwd<300;pwd++)
- {
- delay(10);
- if(keyyyy()==nowkey);
- else goto MAINEND;
- }
- goto REBEGIN;
- }
- MAINEND:;
- }
- }
- void T0int()interrupt 1
- {
- if(music[0]==1) //T0啟動,檢查是否要播放音樂
- {
- TH0=music[2];
- TL0=music[3];
- P3_7=~P3_7;
- }
- else if(chronograph[state_Chronograph_On_Off]==1) //否則再檢測是否要啟動秒表
- {
- //給下一次定時賦值
- TH0=(65536-10000)/256; //高八位賦初值
- TL0=(65536-10000)%256; //低八位賦初值
- chronograph[chronograph_10ms]++; //加百分之一秒,然后進行溢出判斷以及處理
- if(chronograph[chronograph_10ms]>98)
- {
- chronograph[chronograph_10ms]=0;
- chronograph[chronograph_sec]++;
- if(chronograph[chronograph_sec]>59)
- {
- chronograph[chronograph_sec]=0;
- chronograph[chronograph_min]++;
- }
- if(chronograph[chronograph_min]>59)
- {
- chronograph[chronograph_min]=0;
- chronograph[chronograph_hour]++;
- }
- if(chronograph[chronograph_hour]>23)
- {
- chronograph[chronograph_hour]=0;
- }
- }
- }
- else
- {
- TR0=0; //在不播放音樂,不啟動定時器的狀態下開啟了定時器,則關閉定時器。
- }
- }
復制代碼
三、問題:
如mian.c代碼:第75行,明明刪掉一整個函數調用卻提示溢出,如圖:
個人在項目展示前寫好了兩個輸出函數用來展示,但是當時也是只能放一個到主函數中,再放會溢出。后來改了改部分代碼,又加了幾個按鈕功能才把兩個輸出函數都加進去。現在的狀態是想刪刪不掉,又沒想去對這個項目文件進行優化、或者深入,所以不對其進行處理。下次做小項目的時候得提前做好代碼層細節上的優化,這次就不再對項目進行修改了。
四、壓縮包內文件說明:
項目文件:
仿真圖:
全部資料51hei下載地址:
萬年歷(鬧鐘)+秒表+音樂盒+電子琴.zip
(295.56 KB, 下載次數: 96)
2020-7-19 10:40 上傳
點擊文件名下載附件
|