2023年全國碩士研究生考試考研英語一試題真題(含答案詳解+作文范文)_第1頁
已閱讀1頁,還剩31頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、<p>  本科畢業(yè)論文(設(shè)計)</p><p>  題  目: 基于單片機的推箱子游戲設(shè)計                   </p><p>  學(xué)生姓名:       學(xué)號: </p><p>  院(系): 電子信息工程   專業(yè): 微電子      </p><p>  入

2、學(xué)時間:        年   9    月</p><p>  導(dǎo)師姓名:        職稱/學(xué)位:  講師    </p><p>  導(dǎo)師所在單位:                 </p><p>  完成時間:   2013     年    5    月</p><p>  基于PROTEUS的推箱子游

3、戲的設(shè)計</p><p><b>  摘 要</b></p><p>  本論文主要介紹了基于單片機的推箱子游戲的規(guī)則、硬件結(jié)構(gòu)、軟件代碼的編寫及工作原理、基于T6963C內(nèi)核的液晶模塊PG160128A的詳細介紹以及指令集。模擬出Windows系統(tǒng)下的推箱子游戲,具有任意關(guān)數(shù)選擇、難度依次加大、游戲步數(shù)記錄、游戲時間記錄、按鍵發(fā)聲、系統(tǒng)低功耗、可實現(xiàn)在線調(diào)試等特點。

4、本系統(tǒng)是以單片機為其控制核心,以有源晶振構(gòu)成的電路作為時鐘信號,通過方向鍵的選擇向單片機控制系統(tǒng)發(fā)出人物移動控制命令,控制系統(tǒng)接收命令后做出一系列必要的判斷后,控制人物及箱子的移動。本設(shè)計已通過了實驗仿真,運行穩(wěn)定,基本上沒有規(guī)則方面的錯誤。</p><p>  論文主要分為兩大塊:一塊為游戲的硬件電路組成部分,一塊為軟件程序設(shè)計部分。在硬件電路里主要包括有源晶振部分、方向控制部分及液晶顯示部分等與單片機的接線設(shè)

5、計;軟件編程方面主要是子程序和主程序的編寫,包括:初始化代碼、液晶驅(qū)動代碼、方向按鍵代碼、過關(guān)判斷代碼、步數(shù)記錄代碼、時間記錄代碼、按鍵發(fā)聲代碼、關(guān)數(shù)選擇代碼及表格數(shù)據(jù)代碼等等。所有這些在文中都有詳細說明。</p><p>  關(guān)鍵詞:單片機;推箱子;PG160128A; T6963C內(nèi)核;指令集</p><p>  Design Of PROTEUS Sokoban Game Based

6、 On[1]</p><p><b>  Abstract</b></p><p>  This paper introduces the single-chip based on the rules of the game Sokoban, the structure of hardware, software code writing and working pr

7、inciple, based on the core T6963C LCD module PG160128A, as well as details of the instruction set. Simulate the system under Windows Sokoban game, an arbitrary number of related options, in turn increase the difficulty o

8、f the game a few step-by-step record time of the game record, sound button, low-power system can achieve on-line debugging and so on. The s</p><p>  Key words:MCU; Sokoban; PG160128A; T6963C core; instructio

9、n set</p><p><b>  目錄</b></p><p>  1 推箱子游戲編譯介紹7</p><p>  2 推箱子游戲的硬件部分設(shè)計7</p><p>  2.1 PG160128A液晶屏介紹7</p><p>  2.2 T6963C及其指令集介紹9</p>

10、<p>  2.2.1 T6963C9</p><p>  2.3 晶振、復(fù)位電路10</p><p>  2.3.1 晶振電路10</p><p>  2.3.2 復(fù)位電路11</p><p>  2.4 液晶顯示屏與單片機接口電路11</p><p>  3 推箱子游戲的軟件部分設(shè)計13&l

11、t;/p><p>  3.1 液晶屏驅(qū)動代碼設(shè)計15</p><p>  3.1.1 讀狀態(tài)程序15</p><p>  3.1.2 是否可讀寫程序15</p><p>  3.1.3 是否可自動讀寫程序16</p><p>  3.1.4寫單參數(shù)程序16</p><p>  3.1.5寫

12、雙參數(shù)程序16</p><p>  3.1.6寫指令程序17</p><p>  3.1.7寫8字節(jié)數(shù)據(jù)程序17</p><p>  3.1.8設(shè)置數(shù)據(jù)顯示在屏幕上的坐標程序17</p><p>  3.1.9設(shè)置數(shù)據(jù)存儲起始地址17</p><p>  3.1.10 CGRAM偏置地址設(shè)置函數(shù)18<

13、/p><p>  3.1.11液晶初始化函數(shù)18</p><p>  3.1.12顯示一個漢字子程序18</p><p>  3.1.13 清屏程序18</p><p>  3.1.14 自定義字符寫入CGROM函數(shù)19</p><p>  3.1.15 設(shè)置點顯示在屏幕上的坐標(以位為單位)19</p&g

14、t;<p>  3.1.16 畫圓子程序,其中x0,y0表示圓心,R表示半徑19</p><p>  3.2 初始化代碼設(shè)計20</p><p>  3.3 游戲時間代碼設(shè)計20</p><p>  3.4 游戲選關(guān)代碼設(shè)計20</p><p>  3.5 步數(shù)、關(guān)數(shù)更新代碼設(shè)計21</p><p&

15、gt;  3.5.1 步數(shù)更新代碼設(shè)計21</p><p>  3.5.2 關(guān)數(shù)更新代碼設(shè)計21</p><p>  3.6 過關(guān)代碼設(shè)計21</p><p>  3.7圖形顯示子程序22</p><p>  3.7.1 地圖顯示子程序22</p><p>  3.7.2原來位置顯示子程序22</p&

16、gt;<p>  3.8 中斷代碼設(shè)計23</p><p>  3.8.1 定時器0中斷發(fā)聲程序23</p><p>  3.8.2 定時器1中斷計時程序23</p><p>  3.9 方向控制代碼設(shè)計23</p><p>  4 推箱子游戲的系統(tǒng)仿真25</p><p>  4.1建立工程

17、項目流程25</p><p>  4.2 Proteus中原理圖的繪制及文件的加載29</p><p>  4.3 開機界面顯示31</p><p>  4.4 游戲界面顯示31</p><p>  4.5 仿真結(jié)果分析及解決方法33</p><p><b>  5 總結(jié)34</b>&

18、lt;/p><p><b>  參考文獻.34</b></p><p><b>  致謝35</b></p><p>  1 推箱子游戲編譯介紹</p><p>  現(xiàn)如今,游戲風(fēng)靡全球,各種游戲?qū)映霾桓F,大到網(wǎng)絡(luò)型的復(fù)雜游戲,小到手機游戲、單機游戲、智力游戲等簡單游戲。但是這種簡單也是相對于網(wǎng)絡(luò)游

19、戲等大型游戲而言的,小游戲本身的代碼還是相當繁雜,它要執(zhí)行一系列指令才能正確的完成一個簡單的操作,才能按照玩家的意志工作。所以我們現(xiàn)在見到的游戲多是在基于電腦這種高速執(zhí)行指令的平臺上運行的,脫離了它就什么事都做不了了。那么推箱子這種小游戲能否在單片機上編出來呢?答案是肯定的。首先,這個游戲是一個小型游戲,實現(xiàn)的功能比較簡單,不像大型游戲那樣功能復(fù)雜,它只要控制人物將所有箱子推到正確的位置即可,難度隨著箱子的增多而加大,對于實現(xiàn)這樣一個功

20、能,程序不是太復(fù)雜,用一塊單片機足以達到目的。其次,它的控件也比較少只有4個方向鍵和2個輔助的功能鍵,這些控鍵在Proteus中用彈跳式按鍵代替即可。第三,游戲地圖相對比較小、畫面簡單,只有箱子、人物和正確位置箱子等幾個圖形,這些在一塊稍大的液晶屏上就足以顯示,用不著電腦顯示屏。第四,就編程語言方面來說,編寫這樣一個簡單的小游戲不需要什么高級的語言,C語言或匯編語言就足以完成,C語言是一種通用型的語言,編程靈活、可讀性強、</p&

21、gt;<p>  2 推箱子游戲的硬件部分設(shè)計</p><p>  本部分內(nèi)容包括介紹PG160128A及其引腳功能;介紹T6963C指令集;晶振電路、復(fù)位電路的硬件設(shè)計;控件及按鍵發(fā)聲電路設(shè)計,最后給出游戲仿真的整體硬件電路圖,接下來是具體的說明。</p><p>  2.1 PG160128A液晶屏介紹[2]</p><p>  PG160128A

22、為一個128行160列的點陣液晶屏,他能顯示各種字符、圖形、漢字,基于T6963C內(nèi)核控制,自帶字符庫,同時用戶也可以自己建立漢字、圖形庫,其在Proteus中的元器件圖形如下: </p><p>  圖1 PG160128 </p><p>  各引腳的功能描敘如下表: </p><p>  表一 PG160128引

23、腳功能表</p><p>  2.2 T6963C及其指令集介紹</p><p>  2.2.1 T6963C[3]</p><p>  T6963C是一個LCD控制器,可設(shè)計為用于液晶顯示器控制驅(qū)動芯片和數(shù)據(jù)顯示的存取器。該控制器有一個8位并行數(shù)據(jù)總線,控制線的讀取或?qū)懭胪ㄟ^微控制器接口實現(xiàn),可以直接連接到TMPZ80微處理器中。它有一個128字節(jié)的字符發(fā)生器也可

24、以控制外部顯示RAM中的數(shù)據(jù),達64K字節(jié)。配置的文字,圖形和外部字符發(fā)生器RAM數(shù)據(jù)能很容易控制其顯示在窗口中,可以自由移動、分配內(nèi)存范圍。該器件支持非常廣泛的字符格式,液晶顯示器允許通過編程設(shè)置選擇不同的組合。它可以用于文字,圖形和結(jié)合文本模式及其他各種屬性的功能。</p><p>  2.2.2 T6963C指令集[4]</p><p>  T6963C共分為十大類,26條指令,詳細

25、信息如下表:</p><p>  表二 T6963C指令集</p><p>  2.3 晶振、復(fù)位電路</p><p>  2.3.1 晶振電路</p><p>  單片機的晶振電路如圖2所示,其中XTAL1和XTAL2分別為片內(nèi)振蕩電路的輸入輸出端。一般電容取20~47uF,本系統(tǒng)晶體的振蕩頻率為24MHz。晶振電路產(chǎn)生的振蕩脈沖經(jīng)過內(nèi)部觸

26、發(fā)器進行二分頻后,成為單片機的時鐘脈沖信號,為單片機提供一個基本時鐘信號。</p><p><b>  圖2 晶振電路</b></p><p>  2.3.2 復(fù)位電路</p><p>  復(fù)位操作是單片機的基本操作,單片機在進入運行前和在運行過程中程序出錯或操作失誤使系統(tǒng)不能正常運行時,需要進行復(fù)位操作,復(fù)位操作后,程序?qū)?000H開始重新

27、執(zhí)行。</p><p>  復(fù)位信號從單片機的RST引腳輸入,復(fù)位操作有上電自動復(fù)位、按鍵電平復(fù)位和外部脈沖復(fù)位三種方式,本電路采用了按鍵電平復(fù)位,電路圖如圖3.。</p><p><b>  圖3 復(fù)位電路</b></p><p>  2.4 液晶顯示屏與單片機接口電路</p><p>  液晶顯示屏共有18個引腳,其

28、中VDD、RST兩腳接電源,VSS、FS1、CE三腳接地,CON、FG兩腳懸空,D0~D7分別與單片機P2.0~P2.7相連接,WR與P1.7腳相連,RD與P1.6腳相連,C/D與P1.5腳相連,電路圖見圖4.</p><p>  2.5 控鍵、喇叭與單片機接口電路</p><p>  本游戲共有6個控件,分別是:四個方向鍵,用于控制箱子的移動方向;一個確定鍵,用于刷新初始化界面進入游戲界

29、面;一個選關(guān)鍵,用于選關(guān)。一個喇叭,用于按鍵發(fā)聲,以提示按鍵是否有效,電路圖見圖4.</p><p>  控件、喇叭與單片機的接線是:上移鍵接P1.0;左移鍵接P1.1;右移鍵接P1.2;下移鍵接P1.3;確定鍵接P1.4;選關(guān)鍵接P1.5;喇叭經(jīng)過分壓式偏置共射放大電路將信號放大再與單片機P3.1口相連,如圖4:</p><p>  圖4 揚聲器放大電路</p><p

30、>  至此,游戲的硬件電路結(jié)構(gòu)及連線全部介紹完成,仿真電路圖如圖5所示,整個電路圖以網(wǎng)絡(luò)標號的形式給出,避免連線過多顯得電路擁擠。</p><p>  圖5 推箱子游戲硬件電路圖</p><p>  3 推箱子游戲的軟件部分設(shè)計</p><p>  本部分主要介紹游戲的軟件部分設(shè)計,包括液晶屏驅(qū)動代碼設(shè)計;初始化代碼設(shè)計游戲時間代碼設(shè)計;游戲關(guān)數(shù)代碼設(shè)計;游戲

31、步數(shù)代碼設(shè)計;過關(guān)代碼設(shè)計;方向控制代碼設(shè)計;按鍵發(fā)聲代碼設(shè)計;數(shù)據(jù)表格設(shè)計等幾個方面,現(xiàn)就對這幾個方面做具體分析。</p><p>  3.1 液晶屏驅(qū)動代碼設(shè)計[5]</p><p>  3.1.1 讀狀態(tài)程序</p><p>  unsigned char Read_State()//返回液晶顯示屏的當前狀態(tài)</p><p>  {un

32、signed char a;</p><p>  P2=0xff;//讀狀態(tài)之前先將數(shù)據(jù)線拉高</p><p>  _CD=1;// 為指令、狀態(tài)操作條件</p><p>  _RD=0;//讀操作條件</p><p>  _RD=1;//為下次讀做準備</p><p>  a=Pin;//將狀態(tài)保存</p>

33、;<p>  return a;}</p><p>  3.1.2 是否可讀寫程序</p><p>  void Enable()</p><p>  {while(1) //bit0指令寫狀態(tài)位,bit1數(shù)據(jù)讀/寫狀態(tài)位,為1時候空閑</p><p>  if((Read_State()&3)==3)break;}//

34、如果狀態(tài)的低2為1則可讀寫</p><p>  3.1.3 是否可自動讀寫程序</p><p>  void Aut_Write()</p><p>  {while(1) //bit3數(shù)據(jù)自動寫狀態(tài)位,為1時候空閑</p><p>  if((Read_State()&8)==8)break;} //如果狀態(tài)的第4為1則可自動讀寫&

35、lt;/p><p>  3.1.4寫單參數(shù)程序</p><p>  //Data1為傳入的參數(shù),Com為傳入的指令;寫入順序為先數(shù)據(jù)后寫指令。</p><p>  void Write_Data1(unsigned char Data1,unsigned char Com)</p><p>  {Enable();//判斷是否可讀寫</p&

36、gt;<p>  _CD=0;//為數(shù)據(jù)操作條件</p><p>  Pin=Data1;//將數(shù)據(jù)送數(shù)據(jù)線</p><p>  _WR=0;//寫操作</p><p>  _WR=1;//為下次寫做裝備</p><p><b>  Enable();</b></p><p>  _

37、CD=1; // 為指令、狀態(tài)操作條件</p><p>  Pin=Com; //將指令送數(shù)據(jù)線</p><p><b>  _WR=0;</b></p><p><b>  _WR=1;}</b></p><p>  3.1.5寫雙參數(shù)程序</p><p>  // Dat

38、a1/Data2為傳入的參數(shù),Com為傳入的指令,先Data1后Data2,最后寫指令。</p><p>  void Write_Data2(unsigned char Data1,unsigned char Data2,unsigned char Com)</p><p>  {Enable();//判斷是否可讀寫</p><p>  _CD=0; //為數(shù)據(jù)操

39、作條件</p><p>  Pin=Data1; //將數(shù)據(jù)1送數(shù)據(jù)線</p><p>  _WR=0; //寫操作</p><p>  _WR=1; //為下次寫做裝備</p><p><b>  Enable();</b></p><p><b>  _CD=0;</b>

40、</p><p>  Pin=Data2; //將數(shù)據(jù)2送數(shù)據(jù)線</p><p><b>  _WR=0;</b></p><p><b>  _WR=1;</b></p><p><b>  Enable();</b></p><p><b>

41、;  _CD=1;</b></p><p>  Pin=Com; //將指令送數(shù)據(jù)線</p><p><b>  _WR=0;</b></p><p><b>  _WR=1;}</b></p><p>  3.1.6寫指令程序</p><p>  void Wr

42、ite_Com(unsigned char Com)</p><p>  {Enable();//判斷是否可讀寫</p><p>  _CD=1; // 為指令、狀態(tài)操作條件</p><p>  Pin=Com; //將指令送數(shù)據(jù)線</p><p>  _WR=0;//寫操作</p><p>  _WR=1;}//為下

43、次寫做裝備</p><p>  3.1.7寫8字節(jié)數(shù)據(jù)程序</p><p>  // Addr表示數(shù)據(jù)首地址,Way表示寫的方式</p><p>  void Write_8_Data(unsigned char Addr,unsigned char Way)</p><p>  {Aut_Write();//判斷是否能自動寫</p&g

44、t;<p>  Write_Com(AUT_WR);//自動寫開始</p><p>  Write_Data1(Addr,Way);</p><p>  Write_Com(AUT_WO);}//自動寫結(jié)束</p><p>  3.1.8設(shè)置數(shù)據(jù)顯示在屏幕上的坐標程序</p><p>  // (以字節(jié)為單位),x表示顯示的行(

45、0~15),y表示顯示的列(0~19)</p><p>  void Set_xy(unsigned char x,unsigned char y)</p><p>  {unsigned int a;a=x*20+y;</p><p>  Write_Data2(a&0xff,a>>8,ADR_POS);}</p><p&g

46、t;  3.1.9設(shè)置數(shù)據(jù)存儲起始地址</p><p>  void Set_Addr(unsigned char Addr1,unsigned char Addr2)</p><p>  {Write_Data2(Addr1,Addr2,ADR_POS);}</p><p>  3.1.10 CGRAM偏置地址設(shè)置函數(shù)</p><p>  

47、void Set_CGRAM()</p><p>  {Write_Data2(1,0,CGR_POS);}</p><p>  3.1.11液晶初始化函數(shù)</p><p>  //(文本區(qū)首地址D1,文本區(qū)首地址D2, 文本區(qū)寬度, 圖形區(qū)首地址D1, </p><p>  //圖形區(qū)首地址D2, 圖形區(qū)寬度, 光標形狀, 顯示方式

48、, 顯示開關(guān))</p><p>  void LCD_Init(unsigned char Txt1,unsigned char Txt2,unsigned char Txt_Wide,</p><p>  unsigned char Map1,unsigned char Map2,unsigned char Map_Wide,</p><p>  unsigne

49、d char Guang_Biao,unsigned char Disp_Mode,unsigned char Kai_Guan)</p><p>  {Write_Data2(Txt1,Txt2,TXT_STP);</p><p>  Write_Data2(Txt_Wide,0,TXT_WID);</p><p>  Write_Data2(Map1,Map2,

50、GRH_STP);</p><p>  Write_Data2(Map_Wide,0,GRH_WID);</p><p>  Write_Com(CUR_SHP|Guang_Biao);</p><p>  Write_Com(Disp_Mode);</p><p>  Write_Com(DIS_SW|Kai_Guan);}</p&g

51、t;<p>  3.1.12顯示一個漢字子程序</p><p>  //x表示顯示的行(0~15),y表示顯示的列(0~19),n表示字在表格中的位置</p><p>  void Han_Zi(unsigned char x,unsigned char y,unsigned char Addr)</p><p>  {Set_xy(x,y);<

52、/p><p>  Write_8_Data(Addr,INC_WR);</p><p>  Write_8_Data(Addr+2,INC_WR);</p><p>  Set_xy(x+1,y);</p><p>  Write_8_Data(Addr+1,INC_WR);</p><p>  Write_8_Data(

53、Addr+3,INC_WR);}</p><p>  3.1.13 清屏程序</p><p>  void Clear_LCD()</p><p>  {unsigned int a;</p><p>  Set_xy(0,0);//從最左上角開始</p><p>  for(a=0;a<320;a++)//清屏

54、320字節(jié)</p><p>  Write_8_Data(0x83,INC_WR);}// 數(shù)據(jù)寫,地址加1</p><p>  3.1.14 自定義字符寫入CGROM函數(shù)</p><p>  void Write_CGORM()</p><p>  {unsigned int a;</p><p>  Set_CGR

55、AM();Set_Addr(0,0x0c);</p><p>  for(a=0;a<992;a++)//992字節(jié)</p><p>  Write_8_Data(Tab[a],INC_WR);}</p><p>  3.1.15 設(shè)置點顯示在屏幕上的坐標(以位為單位)</p><p>  //x表示顯示的行(0~127),y表示顯示的

56、列(0~159),n=1表示打一點,n=0清除一點</p><p>  void Point(unsigned char x,unsigned char y,bit n)</p><p>  {unsigned char point;</p><p>  unsigned int temp;</p><p>  temp=x*20+y/8+3

57、20;point=0xf7-y%8;</p><p>  if(n)point|=0xf8;</p><p>  else point&=0xf7;</p><p>  Write_Data2(temp&0xff,temp>>8,0x24);//設(shè)置寫地址</p><p>  Write_Com(point);}

58、</p><p>  3.1.16 畫圓子程序,其中x0,y0表示圓心,R表示半徑</p><p>  //先打第一象限內(nèi)的1/4段圓弧,再依據(jù)對稱原理打出其他3段圓弧</p><p>  void Circle(unsigned char x0,unsigned char y0,unsigned R,bit n)</p><p>  {un

59、signed char i,j=0;</p><p>  Point(x0,y0,n);</p><p>  for(i=0;i<=R;i++)</p><p>  { while(1)</p><p>  { if(R*R-i*i<=j*j)break; j++;}</p><p>  Point(x0-

60、j,y0+i,n);Point(x0-i,y0+j,n); //第一象限打點</p><p>  Point(x0+j,y0+i,n);Point(x0+i,y0+j,n); //第二象限打點</p><p>  Point(x0+j,y0-i,n);Point(x0+i,y0-j,n); //第三象限打點</p><p>  Point(x0-j,y0-i,n);

61、Point(x0-i,y0-j,n); //第四象限打點</p><p><b>  j=0; }}</b></p><p>  3.2 初始化代碼設(shè)計[6]</p><p>  //初始化代碼里包含定時器0、1的相關(guān)參數(shù)設(shè)置,初始化開機界面顯示等。</p><p>  EA=ET0=ET1=1;//開啟中斷總開關(guān),允許

62、外部中斷0、1中斷</p><p>  TMOD=0x11;//將定時器0、1都設(shè)為定時模式且工作在方式一。</p><p>  TH0=64800/256;//定時器0初始值裝載,用于按鍵發(fā)聲</p><p>  TL0=64800%256;</p><p>  TH1=0x3c;// 定時器1初始值裝載,每25ms中斷一次</p&g

63、t;<p><b>  TL1=0xb0;</b></p><p>  Init_disply();//調(diào)用開機界面顯示子函數(shù),包含了開機界面的所有內(nèi)容</p><p>  3.3 游戲時間代碼設(shè)計</p><p>  if(F) //當程序檢測到讀時間標志位F=1(由定時器1控制)時會刷新一次時間。</p><

64、;p>  {F=0;//為下一次做準備</p><p>  Set_xy(13,17);//設(shè)置百位數(shù)字顯示的位置</p><p>  Write_8_Data(0x10+Time/100,0xc4);//得到時間的百位數(shù)據(jù)</p><p>  Set_xy(13,18); //設(shè)置十位數(shù)字顯示的位置</p><p>  Write_8

65、_Data(0x10+Time%100/10,0xc4);//得到時間的十為數(shù)據(jù)</p><p>  Set_xy(13,19); //設(shè)置個位數(shù)字顯示的位置</p><p>  Write_8_Data(0x10+Time%10,0xc4);}//得到時間的個位數(shù)據(jù)</p><p>  3.4 游戲選關(guān)代碼設(shè)計</p><p>  //當按

66、下選關(guān)按鍵后,主程序調(diào)用選關(guān)函數(shù),程序代碼如下:</p><p>  void Choice_Customs()</p><p>  {Time=Steps=0;//選關(guān)時將時間、步數(shù)歸零</p><p>  New_Step();//更新步數(shù)顯示</p><p>  Custom=Cust;//將選得的關(guān)傳給關(guān)數(shù)寄存器</p>

67、<p>  New_Custom();//更新關(guān)數(shù)顯示</p><p>  Dispaly();//更新地圖顯示</p><p>  Cust++;//沒按下一次鍵鍵關(guān)數(shù)加一</p><p>  if(Cust==18)Cust=1;}//如果關(guān)數(shù)等于18則回到第一關(guān)(游戲總共17關(guān))</p><p>  3.5 步數(shù)、關(guān)數(shù)更新代

68、碼設(shè)計[7]</p><p>  3.5.1 步數(shù)更新代碼設(shè)計</p><p>  //當按下任意一個方向鍵,且箱子能移動時,會調(diào)用游戲步數(shù)更新子程序</p><p>  void New_Step()</p><p>  {Set_xy(7,17); //設(shè)置百位數(shù)字顯示的位置</p><p>  Write_8_D

69、ata(0x10+Steps/100,0xc4); //得到步數(shù)的百位數(shù)據(jù)</p><p>  Set_xy(7,18); //設(shè)置十位數(shù)字顯示的位置</p><p>  Write_8_Data(0x10+Steps%100/10,0xc4); //得到步數(shù)的十位數(shù)據(jù)</p><p>  Set_xy(7,19); //設(shè)置個位數(shù)字顯示的位置</p>

70、<p>  Write_8_Data(0x10+Steps%10,0xc4);} //得到步數(shù)的個位數(shù)據(jù)</p><p>  3.5.2 關(guān)數(shù)更新代碼設(shè)計</p><p>  void New_Custom()</p><p>  {Set_xy(1,18);// 設(shè)置十位數(shù)字顯示的位置</p><p>  Write_8_Dat

71、a(0x10+Custom/10,0xc4);// 得到關(guān)數(shù)的十位數(shù)據(jù)</p><p>  Set_xy(1,19);// 設(shè)置個位數(shù)字顯示的位置</p><p>  Write_8_Data(0x10+Custom%10,0xc4);}// 得到關(guān)數(shù)的個位數(shù)據(jù)</p><p>  3.6 過關(guān)代碼設(shè)計</p><p>  //當所有箱子都推

72、到指定位置時,會調(diào)用過關(guān)子程序,代碼如下:</p><p>  void Pass()</p><p>  {unsigned char i,j,a=1;//內(nèi)存空間分配</p><p>  for(i=0;i<8;i++)//掃描8行</p><p>  {if(!a)break;//如果a=0則直接跳出函數(shù)</p>&

73、lt;p>  for(j=0;j<9;j++) //掃描9列 </p><p>  //如果關(guān)卡數(shù)組表格中此位置是叉圖形或箱子和叉重合后的圖

74、 </p><p>  if(Customs[Custom-1][i][j]==5||Customs[Custom-1][i][j]==4)</p><p>  //如果動作跟蹤數(shù)組里此位置是箱子和叉重合后的圖,則將a置1</p><p>  if(Follow_Action[i][j]==5)a=1;</p><p

75、>  //如果動作跟蹤數(shù)組里此位置不是箱子和叉重合后的圖,則將a置0,并退出</p><p>  else {a=0;break;}}</p><p>  if(a){Custom++;//如果a=1則將關(guān)數(shù)加一(因為所有箱子都已推好,可以過關(guān))</p><p>  Steps=Time=0;//過關(guān)時將時間、步數(shù)歸零</p><p>

76、  New_Step();//更新步數(shù)顯示</p><p>  if(Custom==18)Custom=1;//如果關(guān)數(shù)等于18則回到第一關(guān)(游戲總共17關(guān))</p><p>  New_Custom();//更新關(guān)數(shù)顯示</p><p>  Dispaly();}}//更新地圖顯示</p><p>  3.7圖形顯示子程序</p&g

77、t;<p>  圖形顯示子程序包括地圖顯示程序和原來位置顯示子程序兩個</p><p>  3.7.1 地圖顯示子程序</p><p>  //在調(diào)用過關(guān)函數(shù)或選關(guān)函數(shù)時,會調(diào)用到顯示子函數(shù),功能是刷新地圖</p><p>  void Dispaly()</p><p>  {unsigned char i,j,a;</

78、p><p>  for(i=0;i<8;i++)//掃描8行</p><p>  {for(j=0;j<9;j++)//掃描9列</p><p>  {Follow_Action[i][j]=Customs[Custom-1][i][j];將關(guān)卡數(shù)組中的數(shù)據(jù)傳給跟蹤數(shù)組

79、 </p><p>  a=Follow_Action[i][j];//將跟蹤數(shù)組中的數(shù)據(jù)傳給動態(tài)內(nèi)存</p><p>  switch(a)//根據(jù)內(nèi)存中的數(shù)據(jù)做出判斷</

80、p><p>  {case 0:a=0x80;break;//如果是0(空白)則將空白字模的地址80H傳給內(nèi)存</p><p>  //如果是1(人物)則將人物字模的地址94H傳給內(nèi)存,并記錄人物位置所在坐標</p><p>  case 1:a=0x94;x_Coordinate=i;y_Coordinate=j;break;</p><p>

81、  case 2:a=0x84;break;// 如果是2(墻壁)則將墻壁字模的地址84H傳給內(nèi)存</p><p>  case 3:a=0x8c;break;// 如果是3(箱子)則將箱子字模的地址8cH傳給內(nèi)存</p><p>  case 4:a=0x88;break;// 如果是4(叉)則將叉字模的地址88H傳給內(nèi)存</p><p>  case 5:a=0

82、x90;break;}//如果是5(箱子和叉重合)則將地址90H傳給內(nèi)存</p><p>  Han_Zi(2*i,2*j,a);}}}//調(diào)用寫漢字程序,將圖形顯示出來</p><p>  3.7.2原來位置顯示子程序</p><p>  //此程序顯示當人物移動后,人物本身位置所要顯示的圖形</p><p>  void _Display

83、()</p><p>  {if(a==0||a==3||a==1) //如果原來人物這個位置是空白或是箱子則顯示一個空白</p><p>  {Han_Zi(2*x_Coordinate,2*y_Coordinate,0x80);// 將空白圖形顯示出來</p><p>  Follow_Action[x_Coordinate][y_Coordinate]=0;}

84、//更新跟蹤數(shù)組中的內(nèi)容</p><p>  //如果人物本身這里是一個叉圖形或是箱子或叉重合后的圖則顯示一個叉</p><p>  if(a==4||a==5)</p><p>  {Han_Zi(2*x_Coordinate,2*y_Coordinate,0x88);// 將叉圖形顯示出來</p><p>  Follow_Action[

85、x_Coordinate][y_Coordinate]=4;}}// 更新跟蹤數(shù)組中的內(nèi)容</p><p>  3.8 中斷代碼設(shè)計</p><p>  中斷代碼設(shè)計包括定時器0和1兩段,定時器0為中斷發(fā)聲代碼,定時器1為中斷計時代碼,代碼如下:</p><p>  3.8.1 定時器0中斷發(fā)聲程序</p><p>  void Time_0

86、_Int() interrupt 1 using 0</p><p>  {TH0=64800/256;TL0=64800%256;//定時器0初值設(shè)定</p><p>  Count++;//每次進入中斷,發(fā)聲計數(shù)數(shù)據(jù)加1</p><p>  if(Count==150)TR0=Count=0;//發(fā)聲100ms后Count中數(shù)據(jù)歸零,并關(guān)定時器</p>

87、;<p>  Speaker=~Speaker;}//喇叭引腳電平取反</p><p>  3.8.2 定時器1中斷計時程序</p><p>  void Time_1_Int() interrupt 3 using 1</p><p>  {TH1=0x3c;TL1=0xb0;// 定時器1初值設(shè)定</p><p>  Cou

88、nts++;//每次進入中斷,計時計數(shù)數(shù)據(jù)加1</p><p>  if(Counts==40)//如果1秒中到</p><p>  {Counts=0;Time++;F=1;}}// Counts數(shù)據(jù)歸零,時間全局量加1,讀時間標志置1</p><p>  3.9 方向控制代碼設(shè)計[8]</p><p>  游戲共有4個方向鍵,每一個鍵代碼

89、編寫的原理,判斷順序及執(zhí)行何種操作都是一樣的,不同的是方向各不相同,現(xiàn)已向上推箱子為例詳細說明其執(zhí)行過程。</p><p>  void On_Push()//向上推子函數(shù)</p><p>  {Cust=1;//關(guān)數(shù)計數(shù)器置一,為選關(guān)做準備</p><p>  a=Customs[Custom-1][x_Coordinate][y_Coordinate];//原來

90、人物這個位置是什么</p><p>  b=Follow_Action[x_Coordinate-1][y_Coordinate]; //現(xiàn)在人物位置上面是什么

91、 </p><p>  if(b==0||b==4)//如果現(xiàn)在人物位置上面是空白或是叉圖形則顯示一個人物</p><p>  {Steps++;//箱子可以移動,步數(shù)加1</p><p>  New_Step();//更新步數(shù)</p><p>  Han_Zi(2*

92、(x_Coordinate-1),2*y_Coordinate,0x94);//在上面顯示人物</p><p>  _Display();//調(diào)用原來位置顯示子程序,還原人物本身位置圖形</p><p>  x_Coordinate--;}//更新人物坐標</p><p>  if(b==3||b==5)//如果現(xiàn)在人物位置上面是箱子或是箱子和叉重合的圖形則還得判/

93、/斷人物上面的上面是什么圖形,如果人物上面的上面不是箱子、墻壁和箱子和叉//重合后的圖形則可以移動</p><p>  {if(Follow_Action[x_Coordinate-2][y_Coordinate]!=2&&Follow_Action[x_Coor</p><p>  dinate-2][y_Coordinate]!=3&&Follow_Ac

94、tion[x_Coordinate-2][y_Coordinate]!=5)</p><p>  {Steps++;//箱子可以移動,步數(shù)加1</p><p>  New_Step();//更新步數(shù)</p><p>  //如果現(xiàn)在人物位置上面的上面是空白</p><p>  if(Follow_Action[x_Coordinate-2][

95、y_Coordinate]==0)</p><p>  {Han_Zi(2*(x_Coordinate-2),2*y_Coordinate,0x8c);//則在上面的上面顯示個箱子</p><p>  Follow_Action[x_Coordinate-2][y_Coordinate]=3;}//更新箱子的位置</p><p>  //如果現(xiàn)在人物位置上面的上面是

96、叉</p><p>  else if(Follow_Action[x_Coordinate-2][y_Coordinate]==4)</p><p>  {//則在上面的上面顯示一個箱子和叉重合后的圖</p><p>  Han_Zi(2*(x_Coordinate-2),2*y_Coordinate,0x90);</p><p>  Fo

97、llow_Action[x_Coordinate-2][y_Coordinate]=5; }//更新箱子和叉重合的位置</p><p>  Han_Zi(2*(x_Coordinate-1),2*y_Coordinate,0x94); //在上面顯示一個人物</p><p>  //如果現(xiàn)在人物位置上面是箱子則更新為空白(因為箱子已經(jīng)移掉了)</p><p>  i

98、f(b==3)Follow_Action[x_Coordinate-1][y_Coordinate]=0;</p><p>  //如果現(xiàn)在人物位置上面是箱子和叉重合的圖則更新為叉(因為箱子已經(jīng)移掉了)</p><p>  if(b==5)Follow_Action[x_Coordinate-1][y_Coordinate]=4;</p><p>  _Displa

99、y();//調(diào)用原來位置顯示子程序,顯示人物本身位置所要顯示的圖形</p><p>  x_Coordinate--;//更新人物坐標</p><p>  Pass();}}}//調(diào)用過關(guān)子程序,判斷是否過關(guān)</p><p>  4 推箱子游戲的系統(tǒng)仿真[9,10,11,12]</p><p>  在仿真前先介紹有關(guān)工程項目的建立及編譯生成

100、可執(zhí)行文件(*.Hex)的具體過程。</p><p>  4.1建立工程項目流程</p><p>  1)建立一個新工程 單擊Project菜單,在彈出的下拉菜單中選中New Project選項,如下圖 </p><p>  2)然后選擇你要保存的路徑,輸入工程文件的名字,比如保存到C51目錄里,工程文件的名字為C51,如下圖所示,然后點擊保存.</p>

101、;<p>  3)這時會彈出一個對話框,要求你選擇單片機的型號,你可以根據(jù)你使用的單片機來選擇,keil c51幾乎支持所有的51核的單片機,我這里還是以大家用的比較多的Atmel 的89C51來說明,如下圖所示,選擇89C51之后,右邊欄是對這個單片機的基本的說明,然后點擊確定.</p><p>  4)完成上一步驟后,屏幕如下圖所示 </p><p>  5)在下圖中,單

102、擊“File”菜單,再在下拉菜單中單擊“New”選項 ,如果已經(jīng)寫好了C文件則直接添加為文件,這一步可去掉。</p><p>  新建文件后屏幕如下圖所示</p><p>  在建立目標文件之前,首先要將文件添加到組里去。具體操作如下:將鼠標箭頭移至中間左邊項目窗口中的“Source Group 1”前的圖標上,再單擊鼠標右鍵,在彈出的菜單項中選擇“Add files to Group ‘

103、Source Group 1’”。在彈出的對話框中選擇剛才編輯保存好的源程序文件;需點“文件類型”右側(cè)文本框中的倒三角,在彈出的下拉菜單中選“All files(*.*)”,然后再找到程序文件。點“Add”按鈕,再在彈出的對話框中選擇文件類型,如“Assembly language file”;再點“Close”按鈕。若是C語言源程序文件“*.c”;或匯編語言的源程序文件“*.asm”,則點“文件類型”右側(cè)文本框中的倒三角,在彈出的下

104、拉菜單中選“c source file”或“asm source file”,然后再找到程序文件。點“Add”按鈕,再點“Close”按鈕。此時按鈕建立目標“Build target”前的編譯當前文件“Translate current file”按鈕的顏色也變深了。而在中間左邊項目窗口中的“Source Group 1”前多了一個“+”號。</p><p>  Keil中文件的添加</p><

105、;p>  完成上述操作后方可進入建立目標文件。通常先點編譯當前文件“Translate current file”,再建立目標文件“Build target”;或直接點重建目標文件“Rebuild all target files”。即可生成我們需要的后綴名為HEX的十六進制文件。編譯或匯編的結(jié)果見如圖所示,上面提示“0個錯誤、0個報警”。如果在編譯、連接中出現(xiàn)錯誤,則可按照提示進行檢查。這個文件就是我們要下載到單片機中的程序文件

106、。</p><p>  圖6 Keil工程項目目標文件生成</p><p>  4.2 Proteus中原理圖的繪制及文件的加載</p><p>  依照仿真電路在Proteus中繪圖,如下圖所示</p><p>  Proteus中的推箱子原理圖</p><p>  雙擊單片機彈出對話框,在Clock Freque

107、ncy欄中將晶振設(shè)置為24MHz,在Program file欄中加載“推箱子.Hex”文件,再單擊OK設(shè)置完成,圖片如下:</p><p>  單片機文件加載及晶振設(shè)置</p><p>  至此仿真前的準備工作都已經(jīng)全部完成,接下來正式進入仿真調(diào)試。</p><p>  4.3 開機界面顯示</p><p>  點擊仿真按鈕,程序調(diào)用初始化函

108、數(shù),進入開機界面顯示,圖片如下:</p><p>  4.4 游戲界面顯示</p><p>  當進入開機界面顯示后,只有確定鍵有效,其他按鍵被鎖定,當按下確定鍵后,確定鍵失效,其他鍵鎖定解除,畫面進入第一關(guān)游戲界面顯示,關(guān)數(shù)、步數(shù)、時間開始記錄數(shù)據(jù),圖片如下:</p><p>  第一關(guān)游戲界面 第四關(guān)游戲界面</p>&

109、lt;p>  第六關(guān)游戲界面 第八關(guān)游戲界面</p><p>  第十關(guān)游戲界面 第十二關(guān)游戲界面</p><p>  第十四關(guān)游戲界面 第十七關(guān)游戲界面</p><p>  4.5 仿真結(jié)果分析及解決方法</p><p>  通過以上給出的仿真波形分析可知,本

110、設(shè)計中的各項功能夠很好的實現(xiàn)。在時鐘脈沖的作用下,各個按鍵都能按照事先設(shè)定好的規(guī)則進行游戲控制。確定鍵能使界面從初始化顯示切換到游戲界面顯示,上下左右鍵控制箱子的移動方向,如果可以移動則移動方塊同時跟蹤人物的位置及刷新動態(tài)數(shù)組的內(nèi)容。在游戲的同時程序會隨時記錄玩家所走的游戲步數(shù)、游戲時間,直至本關(guān)通過,在進入下一關(guān)的同時更新地圖并刷新游戲步數(shù)和時間。選關(guān)鍵用于選擇游戲關(guān)數(shù),在游戲過程中這個鍵任何時候都有效,當按下選關(guān)鍵后,游戲地圖返回第

111、一關(guān),再次按下時游戲進入二關(guān),這樣每按下一次鍵游戲關(guān)數(shù)加一,如果游戲到了第17關(guān)將自動返回第一關(guān)。</p><p>  游戲在主程序中設(shè)了按鍵去抖程序。既在實際當中由于偶然的原因鍵盤抖動而導(dǎo)致引腳電平為低人后瞬間又恢復(fù)為高,或雖然只是按下按鍵一次然后放掉,結(jié)果在按鍵信號穩(wěn)定前后,竟出現(xiàn)了一些不該存在的噪聲,這些情況下按鍵是并沒有真的被按下的,如果沒有去抖動程序,游戲會將其當做一次正確的按鍵操作去執(zhí)行相應(yīng)功能,這樣

112、就會引起電路的誤動作。處理方法是:當掃描到有鍵按下時,軟件演示10ms在判斷改鍵時候仍是按鍵,若是這按鍵有效,同時喇叭發(fā)聲,否則,把它當成是誤操作處理。這樣大大提高了程序的可靠性。</p><p>  本游戲還是有一些不足之處,比如沒有設(shè)置超時提示、游戲地圖界面比較小,最大的地圖也只有8行9列,對于一些大的地圖無法顯示、游戲發(fā)聲也比較單調(diào),只有一個頻率的聲音、雖然代碼幾經(jīng)修改也難免有不足之處,代碼的優(yōu)化程度可能是

113、個問題,要知道代碼越多單片機執(zhí)行速度就越慢,依靠提高晶振頻率來提高速度是不能解決問題的實質(zhì)的。沒修改之前代碼長度至少多出現(xiàn)在一半,但我不能說現(xiàn)在的就是最精煉的,可能有待改進的地方還很多。</p><p>  在沒有優(yōu)化代碼之前數(shù)據(jù)代碼段的128字節(jié)存儲區(qū)遠遠不夠,當時我考慮外部擴展數(shù)據(jù)存儲區(qū),但那樣一來不僅電路復(fù)雜,且程序長度和讀寫速度都受到影響,幾經(jīng)修改終于將數(shù)據(jù)區(qū)壓縮到101.3字節(jié),省去了外部數(shù)據(jù)存取器使電

114、路變得更加簡潔, 同時也降低控制器的成本。</p><p><b>  5 總結(jié)</b></p><p>  在這段設(shè)計的過程中,確實也遇到很多的困難。首先,第一次獨立完成這樣的畢業(yè)設(shè)計,開始的時候不知從何下手,沒有頭緒,這是讓我最頭痛的事情。其次用單片機邊游戲是一個不常見的課題,這方面的資料不是很多,所有的一切只有靠自己去摸索,這是一個比較漫長的過程。在求助于老師、

115、理清思路后,于是到圖書館、網(wǎng)上查閱資料,終于攻克畢業(yè)設(shè)計中的道道難題。其中繪制電路原理圖、編程是考驗我的一道難題。經(jīng)過指導(dǎo)老師楊老師的耐心指點和連續(xù)一個星期的奮戰(zhàn)才算基本合格。隨后畫電路圖,寫程序,仿真都沒少讓我傷透腦筋。但是,當我把這些問題都解決后,我發(fā)現(xiàn)我收獲了不少,通過查資料讓我了解了直流電機工作原理及用途、PWM控制技術(shù)、鍵盤電路接口技術(shù)、時鐘電路技術(shù)等等,同時也讓我學(xué)習(xí)現(xiàn)代電子產(chǎn)品的設(shè)計流程,為以后從事產(chǎn)品開發(fā)打好了基礎(chǔ)。&l

116、t;/p><p>  雖然我的這次論文作品并不是很完善,還有很多的不足之處,但是我仍可以肯定地說,這里面的每一個圖、每一個字,都是經(jīng)過我的大腦篩選出來的。當看著自己排好的版面符合設(shè)計的要求,自己編寫的程序能夠按照設(shè)計的要求正常運行時,心里多少有點成就感和欣慰。我相信在這設(shè)計過程中的所有酸甜苦辣最終都會化為甜美的甘泉。</p><p>  這次做畢業(yè)設(shè)計的經(jīng)歷也會使我受益匪淺。我認為不管做畢業(yè)設(shè)

117、計也好,還是做其他什么樣的事也好,都要努力去做,還要用心去學(xué),更要有堅持不懈的精神,只有這樣才能收獲到最好的果實。</p><p><b>  參考文獻:</b></p><p>  1任治剛.《電子信息工程專業(yè)英語教程》[M]北京.電子工業(yè)出版社.2006.129-15</p><p>  2 張萬奎.《模擬電子技術(shù)》[M].湖南.湖南大學(xué)出

溫馨提示

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

評論

0/150

提交評論