Keil C 上機(jī)的基本方法_第1頁
Keil C 上機(jī)的基本方法_第2頁
Keil C 上機(jī)的基本方法_第3頁
Keil C 上機(jī)的基本方法_第4頁
Keil C 上機(jī)的基本方法_第5頁
已閱讀5頁,還剩6頁未讀 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

第2章從標(biāo)準(zhǔn)C轉(zhuǎn)向KeilC2.1概述常用的單片機(jī)應(yīng)用系統(tǒng)的軟件編寫語言有匯編、BASIC、C、C++等,對51單片機(jī)而言,使用最為廣泛的還是匯編語言和C語言。有經(jīng)驗的程序員用匯編語言可編寫出高效率的程序,但用匯編語言不便于表達(dá)人們?nèi)粘=鉀Q問題的思路和方法,還有編程工作量大、容易出現(xiàn)Bug(程序中的錯誤)、編寫的程序不容易移植等缺點,故匯編語言一般只用于小型程序的編寫或整個軟件中對執(zhí)行效率要求較高的關(guān)鍵部分。用C語言編寫程序比匯編更符合人們的思維習(xí)慣,開發(fā)者可以更專心考慮算法,對于51單片機(jī)而言,最著名的C語言開發(fā)工具是KellSoftware公司的yVision3集成開發(fā)環(huán)境,一般將其中的C語言稱為C51。C51對ANSI(標(biāo)準(zhǔn))C作了擴(kuò)展,使C51和匯編浯言一樣可直接訪問8051的硬件資源。對絕大多數(shù)51單片機(jī)應(yīng)用系統(tǒng)可只用C語言,不使用匯編就可完成軟件開發(fā)任務(wù);但即使是用C語言編寫程序,也須理解51單片機(jī)的內(nèi)部結(jié)構(gòu),特別是內(nèi)存、中斷、串行通信口等資源的使用方法,否則很難實現(xiàn)一個實際的應(yīng)用系統(tǒng)。C51是專門為51系列單片機(jī)設(shè)計的,根據(jù)51單片機(jī)自身的特點進(jìn)行了若干擴(kuò)展,與ANSIC在語法和庫函數(shù)方面存在稍許差別,但絕大部分是兼容的。卩Vision3集成開發(fā)環(huán)境(IDE)包括項目(Project)管理器、程序編輯器、Cx51編譯器、Ax5l宏匯編器、BL51/Lx5l連接定位器、RTX51實時操作系統(tǒng)、Simulator軟件模擬器以及Monitor51硬件目標(biāo)調(diào)試器,所有這些功能均可在卩Vision3提供的單一而靈活的開發(fā)環(huán)境中極為簡便地進(jìn)行操作。卩Vision3提供了強(qiáng)大的項目管理功能,可以十分方便地進(jìn)行結(jié)構(gòu)化多模塊程序設(shè)計。開發(fā)一個單片機(jī)系統(tǒng)的一般步驟如下:設(shè)計并制作好硬件電路板(目標(biāo)板)。根據(jù)目標(biāo)板各功能模塊,用KeilC或其他開發(fā)工具編寫目標(biāo)板功能模塊測試程序。拔下目標(biāo)板上的CPU,將仿真器的仿真頭插人目標(biāo)電路板的CPU插座,并將仿真器與PC的通信電纜(一般用串口)連接好,然后給目標(biāo)電路板和仿真器加電,這樣仿真器內(nèi)的CPU就可代替(模擬)目標(biāo)電路板的CPU。在PC上運行仿真器配套的測試軟件,編寫或打開第②步得到的模塊測試程序,運行并調(diào)試程序。程序調(diào)試的方法與TC、VC等環(huán)境下程序調(diào)試的方法相似,如目標(biāo)板不能實現(xiàn)所需功能,應(yīng)檢查井更正目標(biāo)板軟、硬件設(shè)計中的錯誤,然開重復(fù)①?④步,直至目標(biāo)板各功能模塊測試正確為止。目標(biāo)板硬件功能通過測試后,編寫單片機(jī)應(yīng)用系統(tǒng)的軟件,采用與③④步相似的方法,測試單片機(jī)系統(tǒng)軟硬件的正確性,直至系統(tǒng)軟硬件功能正確。將開發(fā)工具生成的可執(zhí)行文件固化到芯片中。軟硬件調(diào)試正確后,用KeilC或其他開發(fā)工具生成可執(zhí)行文件。如程序在目標(biāo)板CPU片內(nèi)運行,則用編程器將生成的可執(zhí)行文件寫入CUP中;如程序在片外運行,則將可執(zhí)行文件寫入ROM芯片中。目標(biāo)板斷電,拔下仿真頭,將寫入程序后的CPU及ROM芯片插入目標(biāo)扳后加電,驗證目標(biāo)板是否實現(xiàn)了所需功能;如不正確.則應(yīng)重復(fù)①一⑦步,直至正確。許多廠商都能生產(chǎn)符合KeilC公司Mon51標(biāo)準(zhǔn)、能在KeilC集成開發(fā)環(huán)境中使用的Mon51仿真器,如廣州周立功公司的TKS系列仿真器。當(dāng)采用KellC配合Mon51仿真器作為開發(fā)工具時,KeilC既是軟件編與工具,也是程序調(diào)試工具,可避免在各種開發(fā)工具間反復(fù)切換,方便軟件開發(fā)。隨著軟件技術(shù)的發(fā)展,在實際的開發(fā)過程中,程序調(diào)試的絕大多數(shù)工作可不依賴硬仿真器,也不必非等到目標(biāo)板完成制作后才開始軟件測試。與目標(biāo)板外圍電路無關(guān)的部分,可利用KeilC的8051軟仿真器來完成程序稠試;與目標(biāo)板相關(guān)的部分,可利用Protues軟件與KeilC聯(lián)合仿真的方法進(jìn)行軟件調(diào)試。單片機(jī)應(yīng)用要求較多的綜合知識,與電子技術(shù)、自動控制技術(shù)、通信技術(shù)等知識緊密相關(guān),建議有條件的讀者實際上手完成書中介紹的PID溫度控制器,以真正完成知識綜合、理論到實踐的學(xué)習(xí)過程。2.2C51程序的一般結(jié)構(gòu)與標(biāo)準(zhǔn)C語言相同,C51程序由一個或多個函數(shù)構(gòu)成,其中至少包含一個主函數(shù)main。程序執(zhí)行時一定是從主函數(shù)開始,調(diào)用其它函數(shù)后又返回主函數(shù);被調(diào)函數(shù)如果位于主調(diào)函數(shù)前面,可以直接調(diào)用,否則要先聲明后調(diào)用。這里函數(shù)與匯編語言中的子程序類似,函數(shù)之間也可以互相調(diào)用。C51程序的一般結(jié)構(gòu)如下:預(yù)處理命令 /*用于包含頭文件等*/全局變量定義 /*全局變量可以被本程序的所有函數(shù)引用*/函數(shù)1聲明函數(shù)n聲明/*主函數(shù)*/Main(){局部變量定義;/*局部變量只能在所定義的函數(shù)內(nèi)部引用*/執(zhí)行語句;函數(shù)調(diào)用(形式參數(shù)表);}/*其它函數(shù)定義*/函數(shù)1(形式參數(shù)){局部變量定義;/*局部變量只能在所定義的函數(shù)內(nèi)部引用*/執(zhí)行語句;函數(shù)調(diào)用(形式參數(shù)表)}函數(shù)n(形式參數(shù)){局部變量定義;/*局部變量只能在所定義的函數(shù)內(nèi)部引用*/執(zhí)行語句;函數(shù)調(diào)用(形式參數(shù)表);}2.3KeilC上機(jī)的基本方法一、pVision3中編程的基本步驟采用KeilC開發(fā)8051單片機(jī)應(yīng)用程序一般需要以下步驟:1) 在pVision3集成開發(fā)環(huán)境中創(chuàng)建一個新項目(Project),并為該項目選定合適的單片機(jī)型號。2) 利用pVision3的文件編輯器編寫C語言(或匯編語言)源程序文件,并將文件添

加到項目中去。一個項目可以包含多個文件,除源程序文件外還可以有庫文件或文本說明文件。通過pVision3的各種選項,配置Cx51編譯器、Ax51宏匯編器、BL51/Lx51連接定位器以及Debug調(diào)試器的功能。利用pVision3的構(gòu)造(Build)功能對項目中的程序文件進(jìn)行編譯鏈接,生成絕對目標(biāo)代碼和可選的HEX格式的可執(zhí)行文件,如果出現(xiàn)編譯鏈接錯誤則返回第2)步,修改源程序中的錯誤后重新構(gòu)造整個項目。將沒有錯誤的絕對目標(biāo)代碼裝入pVision3調(diào)試器進(jìn)行仿真調(diào)試,調(diào)試成功后用編程器將可執(zhí)行文件寫入到單片機(jī)應(yīng)用系統(tǒng)的程序存儲器或單片機(jī)內(nèi)部的FlashROM中。二、pVision3上機(jī)實例下面,我們以實例來介紹在pVision3集成開發(fā)環(huán)境中,如何創(chuàng)建一個應(yīng)用程序。/*【例2.1】從鍵盤輸入兩個數(shù),在屏幕上輸出較大者。其源程序?qū)懺趍ax.c文件中。*/max.c源程序如下:#include"reg51.h"#include"stdio.h"voidserial_initial(void){SCON=0x50;TMOD=0x20;TH1=0xf3;TR1=1;TI=1;voidserial_initial(void){SCON=0x50;TMOD=0x20;TH1=0xf3;TR1=1;TI=1;/*串口工作方式1、允許接收*//*定時器/計數(shù)器1工作于方式2,8位自動重裝載*//*f=12MHzSMOD=0波特率=2400的重裝載值*//*啟動定時器1*//*TI置位以便發(fā)送通用異步收發(fā)器的第一個字符*/}intmax(intx,inty){intz;if(x>y)z=x;elsez=y;return(z);}main(){inta,b,c;serial_initial();printf("PleaseInputa,b:\n");scanf("%d,%d",&a,&b);c=max(a,b);printf("max=%d\n",c);while(1); /*死循環(huán),防止CPU取到非法指令*/}在上例的結(jié)尾,有一條死循環(huán)語句:while(1),為什么要加這條死循環(huán)語句?在程序執(zhí)行時,CPU會根據(jù)當(dāng)前指令的長度自動修改指令指針寄存器(PC)的值,以使PC指向下一條指令。如果應(yīng)用程序只占用程序存儲區(qū)的一部分,則程序存儲器中除應(yīng)用程序外的其它部分是無意義的內(nèi)容。若上例的最后沒有while(1)這條死循環(huán)語句,則程序執(zhí)行完printf(“max=%d\n”,c)函數(shù)調(diào)用后,PC就會指向沒有用戶程序的存儲區(qū),從而取到非法指令而導(dǎo)致錯誤。為防止這種錯誤,C51應(yīng)用程序的main函數(shù)常用如下結(jié)構(gòu):voidmain(){?//初始化部分while(1){?//其他代碼}}在PC機(jī)上編寫的C程序由于有Windows等操作系統(tǒng)的支持,不必采用這種結(jié)構(gòu)。上機(jī)的具體步驟:(1)啟動KeiluVision3雙擊桌面上的KeiluVision3圖標(biāo)或者單擊屏幕左下方的“開始”,在彈出的對話框中選擇“程序”;再在彈出的程序?qū)υ捒蛑?,單擊KeiluVision3選項,則進(jìn)入KeiluVision3集成開發(fā)環(huán)境。(2)建立項目文件選擇ProjectINewProject菜單項,則彈出CreateNewProject界面,單擊其中的“保存在”下拉按鈕,選擇“E盤”,再單擊創(chuàng)建新文件夾按鈕,給文件夾起名為“MyProject”然后雙擊MyProject文件夾進(jìn)入。在“文件名”文字框輸入程序項目名稱,這里輸入“Myexample”,保存后的文件名擴(kuò)展名為uv2,以后可以雙擊此文件打開該項目。在uVision3中,一個項目是由包括項目文件(.uv2文件)、源程序等在內(nèi)的很多文件組成,為例便于管理,通常為每個項目建一個文件夾,本例建立了項目文件夾MyProject。(3) 選擇CPU器件項目文件夾保存完畢后將彈出SelectDeviceforTargit?Targit1'界面,用于為新建項目選擇一種CPU器件,本例選Atmel公司的AT89C51,選定后“Vision3將按所選器件自動設(shè)置默認(rèn)的工具選項,從而簡化了項目的配置過程。窗口的Description列表框?qū)λx的CPU的I/O線,內(nèi)部RAM、FLASHROM容量等主要性能作了簡要描述。(4) 加入KeilC提供的啟動文件STARTUP.A51完成CPU器件選擇后,點擊OK,則彈出是否增加啟動文件到本項目界面,此處可以選擇“是”。STARTUP.A51是用匯編語言編寫的源文件,一般用戶無須修改;高級用戶可修改其中的內(nèi)容,以定制堆棧管理、動態(tài)存儲分配等相關(guān)設(shè)置。創(chuàng)建一個新項目后,在項目管理窗口(ProjectWorkspace)中自動生成一個默認(rèn)的目標(biāo)(Targit1)和文件組(SouceGroup1)。在項目管理窗口的底部,有5個選項卡:“文件(File)選項卡、用于在項目中快速定位、添加、移除文件;“寄存器(Regs)”選項卡,用于程序仿真運行時顯示寄存器的值;“書籍(Book)”選項卡,用于打開幫助文件;“函數(shù)(Functions)”選項卡,用于在項目中快速定位已定義的函數(shù);“模板(Templates)”選項卡,對C語言不太熟悉的初學(xué)者可利用該選項卡提供的功能快速輸入C語言的各種語句,減少源程序的語法錯誤。(5)編輯源程序文件選擇FileNew菜單項,從打開的編輯界面中輸入前面列出的max.c。注意:輸入源程序可采取先保存文件(以文件名max.c保存),然后再輸入的方法。同學(xué)自可體會其中的優(yōu)點。(6)將源程序加入到項目中源程序文件可以是已有的,也可以是新建的。|JVision3具有十分完善的右鍵功能,選擇項目管理窗口File選項卡,在其中的SourceGroup1上面右擊,則彈出一個快捷菜單,選擇快捷菜單中的AddFilestoGroup‘SourceGroup1'選項,彈出AddFilestoGroup‘SourceGroup1'源文件選擇頁面,選擇剛才保存的源程序文件max.c,單擊Add按鈕,將其添加到新創(chuàng)建項目中去,然后單擊Close按鈕關(guān)閉此頁面。設(shè)置項目配置選項右擊項目管理窗口中Targit1節(jié)點,在彈出的快捷菜單中選擇OptionsforTargit'Targit1'選項,則彈出OptionsforTargit‘Targit1'項目配置界面。這是一個十分重要的窗口,包括Device、Targit、Output、Listing、C51、A51、BL51Locate、BL51Misc、Debug和Utilities選項卡,每個選項卡均可根據(jù)項目需要作必要的調(diào)整。本例全部使用默認(rèn)值,不做任何修改。生成可執(zhí)行文件完成項目配置iang的基本設(shè)定之后,就可以對當(dāng)前新建項目進(jìn)行整體創(chuàng)建(BuildTargit)。單擊項目管理窗口上方工具欄中的Build圖標(biāo)按鈕或選擇ProjectIBuildTargit菜單項單擊。pVision3將按照所設(shè)定的項目選項,自動完成當(dāng)前項目中所有源程序模塊文件的編譯鏈接,并在|JVision3下面的輸出窗口(OutputWindow)中顯示編譯鏈接提示信息。如果有錯誤,則雙擊輸出窗口內(nèi)的提示信息,光標(biāo)將自動跳到源程序文件的錯誤位置,以便修改;如果沒有編譯錯誤,則生成絕對目標(biāo)代碼文件(可執(zhí)行文件)。仿真運行程序編譯鏈接完成后,選擇Debug|Start/StopDebugsession菜單項或者單擊工具欄上的圖標(biāo)按鈕,彈出新的窗口。在此狀態(tài)下,項目管理窗口自動轉(zhuǎn)到Regs選項卡,顯示調(diào)試過程中單片機(jī)內(nèi)部的工作寄存器R0?R7、累加器A、堆棧指針SP、數(shù)據(jù)指針DPTR、程序計數(shù)器PC以及程序狀態(tài)字PSW燈特殊功能寄存器的值。在仿真調(diào)試狀態(tài)下,單擊Run圖標(biāo)按鈕或者選擇Debug|Run菜單項,啟動用戶程序全速運行,再選擇View|SerialWindow#1菜單項或者單擊工具欄上SerialWindow#1圖標(biāo)按鈕,打開調(diào)試狀態(tài)下pVision3的串行窗口1。用戶程序中采用scanf()和printf()所進(jìn)行的輸入輸出操作,都是通過穿新窗口1實現(xiàn)的。單擊串行窗口1,將輸入法切換到英文輸入狀態(tài),輸入數(shù)字“5,10”后回車,立即得到輸出結(jié)果“max=10”。至此,我們完成了建立一個pVision3項目的全過程。通過以上的具體步驟,希望讀者能對pVision3軟件在宏觀上有一個感性認(rèn)識,并對所講的操作方法舉一反三。在熟悉本例所述上機(jī)過程后,讀者應(yīng)仔細(xì)閱讀下面的上機(jī)注意事項,以便更好地使用pVision3開發(fā)工具。三、 pVision3上機(jī)注意事項為方便程序調(diào)試,KeilC也提供了scanf和printf這兩個函數(shù),這兩個庫函數(shù)使用8051的串行通信口收發(fā)數(shù)據(jù)。Printf函數(shù)通過8051串口將數(shù)據(jù)送到“串行窗口”(一個Windows標(biāo)準(zhǔn)窗口)并顯示出來,scanf函數(shù)從8051串口讀入自“串行窗口”中輸入的數(shù)據(jù)。為使這兩個函數(shù)正確執(zhí)行,應(yīng)如上例中的serial_initial函數(shù)一樣,設(shè)置好串行口的接收允許。每進(jìn)行一次Build,pVision3都會根據(jù)項目選項重新編譯生成可執(zhí)行文件。BuildTarget命令只編譯修改過的或新加進(jìn)來的文件,然后生成可執(zhí)行文件。Rebuildalltargetfiles命令重新編譯項目中的所有文件,而不論是否修改過,然后再生成可執(zhí)行文件。Translatecurrentfile命令只編譯當(dāng)前源程序編輯窗口中的源程序文件,但并不鏈接生成可執(zhí)行文件。KeilC生成的默認(rèn)可執(zhí)行文件無擴(kuò)展名,以項目名作為可執(zhí)行文件名稱,其名稱可以修改。多數(shù)編譯器都支持Intel的Hex目標(biāo)文件格式。如在OptionsforTarget對話窗口的Output選項卡中選擇CreateHexFile選項,則在Build項目時同時生成默認(rèn)的可執(zhí)行文件和Hex格式的可執(zhí)行文件。在項目管理窗口中右擊某個文件,從彈出的快捷菜單中選擇RemoveFile,可從項目中移除該文件;此時項目將不再引用該文件,但并不從硬盤上刪除該文件。原版的KeilC編譯器會忽略編碼為OxFD的字符,當(dāng)編寫中文顯示程序時會出現(xiàn)問題,應(yīng)安裝針對這一問題的專用補(bǔ)丁。四、 KeilC軟仿真器及程序調(diào)試方法1.調(diào)試相關(guān)工具介紹名稱圖標(biāo)按鈕功能Start/StopDebugSession開始/停止調(diào)試時間ProjectWorkspace顯示/隱藏項目管理窗口OutputWindow顯示/隱藏輸出窗口Inset/RemoveBreakpoint插入/取消斷點KillAllBreakpoint清除所有斷點Enable/Disnablebreakpoint使能/禁止某一斷點DisableAllBreakpoint禁止所有斷點,但不清除斷點ResetCPU重新從頭開始運行程序Run運行程序,執(zhí)行到斷點處程序暫停執(zhí)行Halt暫停程序執(zhí)行StepInto進(jìn)入被調(diào)函數(shù)StepOver執(zhí)行一條語句StepOut從被調(diào)函數(shù)返回RuntoCursorLine執(zhí)行到源程序編輯窗口當(dāng)前光標(biāo)處暫停WatchandCallStackWindow顯示/關(guān)閉監(jiān)視和調(diào)用堆棧窗口2.斷點設(shè)置及應(yīng)用實例下面結(jié)合max.c來說明斷點設(shè)置及跟蹤程序執(zhí)行過程的基本方法。如果想在main()函數(shù)中觀察變量c的值,則操作步驟如下:在源程序編輯窗口將光標(biāo)移到“printf(“max=%d\n”,c);”代碼行。單擊工具欄上的“插入/取消斷點”圖標(biāo),在該代碼行添加一個斷點。單擊Start/StopDebugSession按鈕,進(jìn)入調(diào)試狀態(tài),程序執(zhí)行到main()函數(shù)時暫停。單擊run按鈕繼續(xù)執(zhí)行程序,此時打開SerialWindow#1,在其中輸入兩個值“5,6”并回車,程序執(zhí)行到第2)步所設(shè)的斷點行暫停。單擊WatchandCallStackWindow按鈕,在界面右下角出現(xiàn)監(jiān)視和調(diào)用堆棧窗口。在此窗口可以兩種方法觀察變量a,b,c的值:方法1:在Locals選項卡中可直接查看各局部變量的值。方法2:在Watch#1或Watch#2選項卡中,單擊有提示說明的一行后按F2鍵,輸入變量名a并回車,則可顯示變量a的值。順便說明,CallStack選項卡用于顯示函數(shù)間的調(diào)用關(guān)系。此外,還有一種觀察變量值的方法:在源程序編輯窗口中用鼠標(biāo)指向變量c并稍停片刻,在光標(biāo)下方的淺黃色小窗口中將顯示變量c所在的存儲空間、十六進(jìn)制地址、十六進(jìn)制值。五、 C51中的變量和函數(shù)數(shù)據(jù)類型存儲類型字節(jié)順序

存儲模式選擇絕對地址訪問和I/O端口讀/寫指針C51函數(shù)/*【Li2.2】檢測BDATA存儲類型變量bit_status的第三位是否為1,如果是1,則將temp變量加1*/#include"stdio.h"#include"Reg51.h"/*定義一個可位尋址變量,其第3位為零*/unsignedcharbdatabit_status=0x43; /*0x43寫成二進(jìn)制位01000011*//*針對bit_status變量的第3位聲明一個位變量*/sbitstatus_3=bit_statusA3;voidmain(void){unsignedchartemp=0;SCON=0x12; /*允許向串口發(fā)送數(shù)據(jù);printf函數(shù)需向串口發(fā)送數(shù)據(jù)*/if((bit)(status_3)){

temp++;/*=if(status_3)*/if((bit)(status_3)){

temp++;/*由于bit_status的第3位是0,temp不會加1*/if(bit_statusA3){ /*錯誤代碼*/temp++;}if(bit_status&0x04){/*如果第3位置位temp再加1*/temp++;}printf("temp=%bd\n",temp);while(1);}/*上例運行后,在KeilC的串行窗口顯示的temp的值是1,而不是0!原因在于第12行錯誤代碼所致*//*【例2.3】在代碼段中定義及訪問只讀數(shù)據(jù)的實例*/#include"reg51.h"#include"stdio.h"/*下面的chs字符數(shù)組的最后一個元素的值初始化為0,C語言*/unsignedcharcodechs[]={'H','e','l','l','o','!',0x00};voidmain(){unsignedchardatai;SCON=0x12;printf("%s\n",chs);/*用for循環(huán)顯示Hello!*/for(i=0;chs[i]!=0;i++)printf("%c",chs[i]);printf("\n");/*換行*/while(1);}/*【例2.3_1】在代碼段中定義及訪問只讀數(shù)據(jù)的實例(modified)*/#include"reg51.h"#include"stdio.h"unsignedcharcodechs[]="HelloWorld!";voidmain(){unsignedchardatai;SCON=0x12;printf("%s\n",chs);/*用for循環(huán)顯示HelloWorld!*/for(i=0;chs[i]!=0;i++)printf("%c",chs[i]);printf("\n");while(1);}/*【例2.4】通用指針與特定指針執(zhí)行效率的比較*/#include<absacc.h>char*generic_ptr;/*字符型通用指針*/chardata*xd_ptr;/*指向data空間的字符型指針*/chardatamystring[]="Testoutput";main(){generic_ptr=mystring;while(*generic_ptr){ /*此行設(shè)置斷點,運行到此處時,機(jī)器周期數(shù)為586*/XBYTE[0x0000]=*generic_ptr;generic_ptr++;}xd_ptr=mystring; /*此行設(shè)置斷點,運行到此處時,機(jī)器周期數(shù)為922*/while(*xd_ptr){ /*此行設(shè)置斷點,運行到此處時,機(jī)器周期數(shù)為924*/XBYTE[0x0000]=*xd_ptr;xd_ptr++;}while(1); /*此行設(shè)置斷點,運行到此處時,機(jī)器周期數(shù)為1073*/仿真運行上例時,單擊Start/StopDebugSession按鈕運行程序,在源程序編輯窗口將光標(biāo)定位到第1個斷點行,再單擊Stepinto按鈕,使程序運行到光標(biāo)位置后暫停執(zhí)行。此時在ProjectWorkspace中Regs選項卡上的statues和sec兩項,分別代表程序已運行的機(jī)器周期數(shù)和秒數(shù),分別為586個機(jī)器周期和0.00058600s。按本例源程序注釋設(shè)置好斷點,重新運行程序,運行到各斷點行程序暫停執(zhí)行時,觀察ProjectWorkspace中Regs選項卡上的states項,可得到執(zhí)行到各斷點語句時的機(jī)器周期數(shù)(源程序注釋中已記錄),用此方法可知執(zhí)行完使用通用指針的第一個循環(huán)需要922-586=336個機(jī)器周期,使用特定指向指針的后一個循環(huán)之需要1073-924=149個機(jī)器周期,可見特定指向指針的效率遠(yuǎn)高于通用指針。在實時性要求較高時,對代碼的執(zhí)行效率有要求,可用本例介紹的方法獲取某段代碼的執(zhí)行時間,以判斷其是否滿足系統(tǒng)性能要求。C51函數(shù)語法與標(biāo)準(zhǔn)C函數(shù)基本相同,但針對51單片機(jī)的特點作了擴(kuò)展,定義C51函數(shù)的語法格式如下:<return_type>funcname(<args>)<small|compact|large><reentrant><interruptx><usingy>/*【例2.5】遞歸調(diào)用不可重入函數(shù)錯誤計算5的階乘(factorial)*/#include"stdio.h"#include"Reg51.h"/*不可重入函數(shù)fact遞歸調(diào)用來計算N的階乘*/unsignedintfact(unsignedcharN){if(N==0)return1;if(N>1)returnN*fact(N-1);}voidmain(){SCON=0x12;printf("5!=%u\n",fact(5));while(1);}/*函數(shù)的重入是指函數(shù)上次運行未結(jié)束,又被再次調(diào)用的情形*//*若定義某函數(shù)時不特別指明,C51中就把該函數(shù)作為不可重入函數(shù)看待*/上面的程序執(zhí)行后,計算出的5的階乘為1,而不是120,就是因為遞歸調(diào)用了不可重入函數(shù)fact()而導(dǎo)致了錯誤的結(jié)果。C51允許使用reentrant屬性將函數(shù)定義成可重入函數(shù),而不用擔(dān)心變量被覆蓋,但要修改Startup.A51相關(guān)內(nèi)容。/*【例2.6】遞歸調(diào)用可重入函數(shù)正確計算5的階乘*//*注意:編譯前須修改Startup.A51啟動文件*/#include"stdio.h"#include"Reg51.h"/*遞歸調(diào)用可重入函數(shù)fact計算N的階乘*/unsignedintfact(unsignedcharN)reentrant{if(N==0)return1;if(N>1)returnN*fact(N-1);}voidmain(){SCON=0x12;printf("5!=%u\n",fact(5));

while(1);}項目用Small存儲模式,下面是Startup.A51需修改部分的原始內(nèi)容及修改后的內(nèi)容。原始內(nèi)容:IBPSTACKEQU0;setto1ifsmallreentrantisused.IBPSTACKTOPEQU 0xFF+1;default0FFH+1參考以上兩行后面的注釋,改為:IBPSTACKEQU1IBPSTACKTOPEQU 0x7F+1注意:標(biāo)準(zhǔn)8051內(nèi)部RAM7FH+1(80H)以上部分為特殊功能寄存器,但由于模擬棧是向下生長的,因此不會進(jìn)入特殊功能寄存器區(qū)。六、KeilC中的51單片機(jī)中斷編程/*【例2.7】8051晶振頻率fosc為12MHz,用定時器0的溢出中斷實現(xiàn)每隔50ms在“SerialWindow#1”上顯示一行字符串“HelloWorld!"。*/#include<reg51.h>#include<stdio.h>#defineRELOADVALH0x3c#defineRELOADVALL0xb0voidmain(){IE=0;TR0=0;SCON=0x12;TMOD=0x01;TH0=RELOADVALH;TL0=RELOADVALL;IE=0x82;TR0=1;while(1);}voidtimer0_int(void)interrupt1{ET0=0;TR0=0;TH0=RELOADVALH;TL0=RELOADVALL;TR0=1;printf("HelloWorld!\n");ET0=1;/*定時器初值高/*定時器初值高8位*//*定時器初值低8位*//*關(guān)閉所有中斷*//*停止定時器0*//*允許向串口發(fā)送數(shù)據(jù)*//*定時器0工作在方式1,16位定時器*//*裝定時器初值,50ms后溢出*//*只開定時器0的中斷,其余中斷禁止*//*啟動定時器0*//*關(guān)定時器0中斷*//*停止定時器0*//*啟動定時器0*/注:定時時間=(65535-初值)X機(jī)器周期,而機(jī)器周期=12/12000000=

溫馨提示

  • 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. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論