版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第2章從標(biāo)準(zhǔn)C轉(zhuǎn)向KeilC2.1概述常用的單片機(jī)應(yīng)用系統(tǒng)的軟件編寫(xiě)語(yǔ)言有匯編、BASIC、C、C++等,對(duì)51單片機(jī)而言,使用最為廣泛的還是匯編語(yǔ)言和C語(yǔ)言。有經(jīng)驗(yàn)的程序員用匯編語(yǔ)言可編寫(xiě)出高效率的程序,但用匯編語(yǔ)言不便于表達(dá)人們?nèi)粘=鉀Q問(wèn)題的思路和方法,還有編程工作量大、容易出現(xiàn)Bug(程序中的錯(cuò)誤)、編寫(xiě)的程序不容易移植等缺點(diǎn),故匯編語(yǔ)言一般只用于小型程序的編寫(xiě)或整個(gè)軟件中對(duì)執(zhí)行效率要求較高的關(guān)鍵部分。用C語(yǔ)言編寫(xiě)程序比匯編更符合人們的思維習(xí)慣,開(kāi)發(fā)者可以更專心考慮算法,對(duì)于51單片機(jī)而言,最著名的C語(yǔ)言開(kāi)發(fā)工具是KellSoftware公司的yVision3集成開(kāi)發(fā)環(huán)境,一般將其中的C語(yǔ)言稱為C51。C51對(duì)ANSI(標(biāo)準(zhǔn))C作了擴(kuò)展,使C51和匯編浯言一樣可直接訪問(wèn)8051的硬件資源。對(duì)絕大多數(shù)51單片機(jī)應(yīng)用系統(tǒng)可只用C語(yǔ)言,不使用匯編就可完成軟件開(kāi)發(fā)任務(wù);但即使是用C語(yǔ)言編寫(xiě)程序,也須理解51單片機(jī)的內(nèi)部結(jié)構(gòu),特別是內(nèi)存、中斷、串行通信口等資源的使用方法,否則很難實(shí)現(xiàn)一個(gè)實(shí)際的應(yīng)用系統(tǒng)。C51是專門為51系列單片機(jī)設(shè)計(jì)的,根據(jù)51單片機(jī)自身的特點(diǎn)進(jìn)行了若干擴(kuò)展,與ANSIC在語(yǔ)法和庫(kù)函數(shù)方面存在稍許差別,但絕大部分是兼容的。卩Vision3集成開(kāi)發(fā)環(huán)境(IDE)包括項(xiàng)目(Project)管理器、程序編輯器、Cx51編譯器、Ax5l宏匯編器、BL51/Lx5l連接定位器、RTX51實(shí)時(shí)操作系統(tǒng)、Simulator軟件模擬器以及Monitor51硬件目標(biāo)調(diào)試器,所有這些功能均可在卩Vision3提供的單一而靈活的開(kāi)發(fā)環(huán)境中極為簡(jiǎn)便地進(jìn)行操作。卩Vision3提供了強(qiáng)大的項(xiàng)目管理功能,可以十分方便地進(jìn)行結(jié)構(gòu)化多模塊程序設(shè)計(jì)。開(kāi)發(fā)一個(gè)單片機(jī)系統(tǒng)的一般步驟如下:設(shè)計(jì)并制作好硬件電路板(目標(biāo)板)。根據(jù)目標(biāo)板各功能模塊,用KeilC或其他開(kāi)發(fā)工具編寫(xiě)目標(biāo)板功能模塊測(cè)試程序。拔下目標(biāo)板上的CPU,將仿真器的仿真頭插人目標(biāo)電路板的CPU插座,并將仿真器與PC的通信電纜(一般用串口)連接好,然后給目標(biāo)電路板和仿真器加電,這樣仿真器內(nèi)的CPU就可代替(模擬)目標(biāo)電路板的CPU。在PC上運(yùn)行仿真器配套的測(cè)試軟件,編寫(xiě)或打開(kāi)第②步得到的模塊測(cè)試程序,運(yùn)行并調(diào)試程序。程序調(diào)試的方法與TC、VC等環(huán)境下程序調(diào)試的方法相似,如目標(biāo)板不能實(shí)現(xiàn)所需功能,應(yīng)檢查井更正目標(biāo)板軟、硬件設(shè)計(jì)中的錯(cuò)誤,然開(kāi)重復(fù)①?④步,直至目標(biāo)板各功能模塊測(cè)試正確為止。目標(biāo)板硬件功能通過(guò)測(cè)試后,編寫(xiě)單片機(jī)應(yīng)用系統(tǒng)的軟件,采用與③④步相似的方法,測(cè)試單片機(jī)系統(tǒng)軟硬件的正確性,直至系統(tǒng)軟硬件功能正確。將開(kāi)發(fā)工具生成的可執(zhí)行文件固化到芯片中。軟硬件調(diào)試正確后,用KeilC或其他開(kāi)發(fā)工具生成可執(zhí)行文件。如程序在目標(biāo)板CPU片內(nèi)運(yùn)行,則用編程器將生成的可執(zhí)行文件寫(xiě)入CUP中;如程序在片外運(yùn)行,則將可執(zhí)行文件寫(xiě)入ROM芯片中。目標(biāo)板斷電,拔下仿真頭,將寫(xiě)入程序后的CPU及ROM芯片插入目標(biāo)扳后加電,驗(yàn)證目標(biāo)板是否實(shí)現(xiàn)了所需功能;如不正確.則應(yīng)重復(fù)①一⑦步,直至正確。許多廠商都能生產(chǎn)符合KeilC公司Mon51標(biāo)準(zhǔn)、能在KeilC集成開(kāi)發(fā)環(huán)境中使用的Mon51仿真器,如廣州周立功公司的TKS系列仿真器。當(dāng)采用KellC配合Mon51仿真器作為開(kāi)發(fā)工具時(shí),KeilC既是軟件編與工具,也是程序調(diào)試工具,可避免在各種開(kāi)發(fā)工具間反復(fù)切換,方便軟件開(kāi)發(fā)。隨著軟件技術(shù)的發(fā)展,在實(shí)際的開(kāi)發(fā)過(guò)程中,程序調(diào)試的絕大多數(shù)工作可不依賴硬仿真器,也不必非等到目標(biāo)板完成制作后才開(kāi)始軟件測(cè)試。與目標(biāo)板外圍電路無(wú)關(guān)的部分,可利用KeilC的8051軟仿真器來(lái)完成程序稠試;與目標(biāo)板相關(guān)的部分,可利用Protues軟件與KeilC聯(lián)合仿真的方法進(jìn)行軟件調(diào)試。單片機(jī)應(yīng)用要求較多的綜合知識(shí),與電子技術(shù)、自動(dòng)控制技術(shù)、通信技術(shù)等知識(shí)緊密相關(guān),建議有條件的讀者實(shí)際上手完成書(shū)中介紹的PID溫度控制器,以真正完成知識(shí)綜合、理論到實(shí)踐的學(xué)習(xí)過(guò)程。2.2C51程序的一般結(jié)構(gòu)與標(biāo)準(zhǔn)C語(yǔ)言相同,C51程序由一個(gè)或多個(gè)函數(shù)構(gòu)成,其中至少包含一個(gè)主函數(shù)main。程序執(zhí)行時(shí)一定是從主函數(shù)開(kāi)始,調(diào)用其它函數(shù)后又返回主函數(shù);被調(diào)函數(shù)如果位于主調(diào)函數(shù)前面,可以直接調(diào)用,否則要先聲明后調(diào)用。這里函數(shù)與匯編語(yǔ)言中的子程序類似,函數(shù)之間也可以互相調(diào)用。C51程序的一般結(jié)構(gòu)如下:預(yù)處理命令 /*用于包含頭文件等*/全局變量定義 /*全局變量可以被本程序的所有函數(shù)引用*/函數(shù)1聲明函數(shù)n聲明/*主函數(shù)*/Main(){局部變量定義;/*局部變量只能在所定義的函數(shù)內(nèi)部引用*/執(zhí)行語(yǔ)句;函數(shù)調(diào)用(形式參數(shù)表);}/*其它函數(shù)定義*/函數(shù)1(形式參數(shù)){局部變量定義;/*局部變量只能在所定義的函數(shù)內(nèi)部引用*/執(zhí)行語(yǔ)句;函數(shù)調(diào)用(形式參數(shù)表)}函數(shù)n(形式參數(shù)){局部變量定義;/*局部變量只能在所定義的函數(shù)內(nèi)部引用*/執(zhí)行語(yǔ)句;函數(shù)調(diào)用(形式參數(shù)表);}2.3KeilC上機(jī)的基本方法一、pVision3中編程的基本步驟采用KeilC開(kāi)發(fā)8051單片機(jī)應(yīng)用程序一般需要以下步驟:1) 在pVision3集成開(kāi)發(fā)環(huán)境中創(chuàng)建一個(gè)新項(xiàng)目(Project),并為該項(xiàng)目選定合適的單片機(jī)型號(hào)。2) 利用pVision3的文件編輯器編寫(xiě)C語(yǔ)言(或匯編語(yǔ)言)源程序文件,并將文件添
加到項(xiàng)目中去。一個(gè)項(xiàng)目可以包含多個(gè)文件,除源程序文件外還可以有庫(kù)文件或文本說(shuō)明文件。通過(guò)pVision3的各種選項(xiàng),配置Cx51編譯器、Ax51宏匯編器、BL51/Lx51連接定位器以及Debug調(diào)試器的功能。利用pVision3的構(gòu)造(Build)功能對(duì)項(xiàng)目中的程序文件進(jìn)行編譯鏈接,生成絕對(duì)目標(biāo)代碼和可選的HEX格式的可執(zhí)行文件,如果出現(xiàn)編譯鏈接錯(cuò)誤則返回第2)步,修改源程序中的錯(cuò)誤后重新構(gòu)造整個(gè)項(xiàng)目。將沒(méi)有錯(cuò)誤的絕對(duì)目標(biāo)代碼裝入pVision3調(diào)試器進(jìn)行仿真調(diào)試,調(diào)試成功后用編程器將可執(zhí)行文件寫(xiě)入到單片機(jī)應(yīng)用系統(tǒng)的程序存儲(chǔ)器或單片機(jī)內(nèi)部的FlashROM中。二、pVision3上機(jī)實(shí)例下面,我們以實(shí)例來(lái)介紹在pVision3集成開(kāi)發(fā)環(huán)境中,如何創(chuàng)建一個(gè)應(yīng)用程序。/*【例2.1】從鍵盤輸入兩個(gè)數(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í)器/計(jì)數(shù)器1工作于方式2,8位自動(dòng)重裝載*//*f=12MHzSMOD=0波特率=2400的重裝載值*//*啟動(dòng)定時(shí)器1*//*TI置位以便發(fā)送通用異步收發(fā)器的第一個(gè)字符*/}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)語(yǔ)句:while(1),為什么要加這條死循環(huán)語(yǔ)句?在程序執(zhí)行時(shí),CPU會(huì)根據(jù)當(dāng)前指令的長(zhǎng)度自動(dòng)修改指令指針寄存器(PC)的值,以使PC指向下一條指令。如果應(yīng)用程序只占用程序存儲(chǔ)區(qū)的一部分,則程序存儲(chǔ)器中除應(yīng)用程序外的其它部分是無(wú)意義的內(nèi)容。若上例的最后沒(méi)有while(1)這條死循環(huán)語(yǔ)句,則程序執(zhí)行完printf(“max=%d\n”,c)函數(shù)調(diào)用后,PC就會(huì)指向沒(méi)有用戶程序的存儲(chǔ)區(qū),從而取到非法指令而導(dǎo)致錯(cuò)誤。為防止這種錯(cuò)誤,C51應(yīng)用程序的main函數(shù)常用如下結(jié)構(gòu):voidmain(){?//初始化部分while(1){?//其他代碼}}在PC機(jī)上編寫(xiě)的C程序由于有Windows等操作系統(tǒng)的支持,不必采用這種結(jié)構(gòu)。上機(jī)的具體步驟:(1)啟動(dòng)KeiluVision3雙擊桌面上的KeiluVision3圖標(biāo)或者單擊屏幕左下方的“開(kāi)始”,在彈出的對(duì)話框中選擇“程序”;再在彈出的程序?qū)υ捒蛑校瑔螕鬕eiluVision3選項(xiàng),則進(jìn)入KeiluVision3集成開(kāi)發(fā)環(huán)境。(2)建立項(xiàng)目文件選擇ProjectINewProject菜單項(xiàng),則彈出CreateNewProject界面,單擊其中的“保存在”下拉按鈕,選擇“E盤”,再單擊創(chuàng)建新文件夾按鈕,給文件夾起名為“MyProject”然后雙擊MyProject文件夾進(jìn)入。在“文件名”文字框輸入程序項(xiàng)目名稱,這里輸入“Myexample”,保存后的文件名擴(kuò)展名為uv2,以后可以雙擊此文件打開(kāi)該項(xiàng)目。在uVision3中,一個(gè)項(xiàng)目是由包括項(xiàng)目文件(.uv2文件)、源程序等在內(nèi)的很多文件組成,為例便于管理,通常為每個(gè)項(xiàng)目建一個(gè)文件夾,本例建立了項(xiàng)目文件夾MyProject。(3) 選擇CPU器件項(xiàng)目文件夾保存完畢后將彈出SelectDeviceforTargit?Targit1'界面,用于為新建項(xiàng)目選擇一種CPU器件,本例選Atmel公司的AT89C51,選定后“Vision3將按所選器件自動(dòng)設(shè)置默認(rèn)的工具選項(xiàng),從而簡(jiǎn)化了項(xiàng)目的配置過(guò)程。窗口的Description列表框?qū)λx的CPU的I/O線,內(nèi)部RAM、FLASHROM容量等主要性能作了簡(jiǎn)要描述。(4) 加入KeilC提供的啟動(dòng)文件STARTUP.A51完成CPU器件選擇后,點(diǎn)擊OK,則彈出是否增加啟動(dòng)文件到本項(xiàng)目界面,此處可以選擇“是”。STARTUP.A51是用匯編語(yǔ)言編寫(xiě)的源文件,一般用戶無(wú)須修改;高級(jí)用戶可修改其中的內(nèi)容,以定制堆棧管理、動(dòng)態(tài)存儲(chǔ)分配等相關(guān)設(shè)置。創(chuàng)建一個(gè)新項(xiàng)目后,在項(xiàng)目管理窗口(ProjectWorkspace)中自動(dòng)生成一個(gè)默認(rèn)的目標(biāo)(Targit1)和文件組(SouceGroup1)。在項(xiàng)目管理窗口的底部,有5個(gè)選項(xiàng)卡:“文件(File)選項(xiàng)卡、用于在項(xiàng)目中快速定位、添加、移除文件;“寄存器(Regs)”選項(xiàng)卡,用于程序仿真運(yùn)行時(shí)顯示寄存器的值;“書(shū)籍(Book)”選項(xiàng)卡,用于打開(kāi)幫助文件;“函數(shù)(Functions)”選項(xiàng)卡,用于在項(xiàng)目中快速定位已定義的函數(shù);“模板(Templates)”選項(xiàng)卡,對(duì)C語(yǔ)言不太熟悉的初學(xué)者可利用該選項(xiàng)卡提供的功能快速輸入C語(yǔ)言的各種語(yǔ)句,減少源程序的語(yǔ)法錯(cuò)誤。(5)編輯源程序文件選擇FileNew菜單項(xiàng),從打開(kāi)的編輯界面中輸入前面列出的max.c。注意:輸入源程序可采取先保存文件(以文件名max.c保存),然后再輸入的方法。同學(xué)自可體會(huì)其中的優(yōu)點(diǎn)。(6)將源程序加入到項(xiàng)目中源程序文件可以是已有的,也可以是新建的。|JVision3具有十分完善的右鍵功能,選擇項(xiàng)目管理窗口File選項(xiàng)卡,在其中的SourceGroup1上面右擊,則彈出一個(gè)快捷菜單,選擇快捷菜單中的AddFilestoGroup‘SourceGroup1'選項(xiàng),彈出AddFilestoGroup‘SourceGroup1'源文件選擇頁(yè)面,選擇剛才保存的源程序文件max.c,單擊Add按鈕,將其添加到新創(chuàng)建項(xiàng)目中去,然后單擊Close按鈕關(guān)閉此頁(yè)面。設(shè)置項(xiàng)目配置選項(xiàng)右擊項(xiàng)目管理窗口中Targit1節(jié)點(diǎn),在彈出的快捷菜單中選擇OptionsforTargit'Targit1'選項(xiàng),則彈出OptionsforTargit‘Targit1'項(xiàng)目配置界面。這是一個(gè)十分重要的窗口,包括Device、Targit、Output、Listing、C51、A51、BL51Locate、BL51Misc、Debug和Utilities選項(xiàng)卡,每個(gè)選項(xiàng)卡均可根據(jù)項(xiàng)目需要作必要的調(diào)整。本例全部使用默認(rèn)值,不做任何修改。生成可執(zhí)行文件完成項(xiàng)目配置iang的基本設(shè)定之后,就可以對(duì)當(dāng)前新建項(xiàng)目進(jìn)行整體創(chuàng)建(BuildTargit)。單擊項(xiàng)目管理窗口上方工具欄中的Build圖標(biāo)按鈕或選擇ProjectIBuildTargit菜單項(xiàng)單擊。pVision3將按照所設(shè)定的項(xiàng)目選項(xiàng),自動(dòng)完成當(dāng)前項(xiàng)目中所有源程序模塊文件的編譯鏈接,并在|JVision3下面的輸出窗口(OutputWindow)中顯示編譯鏈接提示信息。如果有錯(cuò)誤,則雙擊輸出窗口內(nèi)的提示信息,光標(biāo)將自動(dòng)跳到源程序文件的錯(cuò)誤位置,以便修改;如果沒(méi)有編譯錯(cuò)誤,則生成絕對(duì)目標(biāo)代碼文件(可執(zhí)行文件)。仿真運(yùn)行程序編譯鏈接完成后,選擇Debug|Start/StopDebugsession菜單項(xiàng)或者單擊工具欄上的圖標(biāo)按鈕,彈出新的窗口。在此狀態(tài)下,項(xiàng)目管理窗口自動(dòng)轉(zhuǎn)到Regs選項(xiàng)卡,顯示調(diào)試過(guò)程中單片機(jī)內(nèi)部的工作寄存器R0?R7、累加器A、堆棧指針SP、數(shù)據(jù)指針DPTR、程序計(jì)數(shù)器PC以及程序狀態(tài)字PSW燈特殊功能寄存器的值。在仿真調(diào)試狀態(tài)下,單擊Run圖標(biāo)按鈕或者選擇Debug|Run菜單項(xiàng),啟動(dòng)用戶程序全速運(yùn)行,再選擇View|SerialWindow#1菜單項(xiàng)或者單擊工具欄上SerialWindow#1圖標(biāo)按鈕,打開(kāi)調(diào)試狀態(tài)下pVision3的串行窗口1。用戶程序中采用scanf()和printf()所進(jìn)行的輸入輸出操作,都是通過(guò)穿新窗口1實(shí)現(xiàn)的。單擊串行窗口1,將輸入法切換到英文輸入狀態(tài),輸入數(shù)字“5,10”后回車,立即得到輸出結(jié)果“max=10”。至此,我們完成了建立一個(gè)pVision3項(xiàng)目的全過(guò)程。通過(guò)以上的具體步驟,希望讀者能對(duì)pVision3軟件在宏觀上有一個(gè)感性認(rèn)識(shí),并對(duì)所講的操作方法舉一反三。在熟悉本例所述上機(jī)過(guò)程后,讀者應(yīng)仔細(xì)閱讀下面的上機(jī)注意事項(xiàng),以便更好地使用pVision3開(kāi)發(fā)工具。三、 pVision3上機(jī)注意事項(xiàng)為方便程序調(diào)試,KeilC也提供了scanf和printf這兩個(gè)函數(shù),這兩個(gè)庫(kù)函數(shù)使用8051的串行通信口收發(fā)數(shù)據(jù)。Printf函數(shù)通過(guò)8051串口將數(shù)據(jù)送到“串行窗口”(一個(gè)Windows標(biāo)準(zhǔn)窗口)并顯示出來(lái),scanf函數(shù)從8051串口讀入自“串行窗口”中輸入的數(shù)據(jù)。為使這兩個(gè)函數(shù)正確執(zhí)行,應(yīng)如上例中的serial_initial函數(shù)一樣,設(shè)置好串行口的接收允許。每進(jìn)行一次Build,pVision3都會(huì)根據(jù)項(xiàng)目選項(xiàng)重新編譯生成可執(zhí)行文件。BuildTarget命令只編譯修改過(guò)的或新加進(jìn)來(lái)的文件,然后生成可執(zhí)行文件。Rebuildalltargetfiles命令重新編譯項(xiàng)目中的所有文件,而不論是否修改過(guò),然后再生成可執(zhí)行文件。Translatecurrentfile命令只編譯當(dāng)前源程序編輯窗口中的源程序文件,但并不鏈接生成可執(zhí)行文件。KeilC生成的默認(rèn)可執(zhí)行文件無(wú)擴(kuò)展名,以項(xiàng)目名作為可執(zhí)行文件名稱,其名稱可以修改。多數(shù)編譯器都支持Intel的Hex目標(biāo)文件格式。如在OptionsforTarget對(duì)話窗口的Output選項(xiàng)卡中選擇CreateHexFile選項(xiàng),則在Build項(xiàng)目時(shí)同時(shí)生成默認(rèn)的可執(zhí)行文件和Hex格式的可執(zhí)行文件。在項(xiàng)目管理窗口中右擊某個(gè)文件,從彈出的快捷菜單中選擇RemoveFile,可從項(xiàng)目中移除該文件;此時(shí)項(xiàng)目將不再引用該文件,但并不從硬盤上刪除該文件。原版的KeilC編譯器會(huì)忽略編碼為OxFD的字符,當(dāng)編寫(xiě)中文顯示程序時(shí)會(huì)出現(xiàn)問(wèn)題,應(yīng)安裝針對(duì)這一問(wèn)題的專用補(bǔ)丁。四、 KeilC軟仿真器及程序調(diào)試方法1.調(diào)試相關(guān)工具介紹名稱圖標(biāo)按鈕功能Start/StopDebugSession開(kāi)始/停止調(diào)試時(shí)間ProjectWorkspace顯示/隱藏項(xiàng)目管理窗口OutputWindow顯示/隱藏輸出窗口Inset/RemoveBreakpoint插入/取消斷點(diǎn)KillAllBreakpoint清除所有斷點(diǎn)Enable/Disnablebreakpoint使能/禁止某一斷點(diǎn)DisableAllBreakpoint禁止所有斷點(diǎn),但不清除斷點(diǎn)ResetCPU重新從頭開(kāi)始運(yùn)行程序Run運(yùn)行程序,執(zhí)行到斷點(diǎn)處程序暫停執(zhí)行Halt暫停程序執(zhí)行StepInto進(jìn)入被調(diào)函數(shù)StepOver執(zhí)行一條語(yǔ)句StepOut從被調(diào)函數(shù)返回RuntoCursorLine執(zhí)行到源程序編輯窗口當(dāng)前光標(biāo)處暫停WatchandCallStackWindow顯示/關(guān)閉監(jiān)視和調(diào)用堆棧窗口2.斷點(diǎn)設(shè)置及應(yīng)用實(shí)例下面結(jié)合max.c來(lái)說(shuō)明斷點(diǎn)設(shè)置及跟蹤程序執(zhí)行過(guò)程的基本方法。如果想在main()函數(shù)中觀察變量c的值,則操作步驟如下:在源程序編輯窗口將光標(biāo)移到“printf(“max=%d\n”,c);”代碼行。單擊工具欄上的“插入/取消斷點(diǎn)”圖標(biāo),在該代碼行添加一個(gè)斷點(diǎn)。單擊Start/StopDebugSession按鈕,進(jìn)入調(diào)試狀態(tài),程序執(zhí)行到main()函數(shù)時(shí)暫停。單擊run按鈕繼續(xù)執(zhí)行程序,此時(shí)打開(kāi)SerialWindow#1,在其中輸入兩個(gè)值“5,6”并回車,程序執(zhí)行到第2)步所設(shè)的斷點(diǎn)行暫停。單擊WatchandCallStackWindow按鈕,在界面右下角出現(xiàn)監(jiān)視和調(diào)用堆棧窗口。在此窗口可以兩種方法觀察變量a,b,c的值:方法1:在Locals選項(xiàng)卡中可直接查看各局部變量的值。方法2:在Watch#1或Watch#2選項(xiàng)卡中,單擊有提示說(shuō)明的一行后按F2鍵,輸入變量名a并回車,則可顯示變量a的值。順便說(shuō)明,CallStack選項(xiàng)卡用于顯示函數(shù)間的調(diào)用關(guān)系。此外,還有一種觀察變量值的方法:在源程序編輯窗口中用鼠標(biāo)指向變量c并稍停片刻,在光標(biāo)下方的淺黃色小窗口中將顯示變量c所在的存儲(chǔ)空間、十六進(jìn)制地址、十六進(jìn)制值。五、 C51中的變量和函數(shù)數(shù)據(jù)類型存儲(chǔ)類型字節(jié)順序
存儲(chǔ)模式選擇絕對(duì)地址訪問(wèn)和I/O端口讀/寫(xiě)指針C51函數(shù)/*【Li2.2】檢測(cè)BDATA存儲(chǔ)類型變量bit_status的第三位是否為1,如果是1,則將temp變量加1*/#include"stdio.h"#include"Reg51.h"/*定義一個(gè)可位尋址變量,其第3位為零*/unsignedcharbdatabit_status=0x43; /*0x43寫(xiě)成二進(jìn)制位01000011*//*針對(duì)bit_status變量的第3位聲明一個(gè)位變量*/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不會(huì)加1*/if(bit_statusA3){ /*錯(cuò)誤代碼*/temp++;}if(bit_status&0x04){/*如果第3位置位temp再加1*/temp++;}printf("temp=%bd\n",temp);while(1);}/*上例運(yùn)行后,在KeilC的串行窗口顯示的temp的值是1,而不是0!原因在于第12行錯(cuò)誤代碼所致*//*【例2.3】在代碼段中定義及訪問(wèn)只讀數(shù)據(jù)的實(shí)例*/#include"reg51.h"#include"stdio.h"/*下面的chs字符數(shù)組的最后一個(gè)元素的值初始化為0,C語(yǔ)言*/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】在代碼段中定義及訪問(wèn)只讀數(shù)據(jù)的實(shí)例(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è)置斷點(diǎn),運(yùn)行到此處時(shí),機(jī)器周期數(shù)為586*/XBYTE[0x0000]=*generic_ptr;generic_ptr++;}xd_ptr=mystring; /*此行設(shè)置斷點(diǎn),運(yùn)行到此處時(shí),機(jī)器周期數(shù)為922*/while(*xd_ptr){ /*此行設(shè)置斷點(diǎn),運(yùn)行到此處時(shí),機(jī)器周期數(shù)為924*/XBYTE[0x0000]=*xd_ptr;xd_ptr++;}while(1); /*此行設(shè)置斷點(diǎn),運(yùn)行到此處時(shí),機(jī)器周期數(shù)為1073*/仿真運(yùn)行上例時(shí),單擊Start/StopDebugSession按鈕運(yùn)行程序,在源程序編輯窗口將光標(biāo)定位到第1個(gè)斷點(diǎn)行,再單擊Stepinto按鈕,使程序運(yùn)行到光標(biāo)位置后暫停執(zhí)行。此時(shí)在ProjectWorkspace中Regs選項(xiàng)卡上的statues和sec兩項(xiàng),分別代表程序已運(yùn)行的機(jī)器周期數(shù)和秒數(shù),分別為586個(gè)機(jī)器周期和0.00058600s。按本例源程序注釋設(shè)置好斷點(diǎn),重新運(yùn)行程序,運(yùn)行到各斷點(diǎn)行程序暫停執(zhí)行時(shí),觀察ProjectWorkspace中Regs選項(xiàng)卡上的states項(xiàng),可得到執(zhí)行到各斷點(diǎn)語(yǔ)句時(shí)的機(jī)器周期數(shù)(源程序注釋中已記錄),用此方法可知執(zhí)行完使用通用指針的第一個(gè)循環(huán)需要922-586=336個(gè)機(jī)器周期,使用特定指向指針的后一個(gè)循環(huán)之需要1073-924=149個(gè)機(jī)器周期,可見(jiàn)特定指向指針的效率遠(yuǎn)高于通用指針。在實(shí)時(shí)性要求較高時(shí),對(duì)代碼的執(zhí)行效率有要求,可用本例介紹的方法獲取某段代碼的執(zhí)行時(shí)間,以判斷其是否滿足系統(tǒng)性能要求。C51函數(shù)語(yǔ)法與標(biāo)準(zhǔn)C函數(shù)基本相同,但針對(duì)51單片機(jī)的特點(diǎn)作了擴(kuò)展,定義C51函數(shù)的語(yǔ)法格式如下:<return_type>funcname(<args>)<small|compact|large><reentrant><interruptx><usingy>/*【例2.5】遞歸調(diào)用不可重入函數(shù)錯(cuò)誤計(jì)算5的階乘(factorial)*/#include"stdio.h"#include"Reg51.h"/*不可重入函數(shù)fact遞歸調(diào)用來(lái)計(jì)算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ù)上次運(yùn)行未結(jié)束,又被再次調(diào)用的情形*//*若定義某函數(shù)時(shí)不特別指明,C51中就把該函數(shù)作為不可重入函數(shù)看待*/上面的程序執(zhí)行后,計(jì)算出的5的階乘為1,而不是120,就是因?yàn)檫f歸調(diào)用了不可重入函數(shù)fact()而導(dǎo)致了錯(cuò)誤的結(jié)果。C51允許使用reentrant屬性將函數(shù)定義成可重入函數(shù),而不用擔(dān)心變量被覆蓋,但要修改Startup.A51相關(guān)內(nèi)容。/*【例2.6】遞歸調(diào)用可重入函數(shù)正確計(jì)算5的階乘*//*注意:編譯前須修改Startup.A51啟動(dòng)文件*/#include"stdio.h"#include"Reg51.h"/*遞歸調(diào)用可重入函數(shù)fact計(jì)算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);}項(xiàng)目用Small存儲(chǔ)模式,下面是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)以上部分為特殊功能寄存器,但由于模擬棧是向下生長(zhǎng)的,因此不會(huì)進(jìn)入特殊功能寄存器區(qū)。六、KeilC中的51單片機(jī)中斷編程/*【例2.7】8051晶振頻率fosc為12MHz,用定時(shí)器0的溢出中斷實(shí)現(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;/*定時(shí)器初值高/*定時(shí)器初值高8位*//*定時(shí)器初值低8位*//*關(guān)閉所有中斷*//*停止定時(shí)器0*//*允許向串口發(fā)送數(shù)據(jù)*//*定時(shí)器0工作在方式1,16位定時(shí)器*//*裝定時(shí)器初值,50ms后溢出*//*只開(kāi)定時(shí)器0的中斷,其余中斷禁止*//*啟動(dòng)定時(shí)器0*//*關(guān)定時(shí)器0中斷*//*停止定時(shí)器0*//*啟動(dòng)定時(shí)器0*/注:定時(shí)時(shí)間=(65535-初值)X機(jī)器周期,而機(jī)器周期=12/12000000=
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 衣物代洗協(xié)議書(shū)
- 語(yǔ)文合作協(xié)議書(shū)
- 幼兒代餐協(xié)議書(shū)
- 裝修勞務(wù)協(xié)議書(shū)
- 小程序合同協(xié)議
- 自愿走讀協(xié)議書(shū)
- 學(xué)生招聘協(xié)議書(shū)
- 詳細(xì)雇傭合同范本
- 2026年上半年湖南株洲市市直單位公益性崗位招聘16人考試重點(diǎn)題庫(kù)及答案解析
- 資產(chǎn)頂賬協(xié)議書(shū)
- 求職OMG-大學(xué)生就業(yè)指導(dǎo)與技能開(kāi)發(fā)智慧樹(shù)知到期末考試答案章節(jié)答案2024年中國(guó)海洋大學(xué)
- JBT 7387-2014 工業(yè)過(guò)程控制系統(tǒng)用電動(dòng)控制閥
- A課堂懲罰游戲
- 整理收納師行業(yè)分析
- GB/T 228.1-2021金屬材料拉伸試驗(yàn)第1部分:室溫試驗(yàn)方法
- 氫能與燃料電池-課件-第五章-制氫技術(shù)
- 科研倫理與學(xué)術(shù)規(guī)范-課后作業(yè)答案
- 2023QC小組活動(dòng)基礎(chǔ)知識(shí)培訓(xùn)
- 生理學(xué)期末考試復(fù)習(xí)試題庫(kù)及答案
- 旅游地理學(xué) 國(guó)家公園建設(shè)與管理
- JJF(石化)036-2020漆膜附著力測(cè)定儀(劃圈法)校準(zhǔn)規(guī)范
評(píng)論
0/150
提交評(píng)論