|
設(shè)計一個基于單片機AT89C52的計算機步進電機控制系統(tǒng),使用數(shù)字控制器進行步進電機的起停、正、反轉(zhuǎn)控制以及步進電機的加速、減速控制。 其中,用K0-K5作為通電方式選擇鍵,K0為單四拍正轉(zhuǎn),K1為單四拍反轉(zhuǎn),K2為雙四拍正轉(zhuǎn),K3為雙四拍反轉(zhuǎn),K4為八拍正轉(zhuǎn),K5為八拍反轉(zhuǎn);K6、K7分別為啟動和停止控制;K8,K9為加減速控制,K10,K11為給定步數(shù)加減控制。正轉(zhuǎn)時紅色指示燈亮,反轉(zhuǎn)時黃色指示燈亮,不轉(zhuǎn)時綠色指示燈亮;LED第一位顯示擋位,用后4位LED顯示剩余工作步數(shù)[6]。 2.2 設(shè)計目標步進電機控制仿真,應(yīng)該需要良好的人機界面,使人們操作更為簡便,設(shè)計實現(xiàn)了步進電機的正反轉(zhuǎn),啟停,工作方式選擇,步數(shù)設(shè)定,加減速功能。在元器件的選用上應(yīng)保證其技術(shù)在近5到10年不會被淘汰,應(yīng)從其性能,價格方面考慮。 2.3 需求分析2.4 技術(shù)方案在該系統(tǒng)中,以AT89C52為中心,ULN2003A和28BYJ48四相28BYJ-48-5VDC步進電機是四六線制步進電機構(gòu)成電機電路,通過單片機進行控制;采用3個LED燈構(gòu)成狀態(tài)顯示電路,實時顯示電機狀態(tài);矩陣鍵盤K0~K11將用戶所需來選擇步進電機的工作狀態(tài);6位數(shù)碼管顯示步數(shù)和速度擋位。如下圖 2?1所示,單片機作為主控芯片,控制各個模塊。步進電機調(diào)速需要調(diào)節(jié)脈沖頻率,所以使用單片機的定時器中斷是可行。 圖 2?1 總體設(shè)計框圖 2.5 方案論證通過Proteus仿真軟件實現(xiàn)步進電機的模擬控制。系統(tǒng)各部分時序控制的配合:啟動電源后,通過矩陣鍵盤選擇功能;然后啟動,通過單片機發(fā)出高低脈沖到電機驅(qū)動電機對電機進行驅(qū)動;通過定時器中斷方式實現(xiàn)加減速功能是電機控制的關(guān)鍵點和難點。動態(tài)掃描方式進行數(shù)碼管顯示;在對單片機編程時,通過查閱有關(guān)資料進行理解分析,得到自己想要實現(xiàn)的程序。 最困難的是對定時器中斷進行操作,因為對定時器中斷的不熟悉,一直無法實現(xiàn)理想的控制。通過查閱單片機手冊解決問題。 2.6 本章小結(jié)本章主要對此次設(shè)計進行總體方案的敘述。2.1介紹了課題需求,對課題的要求進行了詳細的敘述;2.2主要對課題的最終要實現(xiàn)的目標進行敘述,對整個時間安排及器件選型時要注意的一些細節(jié);2.3對要完成課題目標需要采用的軟件,外部器件及實現(xiàn)方式進行了敘述;2.4對課程設(shè)計的總體方案進行敘述,并給出了系統(tǒng)總體框圖;2.5對實現(xiàn)此次課程設(shè)計所采用的方案進行了論證 第3章 硬件設(shè)計3.1 單片機AT89S52是一種低功耗、高性能CMOS8位微控制器,具有8K 系統(tǒng)可編程Flash存儲器。使用Atmel 公司高密度非易失性存儲器技術(shù)制造,與工業(yè)80C51 產(chǎn)品指令和引腳完全兼容。片上Flash允許程序存儲器在系統(tǒng)內(nèi)編程,亦適于常規(guī)編程器。在單芯片上,擁有靈巧的8位CPU和在系統(tǒng)可編程Flash,使得AT89S52在眾多嵌入式控制應(yīng)用系統(tǒng)中得到廣泛應(yīng)用。CPU為Atmel公司生產(chǎn)的89C51/89C52/89C55等。出廠所配晶振頻率為11.0592MH,每個機器周期為1.085us,用戶更換晶振以提高速度。單片機引腳圖如下圖 3?1所示: 圖 3?1 單片機引腳圖 引腳介紹: P0口是一個8位漏極開路的雙向I/O口。作為輸出口,每位能驅(qū)動8個TTL邏 輯電平。對P0端口寫“1”時,引腳用作高阻抗輸入。當訪問外部程序和數(shù)據(jù)存儲器時,P0口也被作為低8位地址/數(shù)據(jù)復用。在這種模式下,P0不具有內(nèi)部上拉電阻。在flash編程時,P0口也用來接收指令字節(jié);在程序校驗時,輸出指令字節(jié)。程序校驗 時,需要外部上拉電阻。P1口是一個具有內(nèi)部上拉電阻的8 位雙向I/O口,p1輸出緩沖器能驅(qū)動4 個 TTL 邏輯電平。 此外,P1.0和P1.1分別作定時器/計數(shù)器2的外部計數(shù)輸入(P1.0/T2)和定時器/計數(shù)器2 的觸發(fā)輸入(P1.1/T2EX)。 在flash編程和校驗時,P1口接收低8位地址字節(jié)。P2 口是一個具有內(nèi)部上拉電阻的8 位雙向I/O 口,P2 輸出緩沖器能驅(qū)動 4個TTL邏輯電平。對P2端口寫“1”時,內(nèi)部上拉電阻把端口拉高,此時可以作為輸入 口使用。作為輸入使用時,被外部拉低的引腳由于內(nèi)部電阻的原因,將輸出電流(IIL)。在訪問外部程序存儲器或用16位地址讀取外部數(shù)據(jù)存儲器(例如執(zhí)行MOVX @DPTR)時,P2口送出高八位地址。在這種應(yīng)用中,P2 口使用很強的內(nèi)部上拉發(fā)送1。在使用8位地址(如MOVX @RI)訪問外部數(shù)據(jù)存儲器時,P2口輸出P2鎖存器的內(nèi)容。在flash編程和校驗時,P2口也接收高8位地址字節(jié)和一些控制信號。P3口是一個具有內(nèi)部上拉電阻的8 位雙向I/O 口,p3 輸出緩沖器能驅(qū)動4個TTL邏輯電平。 P3口亦作為AT89S52特殊功能(第二功能)使用,如下表所示。在flash編程和校驗時,P3口也接收一些控制信號。 RST:復位輸入。當振蕩器工作時,RST引腳出現(xiàn)兩個機器周期以上高電平將使單片機復位。 ALE/PROG:當訪問外部程序存儲器或數(shù)據(jù)存儲器時,ALE(地址鎖存允許)輸出脈沖用于鎖存地址的低8位字節(jié)。一般情況下,ALE仍以時鐘振蕩頻率的1/6輸出固定的脈沖信號,因此它可對外輸出時鐘或用于定時目的。要注意的是:每當訪問外部數(shù)據(jù)存儲器時將跳過一個ALE脈沖。對FLASH存儲器編程期間,該引腳還用于輸入編程脈沖(PROG)。如有必要,可通過對特殊功能寄存器(SFR)區(qū)中的8EH單元的D0位置位,可禁止ALE操作。該位置位后,只有一條MOVX和MOVC指令才能將ALE激活。此外,該引腳會被微弱拉高,單片機執(zhí)行外部程序時,應(yīng)設(shè)置ALE禁止位無效. PSEN:程序儲存允許(PSEN)輸出是外部程序存儲器的讀選通信號,當AT89S52由外部程序存儲器取指令(或數(shù)據(jù))時,每個機器周期兩次PSEN有效,即輸出兩個脈沖,在此期間,當訪問外部數(shù)據(jù)存儲器,將跳過兩次PSEN信號。 EA/VPP:外部訪問允許,欲使CPU僅訪問外部程序存儲器(地址為0000H-FFFFH),EA端必須保持低電平(接地)。需注意的是:如果加密位LB1被編程,復位時內(nèi)部會鎖存EA端狀態(tài)。如EA端為高電平(接Vcc端),CPU則執(zhí)行內(nèi)部程序存儲器的指令。FLASH存儲器編程時,該引腳加上+12V的編程允許電源Vpp,當然這必須是該器件是使用12V編程電壓Vpp。 3.2 晶振電路
圖 3?2 晶振電路 3.3 復位電路復位是單片機的初始化工作,復位后中央處理器CPU和單片機內(nèi)的其它功能部件都處在一定的初始狀態(tài),并從這個狀態(tài)開始工作。為了防止程序執(zhí)行過程中失步或運行紊亂,此處我們采用了上電復位,電路圖如下圖 3?3所示:
圖 3?3 復位電路 3.4 單片機最小系統(tǒng)單片機最小系統(tǒng)是單片機運行的最基本條件:電源,單片機芯片,晶振電路,復位電路。電源為整個系統(tǒng)供能,單片機芯片運行程序,處理數(shù)據(jù);晶振電路為單片機工作提供節(jié)拍,常被理解為單片機心臟;復位電路,在單片機上電時需要復位使程序從頭開始運行。 3.5 鍵盤模塊圖 3?4 矩陣鍵盤 3.6 電動機及驅(qū)動步進電機模塊如下圖 3?5所示
圖 3?5 電動機模塊 3.6.1 步進電機本次設(shè)計采用的是
圖 3?6 步進電機 開始時,開關(guān)SB接通電源,SA、SC、SD斷開,B相磁極和轉(zhuǎn)子0、3號齒對齊,同時,轉(zhuǎn)子的1、4號齒就和C、D相繞組磁極產(chǎn)生錯齒,2、5號齒就和D、A相繞組磁極產(chǎn)生錯齒。 當開關(guān)SC接通電源,SB、SA、SD斷開時,由于C相繞組的磁力線和1、4號齒之間磁力線的作用,使轉(zhuǎn)子轉(zhuǎn)動,1、4號齒和C相繞組的磁極對齊。而0、3號齒和A、B相繞組產(chǎn)生錯齒,2、5號齒就和A、D相繞組磁極產(chǎn)生錯齒。依次類推,A、B、C、D四相繞組輪流供電,則轉(zhuǎn)子會沿著A、B、C、D方向轉(zhuǎn)動。步進電機的按通電順序不同,可分為單四拍,雙四拍,八拍三種工作方式。如下圖 3?7所示:
圖 3?7 步進電機工作時序 當步進電機從A,B,C,D四相依次通電時,電動機正轉(zhuǎn),當反向通電則電動機反轉(zhuǎn)。 3.6.2 驅(qū)動電路ULN2003A電路是美國Texas+Instruments公司和Sprague公司開發(fā)的高壓大電流達林頓晶體管陣列電路。ULN2003是高耐壓、大電流、內(nèi)部由七個硅NPN和達林頓管組成的驅(qū)動芯片,如圖 3?8所示。經(jīng)常在以下電路中使用,作為:顯示驅(qū)動、繼電器驅(qū)動、照明燈驅(qū)動、電磁閥驅(qū)動、伺服電機、步進電機驅(qū)動等電路中。該電路的特點如下:ULN2003的每一對達林頓都串聯(lián)一個2.7K的基極電阻,在5V的工作電壓下它能與TTL和CMOS電路直接相連,可以直接處理原先需要標準邏輯緩沖器來處理的數(shù)據(jù)。ULN2003 是高壓大電流達林頓晶體管陣列系列產(chǎn)品,具有電流增益高、工作電壓高、溫度范圍寬、帶負載能力強等特點,適應(yīng)于各類要求高速大功率驅(qū)動的系統(tǒng)。ULN2003 工作電壓高,工作電流大,灌電流可達500mA,并能在關(guān)態(tài)時承受50V 的電壓,輸出還可以在高負載電流并行運行。
圖 3?8 ULN2003邏輯圖 3.7 狀態(tài)顯示模塊LED發(fā)光二極管顯示步進電機的工作狀態(tài),它們分別接到單片機的P3.4~P3.6。如下圖 3?9所示,讓單片機連接到LED陰極,LED陽極接VCC。這樣通過設(shè)置端口電平就能使LED亮滅,達到顯示效果。本設(shè)計中,綠燈代表停止,紅燈代表正轉(zhuǎn),黃燈代表反轉(zhuǎn)。
圖 3?9 LED狀態(tài)顯示 3.8 數(shù)碼管顯示LED數(shù)碼管實際上是由七個發(fā)光管組成8字形構(gòu)成的,加上小數(shù)點就是8個。這些段分別由字母a,b,c,d,e,f,g,dp來表示。當數(shù)碼管特定的段加上電壓后,這些特定的段就會發(fā)亮,以形成我們眼睛看到的字樣了。通過分時輪流控制各個LED數(shù)碼管的COM端,就使各個數(shù)碼管輪流受控顯示,這就是動態(tài)驅(qū)動。 本課題采用六位共陰極數(shù)碼管來對電機步數(shù),速度擋位進行顯示。電路如下,接在單片機P0口i,P0必須添加上拉電阻,以為P0扣不加上拉電阻時處于開漏狀態(tài),只允許輸出低電平,加上拉電阻后可輸出高電平。電路如下圖 3?10所示。
圖 3?10 數(shù)碼管電路 3.9 本章小結(jié)本章主要是對硬件設(shè)計的描述。先是呈現(xiàn)出總硬件系統(tǒng)框圖及AT89S52單片機的接口及各種特性,再進行各部分電路的設(shè)計的原理,即:晶振電路,復位電路,鍵盤設(shè)計,驅(qū)動電路,電機工作狀態(tài)顯示部分,步數(shù)顯示部分。 第4章 軟件設(shè)計4.1 功能框圖步進電機控制系統(tǒng)功能框圖如下圖 4?1所示,說明了每個模塊與單片機之間的聯(lián)系,控制邏輯;通過單片機控制鍵盤掃描,數(shù)碼管顯示,LED顯示,步進電機控制等。 圖 4?1功能框圖 4.2 主流程圖圖 4?2 主流程圖 首先進行工作方式選擇,按下啟動按鈕,單片機判斷是否啟動,如果沒啟動綠燈亮,啟動后默認正轉(zhuǎn)紅燈亮,可通過選擇反轉(zhuǎn),反轉(zhuǎn)時紅燈亮。由此可以讓步進電機按照指定的方式運轉(zhuǎn),并且剩余步數(shù)顯示到數(shù)碼管上;單片機判斷步數(shù)是否走完。
4.3 步進電機模塊4.3.1 步進電機工作方式說明4.3.2 實現(xiàn)流程
圖 4?3 工作方式選擇 4.4 矩陣鍵盤模塊矩陣鍵盤是整個系統(tǒng)中最重要的環(huán)節(jié),本設(shè)計采用3*4矩陣鍵盤,通過行列掃描獲取鍵值。流程圖如下圖 4?4所示:
圖 4?4 鍵盤掃描 4.5 數(shù)碼管顯示模塊
圖 4?5 數(shù)碼管顯示 4.6 本章小結(jié)本章主要描述了步進電機實現(xiàn)過程軟件的設(shè)計思路,包括功能框圖,主流程圖,步進電機模塊,關(guān)于工作方式的說明,鍵盤模塊設(shè)計,數(shù)碼管顯示設(shè)計。 第5章 測試和驗證5.1 任務(wù)分工5.2 搭建環(huán)境使用Kiel編寫單片機程序,在Proteus中搭建仿真環(huán)境,將可執(zhí)行程序加載到仿真單片機中,進行仿真,驗證設(shè)計的正確性,可行性。 5.2.1 建立編輯編譯環(huán)境- 創(chuàng)建AT89C52工程,C程序文檔,進行編輯。如下圖 5?1所示:
圖 5?1 創(chuàng)建工程 - 編輯代碼,選擇生成.Hex文件。如下圖 5?2所示:
圖 5?2 生成目標文件 5.2.2 建立仿真和測試環(huán)境根據(jù)電路原理圖在Proteus中搭建仿真模型。分別由數(shù)碼管顯示模塊,復位電路,矩陣鍵盤,晶振電路,單片機主控芯片,步進電機模塊,工作狀態(tài)顯示模塊。如下圖 5?3所示:
圖 5?3 仿真模型 5.3 方案驗證通過仿真來驗證步進電機的控制是否合理。驗證如下: 5.3.1 啟動系統(tǒng)系統(tǒng)默認,步進電機啟動轉(zhuǎn)速為1檔,給定步數(shù)500步;停止狀態(tài),綠燈亮。如下圖 5?4所示:
圖 5?4 啟動系統(tǒng) 5.3.2 選擇工作方式選擇8拍正轉(zhuǎn)工作方式,速度調(diào)為3檔,步數(shù)給定500步,此時正轉(zhuǎn)燈亮。仿真如下圖 5?5所示。 選擇8拍反轉(zhuǎn)工作方式,速度調(diào)為6檔,步數(shù)給定1000步,此時反轉(zhuǎn)燈亮。仿真如下圖 5?6所示。 選擇單4拍正轉(zhuǎn),速度5檔,給定步數(shù)300步,此時正轉(zhuǎn)燈亮。仿真如下圖 5?7所示。 選擇雙4拍反轉(zhuǎn),速度6檔,步數(shù)給定500步,此時反轉(zhuǎn)燈亮。仿真如下圖 5?8所示。
圖 5?5 8拍正轉(zhuǎn)
圖 5?6 8拍反轉(zhuǎn)
圖 5?7 單4拍正轉(zhuǎn)
圖 5?8 雙四拍反轉(zhuǎn) 5.4 問題與分析在本次課題中,我遇到一些問題如下: - 由于我對定時器中斷的功能不是很熟悉,所以在使用定時器中斷調(diào)節(jié)步進電機轉(zhuǎn)速時出現(xiàn)問題,通過翻看單片機手冊,學會了定時器中斷的使用方法,和定時器時間的設(shè)定。
- 在程序的編寫過程中,忽略了鍵盤復位檢測,導致在仿真過程中,進行加減檔,步數(shù)加減時,出現(xiàn)多加,多減的情況。后查閱資料添加了復位檢測后得到了解決。
- 課程設(shè)計中,很多元器件的選用以及電路的設(shè)計都無法很快的完成。我們通過請教老師,以及同學之間的討論,上網(wǎng)查閱資料來對這些問題進行了一一解決。
5.5 創(chuàng)新與擴展本次課程設(shè)計的核心在于利用51單片機作為主控芯片控制步進電機的基本功能,但需要進一步對其功能強化。步進電機可運用于很多場合,可以在系統(tǒng)中添加,WIFI模塊,傳感器模塊,紅外模塊,通過外界環(huán)境變化,經(jīng)過AD轉(zhuǎn)化,改變步進電機工作情況。紅外模塊和WIFI模塊,可以對電機進行無線控制。 5.6 本章小結(jié)本章主要對本次課程設(shè)計做了總結(jié),人員的分工,控制的仿真實現(xiàn),通過在PC機上搭建模擬平臺來實現(xiàn)對步進電機控制的仿真,并記錄了每個步驟的情況。 - #include <reg52.h>
- #include <stdio.h>
-
- #define uchar unsigned char
- #define uint unsigned int
-
- uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; //0~9段選碼
- uchar Way_1[] = {0xfe, 0xfd, 0xfb, 0xf7};//單四拍正轉(zhuǎn)
- uchar Way_2[] = {0xf7, 0xfb, 0xfd, 0xfe};//單四拍反轉(zhuǎn)
- uchar Way_3[] = {0xfc, 0xf9, 0xf3, 0xf6};//雙四拍正轉(zhuǎn)
- uchar Way_4[] = {0xf6, 0xf3, 0xf9, 0xfc};//雙四拍反轉(zhuǎn)
- uchar Way_5[] = {0xfe, 0xfc, 0xfd, 0xf9, 0xfb, 0xf3, 0xf7, 0xf6};//八拍正轉(zhuǎn)
- uchar Way_6[] = {0xf6, 0xf7, 0xf3, 0xfb, 0xf9, 0xfd, 0xfc, 0xfe};//八拍反轉(zhuǎn)
- uchar code time_counter[6][2]={{0xdb,0xff},{0xb7,0xfe},{0x93,0xfe},{0x6f,0xfd},{0x4b,0xfd},{0x27, 0xfb}};
-
-
- uchar KeyValue; //鍵值
- uchar time; //定時器次數(shù)
- uchar way = -1; //工作方式選擇
- uchar run = 0; //默認初始為停止狀態(tài)
- uchar speed = 1;//速度調(diào)節(jié),擋位1
- uint step = 500;//初始步數(shù)
- uchar num[4];
-
- sbit WE1 = P2^0; //數(shù)碼管位選1
- sbit WE2 = P2^1; //數(shù)碼管位選2
- sbit WE3 = P2^2; //數(shù)碼管位選3
- sbit WE4 = P2^3; //數(shù)碼管位選4
- sbit WE5 = P2^4; //數(shù)碼管位選5
- sbit WE6 = P2^5; //數(shù)碼管位選6
-
-
- sbit S = P3^4;//停止
- sbit F = P3^5;//正轉(zhuǎn)
- sbit R = P3^6;//反轉(zhuǎn)
-
-
- void delay(uint z)//延時函數(shù)
- {
- uint x, y;
-
- for(x = z; x > 0; x--)
- {
- for(y = 114; y > 0; y--);
- }
- }
-
-
- void display(uint n, uint m)//顯示函數(shù),n為步數(shù),m為擋位
- {
- num[0] = n%10;//個位
- num[1] = n/10%10; //十位
- num[2] =(n/100)%10; //百位
- num[3] = (n/1000)%10; //千位
-
- P2 = 0xff; //擋位顯示
- WE1 = 0;
- WE2 = 1;
- WE3 = 1;
- WE4 = 1;
- WE5 = 1;
- WE6 = 1;
- P0 = table[m];
- delay(5);
-
- P2 = 0xff; //"-"
- WE1 = 1;
- WE2 = 0;
- WE3 = 1;
- WE4 = 1;
- WE5 = 1;
- WE6 = 1;
- P0 = 0x40;
- delay(5);
-
-
- P2 = 0xff;
- WE1 = 1;
- WE2 = 1;
- WE3 = 0; //步數(shù)千位
- WE4 = 1;
- WE5 = 1;
- WE6 = 1;
- P0 = table[num[3]];
- delay(5);
-
- P2 = 0xff;
- WE1 = 1;
- WE2 = 1;
- WE4 = 0; //步數(shù)百位
- WE3 = 1;
- WE5 = 1;
- WE6 = 1;
- P0 = table[num[2]];
- delay(5);
-
- P2 = 0xff;
- WE1 = 1;
- WE2 = 1;
- WE5 = 0; //步數(shù)十位
- WE4 = 1;
- WE3 = 1;
- WE6 = 1;
- P0 = table[num[1]];
- delay(5);
-
- P2 = 0xff;
- WE1 = 1;
- WE2 = 1;
- WE6 = 0; //步數(shù)個位
- WE4 = 1;
- WE5 = 1;
- WE3 = 1;
- P0 = table[num[0]];
- delay(5);
-
- }
-
-
- void KeyScan()
- {
- KeyValue = 0;
- //列掃描
- P1 = 0xf0;
-
- if(P1 != 0xf0)
- {
- delay(10);//軟件消抖
- if(P1!= 0xf0)
- {
- switch(P1)
- {
- case 0xe0: KeyValue = 1; break;
- case 0xd0: KeyValue = 2; break;
- case 0xb0: KeyValue = 3; break;
- }
-
- P1 = 0x0f;//行掃描
- switch(P1)
- {
- case 0x0e: KeyValue = KeyValue; break;
- case 0x0d: KeyValue = KeyValue+3; break;
- case 0x0b: KeyValue = KeyValue+6; break;
- case 0x07: KeyValue = KeyValue+9; break;
- }
- while(P1 != 0x0f);//松手檢測
- }
-
- }
- return ;
- }
-
-
- void Select(void)//功能選擇
- {
- switch(KeyValue)
- {
- case 1: way = 0;break; //單身拍正轉(zhuǎn)
- case 2: way = 1;break; //單四拍反轉(zhuǎn)
- case 3: way = 2;break; //雙四拍正轉(zhuǎn)
- case 4: way = 3;break; //雙四拍反轉(zhuǎn)
- case 5: way = 4;break; //八拍正轉(zhuǎn)
- case 6: way = 5;break; //八拍反轉(zhuǎn)
- case 7: run = 1;break; //啟動按鈕
- case 8: run = 0;time = 0;break; //停止按鈕
- case 9:
- {
- speed++;
- if(speed > 6)
- {
- speed = 1;
- }
- break; //加速
- }
-
- case 10:
- {
- speed--;
- if(speed == 0)
- {
- speed = 6;
- }
- break;//減速
- }
- case 11:step += 10;break; //步數(shù)加
- case 12:step -= 10;break; //步數(shù)減
- }
- KeyValue = 0;
- }
-
- void Timer_Init()
- {
- EA = 1; //中斷開關(guān)
- ET0 = 1;//打開定時器0中斷
- TR0 = 1;//啟動定時器0
- TMOD = 0x01; //16位計時模式
- TH0 = time_counter[speed-1][0]; //定時
- TL0 = time_counter[speed-1][1];
-
- }
-
-
- void main() //主函數(shù)
- {
- Timer_Init(); //定時器初始化,啟動中斷
- while(1)
- {
- KeyScan(); //鍵盤掃描
- Select(); //功能選擇
- display(step, speed); //步數(shù)顯示
- }
-
- }
-
- void Timer0() interrupt 1
- {
- TH0 = time_counter[speed-1][0]; //定時
- TL0 = time_counter[speed-1][1];
-
- if(run)
- {
- if(step == 0) //判斷步數(shù)走完
- {
- run = 0;
- way = -1;
- }
- switch (way) //選擇通電方式
- {
-
- case 0: //單四拍正轉(zhuǎn)
- {
- step--;//步數(shù)--
- P3 = Way_1[time++];
- F = 0; //正轉(zhuǎn)燈亮
- if(time == 4)
- {
- time = 0;
- }
- break;
- }
- case 1: //單四拍反轉(zhuǎn)
- {
- step--;
- P3 = Way_2[time++];
- R = 0;
- if(time == 4)
- {
- time = 0;
- }
- break;
- }
- case 2: //雙四拍正轉(zhuǎn)
- {
- step--;
- P3 = Way_3[time++];
- F = 0;
- if(time == 4)
- {
- time = 0;
- }
- break;
- }
- case 3: //雙四拍反轉(zhuǎn)
- {
- step--;
- P3 = Way_4[time++];
- R = 0;
- if(time == 4)
- {
- time = 0;
- }
- break;
- }
- case 4: //八拍正轉(zhuǎn)
- {
- step--;
- P3 = Way_5[time++];
- F = 0;
- if(time == 8)
- {
- time = 0;
- }
- break;
- }
- case 5: //八拍反轉(zhuǎn)
- {
- step--;
- P3 = Way_6[time++];
- R = 0;
- if(time == 8)
- {
- time = 0;
- }
- break;
- }
- default: break;
- }
- }
- else
- {
- F = 1; //正轉(zhuǎn)燈滅
- R = 1; //反轉(zhuǎn)燈滅
- S = 0; //停止燈亮
- }
-
- }
復制代碼
|