用 51 單片機做的二十四點小游戲
一、任務要求
設計一個模擬紙牌 24 點玩法的單片機模擬器,由單片機隨機發出四個牌點,測試者在實驗板按鍵上輸入計算過程,單片機判斷計算結果是否正確,并評定測試者的成績。
【基本要求】:
1.測試多組數據
2.單片機在數碼管上隨機給出 4 張牌點,牌點范圍為 1-13,10 到 13 由字符 a,b,c,d 表示
3.在單片機實驗板按鍵中設計 4 個數學運算鍵 +-×÷
4.4 個數字中每使用完一個后該字符應有明顯標識
5.只允許測試者使用四則運算(可加括號)
6.無論測試結果是否正確,均有聲光效果提示;
7.測試完畢,由單片機給出測試者的最終成績
二、功能特點與使用說明
功能特點:
1.使用最低的系統時鐘頻率,降低功耗
2.鍵盤掃描使用了軟件消抖,防止按鍵被重復判別為彈起或按下
3.鍵值判斷使用的是鍵值跳變判斷,即使你一直將鍵盤按下,也不會重復執行命令
4.使用后綴表達式計算字符串算式,代碼簡潔易懂
使用說明
各鍵盤功能如表所示:
三、方案設計
1.資源分配:
(1)使用外部晶振 22.1184MHz,使用二分頻作為系統時鐘;
(2)定時器 T2:
開啟中斷,系統時鐘 12 分頻,16 位自動重裝模式;
初始值和自動重裝值均為 FB80,計算(65536-0xFB80)(12/11059200)=0.00125s=1.25ms,即中斷 1.25ms 發生一次;該定時器用來產生 1.25ms 定時,用來掃描鍵盤,判斷其是否被按下,掃描按鍵,完成一次輪詢掃描時間為 51.25ms=6.25ms
(3)定時器 T4:
開啟中斷,系統時鐘 12 分頻,16 位自動重裝模式;
初始值和自動重裝值均為 FB80,計算(65536-0xFB80)*(12/11059200)=0.00125s=1.25ms,即中斷 1.25ms 發生一次;該定時器用來產生 1.25ms 定時,用來掃描鍵值,并執行相應的鍵盤操作
(4)使用了比較多的全局變量,將不需要修改的常量數據存入外部 RAM 中
2.設計思路:
鍵盤設計思路:首先通過 T2 掃描鍵盤,判斷鍵盤是否被按下,這里運用了軟件消抖的方法,連續檢測到四次鍵盤被按下(或松開)才會把鍵值數組里相應的地方置為 1(0)。然后通過 T4 掃描鍵值數組,如果檢測到跳變(防止一直按著某個鍵,其鍵值一直為 1,導致其功能一直被反復執行),且跳變后鍵值為 1,則執行此鍵位的命令。
LCD 屏設計思路:通過字模軟件生成數字字母及運算符號的 32 位字模數組,通過選擇左右屏以及生成的 X,Y 坐標可以將數字顯示在自己想要的地方主程序設計思路:隨機生成四個數并將其存在一個數組之中,然后顯示在屏幕的上方。按鍵選擇數或符號,每選擇了一個數,就會將其原數所在的區域清除,表示此數以及被選擇了,然后將此數或此符號用字符的形式存在一個字符數組里面,最后按下等于鍵,就會運行計算此字符數組對應的表達式的值的程序,最后結果算出來如果等于 24,則會亮起黃燈,如果錯誤則會亮綠燈。
計算字符串表達式的設計思路:
1.中綴表達式轉換為后綴表達式:a).數字直接入隊列 b).運算符要與棧頂元素比較
① 棧為空直接入棧
② 運算符優先級大于棧頂元素優先級則直接入棧
③ 小于或等于則出棧入列,再與棧頂元素進行比較,直到運算符優先級小于棧頂元
素優先級后,操作符再入棧 c).操作符是(則無條件入棧
d).操作符為),則依次出棧入列,直到匹配到第一個(為止,此操作符直接舍棄,(直接出棧舍棄
2.通過逆波蘭表達式計算結果:獲取字符串表達式的每一項,判斷這一項是數據還是操作符,如果是數據,則讓它入棧,如果是操作符,讓數據出棧,和操作符進行運算
四、流程圖
1.主程序 intmain()
2.按鍵檢測子程序 voidKeyboardDriver()
3.按鍵掃描子程序 voidKeyscan(unsignedcharscannum)
4.中綴表達式轉后綴表達式子程序
5.隨機數生成子程序 voidset_24()
六、程序測試方法與結果
再按一次生成四個隨機數
多次按下可見四個數完全隨機
測試按鍵,選擇第一個數
可見第一個數被挪下,且原位置數消失接著測試 +-*/<>
可見功能正常
接著測試計算,首先測試算出來的數不是 24
可見 D2(綠燈)亮起,說明計算錯誤
接著測試計算,測試算出來的數是 24
可見經過多重括號計算出的值為 24,D1(黃燈亮),說明整個程序是完整可行符合要求的
七、心得與體會
在本次專題實驗中我再次深刻體會到單片機是將軟件與硬件緊密結合的,軟件的編程無法脫離實際的硬件電路而存在,軟件的編程是為硬件服務的,硬件工程師需要根據實際實際電路編寫程序,而不是純軟件編程。有時候軟件上編寫正確,硬件上不一定可以實現所想的功能,操縱硬件,是單片機課程的魅力所在。
同時,通過這次專題實驗,我強化了我的編程能力,思維,學到了一些編程上的技巧,也學會如何管理自己的代碼等。
本次實驗中我遇到的最大困難是全局變量和函數內靜態變量的使用,不能濫用全局變量和靜態變量,對于小容量的單片機來說,內存資源很寶貴,如果占用太多空間,內存不足會導致程序運行異常,我也在這個問題上卡了很久,以后會更加注意單片機內存的利用。
另外本次實驗還鍛煉了我的動手能力,滿足我動手實踐的需求,讓我這段時間過得相當充實,謝謝老師給我這次機會。