




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
第4章單片機程序設(shè)計方法4.1
匯編程序設(shè)計方法
4.1.1程序編制的方法和技巧
4.1.2源程序的編輯和匯編
4.1.3
基本程序結(jié)構(gòu)
4.1.4
常用程序舉例4.2C51程序設(shè)計方法
4.2.1C語言的特點及程序結(jié)構(gòu)
4.2.2C51的數(shù)據(jù)類型
4.2.351的運算量
4.2.4C51的運算符及表達式
4.2.5表達式語句及復(fù)合語句
4.2.6C51的輸入輸出
4.2.7C51程序基本結(jié)構(gòu)與相關(guān)語句
4.2.8函數(shù)●基本要求:
1.掌握匯編語言程序設(shè)計方法.
2.具備較復(fù)雜程序設(shè)計能力.3.掌握C語言結(jié)構(gòu)和編程方法
●學(xué)習(xí)重點:
1.匯編語言程序設(shè)計方法
.
2.循環(huán)結(jié)構(gòu)程序的編寫.
4.1.1
程序編制的方法和技巧
1.程序編制的步驟1)預(yù)完成任務(wù)的分析首先,要對單片機應(yīng)用系統(tǒng)預(yù)完成的任務(wù)進行深入的分析,明確系統(tǒng)的設(shè)計任務(wù)、功能要求和技術(shù)指標(biāo)。其次,要對系統(tǒng)的硬件資源和工作環(huán)境進行分析。這是單片機應(yīng)用系統(tǒng)程序設(shè)計的基礎(chǔ)和條件。2)進行算法的優(yōu)化算法是解決具體問題的方法。應(yīng)用系統(tǒng)經(jīng)過分析、研究和明確規(guī)定后,對應(yīng)實現(xiàn)的功能和技術(shù)指標(biāo)可以利用嚴(yán)密的數(shù)學(xué)方法或數(shù)學(xué)模型來描述,從而把實際問題轉(zhuǎn)化成由計算機進行處理的問題。
同一個問題的算法可以有多種,結(jié)果也可能不盡相同,所以,應(yīng)對各種算法進行分析比較,并進行合理的優(yōu)化。比如,用迭代法解微分方程,需要考慮收斂速度的快慢(即在一定的時間里能否達到精度要求)。而有的問題則受內(nèi)存容量的限制而對時間要求并不苛刻。對于后一種情況,速度不快但節(jié)省內(nèi)存的算法則應(yīng)是首選。3)程序總體設(shè)計及流程圖繪制經(jīng)過任務(wù)分析、算法優(yōu)化后,就可以進行程序的總體構(gòu)思,確定程序的結(jié)構(gòu)和數(shù)據(jù)形式,并考慮資源的分配和參數(shù)的計算等。然后根據(jù)程序運行的過程,勾畫出程序執(zhí)行的邏輯順序,用圖形符號將總體設(shè)計思路及程序流向繪制在平面圖上,從而使程序的結(jié)構(gòu)關(guān)系直觀明了,便于檢查和修改。清晰正確的流程圖是編制正確無誤的應(yīng)用程序的基礎(chǔ)和條件。所以,繪制一個好的流程圖,是程序設(shè)計的一項重要內(nèi)容。流程圖可以分為總流程圖和局部流程圖??偭鞒虉D側(cè)重反映程序的邏輯結(jié)構(gòu)和各程序模塊之間的相互關(guān)系。局部流程圖反映程序模塊的具體實施細節(jié)。對于簡單的應(yīng)用程序,可以不畫流程圖。但是當(dāng)程序較為復(fù)雜時,繪制流程圖是一個良好的編程習(xí)慣。常用的流程圖符號有:開始和結(jié)束符號、工作任務(wù)符號、判斷分支符號、程序連接符號、程序流向符號等
2.編制程序的方法和技巧1)采用模塊化程序設(shè)計方法應(yīng)用系統(tǒng)的程序由包含多個模塊的主程序和各種子程序組成。各程序模塊都要完成一個明確的任務(wù),實現(xiàn)某個具體的功能,如:發(fā)送、接收、延時、打印和顯示等。模塊化的程序設(shè)計方法具有明顯的優(yōu)點。把一個多功能的復(fù)雜的程序劃分為若干個簡單的、功能單一的程序模塊,有利于程序的設(shè)計和調(diào)試,有利于程序的優(yōu)化和分工,提高了程序的閱讀性和可靠性,使程序的結(jié)構(gòu)層次一目了然。2.盡量采用循環(huán)結(jié)構(gòu)和子程序采用循環(huán)結(jié)構(gòu)和子程序可以使程序的長度減少、占用內(nèi)存空間減少。多重循環(huán),注意各重循環(huán)的初值和循環(huán)結(jié)束條件,避免出現(xiàn)“死循環(huán)”現(xiàn)象;通用的子程序,除了用于存放子程序入口參數(shù)的寄存器外,子程序中用到的其它寄存器的內(nèi)容應(yīng)壓入堆棧進行現(xiàn)場保護,并要特別注意堆棧操作的壓入和彈出的平衡;中斷處理子程序除了要保護程序中用到的寄存器外,還應(yīng)保護標(biāo)志寄存器。3.匯編語言的語句格式語句行由四個字段組成:
[標(biāo)號:]操作碼[操作數(shù)][;注釋]
括號內(nèi)的部分可以根據(jù)實際情況取舍。每個字段之間要用分隔符分隔,可以用作分隔符的符號有空格、冒號、逗號、分號等。如:LOOP:MOVA,#7FH;A←7FH1)標(biāo)號標(biāo)號是語句地址的標(biāo)志符號,用于引導(dǎo)對該語句的非順序訪問。有關(guān)標(biāo)號的規(guī)定為:2)操作碼操作碼用于規(guī)定語句執(zhí)行的操作。它是匯編語句中唯一不能空缺的部分。它由指令助記符表示。
由1~8個ASCII字符組成。第一個字符必須是字母,其余字符可以是字母、數(shù)字或其他特定字符;不能使用已經(jīng)定義了的符號作為標(biāo)號。如指令助記符、寄存器符號名稱等;后邊必須跟冒號。3)操作數(shù)操作數(shù)用于給指令的操作提供數(shù)據(jù)或地址。在一條匯編語句中操作數(shù)可能是空缺的,也可能包括一項,還可能包括兩項或三項。各操作數(shù)間以逗號分隔。操作數(shù)字段的內(nèi)容可能包括以下幾種情況:(1)工作寄存器名;(2)特殊功能寄存器名;(3)標(biāo)號名;(4)常數(shù);(5)符號“$”,表示程序計數(shù)器PC的當(dāng)前值;(6)表達式。4)注釋
注釋只是對語句的說明。注釋字段可以增加程序的可讀性,有助于編程人員的閱讀和維護。注釋字段必須以分號“;”開頭,長度不限,當(dāng)一行書寫不下時,可以換行接著書寫,但換行時應(yīng)注意要在開頭使用分號“;”。5)數(shù)據(jù)的表示形式數(shù)據(jù)可以有以下幾種表示形式:二進制數(shù),末尾以字母B標(biāo)識。如:10001111B;十進制數(shù),末尾以字母D標(biāo)識或?qū)⒆帜窪省略。如:88D,66;十六進制數(shù),末尾以字母H標(biāo)識。如:78H,0A8H(但應(yīng)注意的是,十六進制數(shù)以字母A~F開頭時應(yīng)在其前面加上數(shù)字“0”。);ASCII碼,以單引號括起來標(biāo)識。如:‘AB’,‘1245’
4.1.2源程序的編輯和匯編
1)源程序的編輯源程序的編寫要依據(jù)80C51匯編語言的基本規(guī)則,特別要用好常用的匯編命令(即偽指令),例如下面的程序段:
ORG0040HMOVA,#7FHMOVR1,#44HEND
這里的ORG和END是兩條偽指令,其作用是告訴匯編程序此匯編源程序的起止位置。編輯好的源程序應(yīng)以“.ASM”擴展名存盤,以備匯編程序調(diào)用。
1.源程序的編輯與匯編2)源程序的匯編
將匯編語言源程序轉(zhuǎn)換為單片機能執(zhí)行的機器碼形式的目標(biāo)程序的過程叫匯編。常用的方法有兩種:手工匯編時,把程序用助記符指令寫出后,通過手工方式查指令編碼表,逐個把助記符指令翻譯成機器碼,然后把得到的機器碼程序(以十六進制形式)鍵入到單片機開發(fā)機中,并進行調(diào)試。機器匯編是在常用的個人計算機PC上,使用交叉匯編程序?qū)R編語言源程序轉(zhuǎn)換為機器碼形式的目標(biāo)程序。生成的目標(biāo)程序由PC機傳送到開發(fā)機上,經(jīng)調(diào)試無誤后,再固化到單片機的程序存儲器ROM中。源程序經(jīng)過機器匯編后,形成的若干文件中含有兩個主要文件,一是列表文件,另一個是目標(biāo)碼文件。因匯編軟件的不同,文件的格式及信息會有一些不同。但主要信息如下:列表文件:地址目標(biāo)碼匯編程序
ORG0040H0040H747FMOVA,#7FH0042H7944MOVR1,#44HEND目標(biāo)碼文件:首地址末地址目標(biāo)碼0040H0044H747F7944
偽指令是匯編程序能夠識別并對匯編過程進行某種控制的匯編命令。它不是單片機執(zhí)行的指令,所以沒有對應(yīng)的可執(zhí)行目標(biāo)碼,匯編后產(chǎn)生的目標(biāo)程序中不會再出現(xiàn)偽指令。2.偽指令1)起始地址設(shè)定偽指令ORG格式為:
ORG表達式該指令的功能是向匯編程序說明下面緊接的程序段或數(shù)據(jù)段存放的起始地址。表達式通常為16進制地址,也可以是已定義的標(biāo)號地址。
ORG8000HSTART:MOVA,#30H……
此時規(guī)定該段程序的機器碼從地址8000H單元開始存放。在每一個匯編語言源程序的開始,都要設(shè)置一條ORG偽指令來指定該程序在存儲器中存放的起始位置。若省略O(shè)RG偽指令,則該程序段從0000H單元開始存放。在一個源程序中,可以多次使用ORG偽指令規(guī)定不同程序段或數(shù)據(jù)段存放的起始地址,但要求地址值由小到大依序排列,不允許空間重疊。
2)匯編結(jié)束偽指令END格式為:
END
該指令的功能是結(jié)束匯編。匯編程序遇到END偽指令后即結(jié)束匯編。處于END之后的程序,匯編程序?qū)⒉惶幚怼?)字節(jié)數(shù)據(jù)定義偽指令DB[標(biāo)號:]DB字節(jié)數(shù)據(jù)表
功能是從標(biāo)號指定的地址開始,在ROM中定義字節(jié)數(shù)據(jù)。該偽指令將字節(jié)數(shù)據(jù)表中的數(shù)據(jù)根據(jù)從左到右的順序依次存放在指定的存儲單元中。一個數(shù)據(jù)占一個存儲單元。例如:DB“howareyou?”把字符串中的字符以ASCII碼的形式存放在連續(xù)的ROM單元中。又如:DB-2,-4,-6,8,10,18把6個數(shù)轉(zhuǎn)換為十六進制表示(FEH,F(xiàn)CH,F(xiàn)AH,08H,0AH,12H),并連續(xù)地存放在6個ROM。
該偽指令常用于存放數(shù)據(jù)表格。如要存放顯示用的十六進制的字形碼,可以用多條DB指令完成:
DB0C0H,0F9H,0A4H,0B0HDB99H,92H,82H,0F8HDB80H,90H,88H,83HDB0C6H,0A1H,86H,84H4)字?jǐn)?shù)據(jù)定義偽指令DW[標(biāo)號:]DW字?jǐn)?shù)據(jù)表功能是從標(biāo)號指定的地址單元開始,在程序存儲器中定義字?jǐn)?shù)據(jù)。該偽指令將字或字表中的數(shù)據(jù)根據(jù)從左到右的順序依次存放在指定的存儲單元中。應(yīng)特別注意:16位的二進制數(shù),高8位存放在低地址單元,低8位存放在高地址單元。例如:
ORG1400HDATA:DW324AH,3CH……
匯編后,(1400H)=32H,(1401H)=4AH,(1402H)=00H,(1403H)=3CH。5)空間定義偽指令DS[標(biāo)號:]DS表達式功能是從標(biāo)號指定的地址單元開始,在程序存儲器中保留由表達式所指定的個數(shù)的存儲單元作為備用的空間,并都填以零值。例如:
ORG3000HBUF:DS50……
匯編后,從地址3000H開始保留50個存儲單元作為備用單元。
6)賦值偽指令EQU符號名EQU表達式功能是將表達式的值(一個8位或16位的數(shù))或特定的某個匯編符號定義為一個指定的符號名。例如:A09EQUR1
LENEQU10SUMEQU21HBLOCKEQU22HCLRAMOVR7,#LENMOVR0,#BLOCKLOOP:ADDA,@R0INCR0DJNZR7,LOOPMOVSUM,AEND
該程序的功能是,把BLOCK單元開始存放的10個無符號數(shù)進行求和,并將結(jié)果存入SUM單元中。
7)數(shù)據(jù)地址賦值偽指令:字符名DATAnnDATA指令與EQU指令功能類似,它是將16位地址賦值所定義的字符名。DATA指令與EQU指令主要的區(qū)別是:EQU定義的名必須先定義后使用,而DATA定義的字符名沒有這種限制,故DATA偽指令通常用在原程序的開頭或末尾。8)位地址符號定義偽指令BIT格式為:符號名BIT位地址表達式功能是將位地址賦給指定的符號名。其中,位地址表達式可以是絕對地址,也可以是符號地址。例如:
STBITP1.0將P1.0的位地址賦給符號名ST,在其后的編程中就可以用ST來代替P1.0。4.1.3基本程序結(jié)構(gòu)程序的基本算法結(jié)構(gòu)有3種:順序結(jié)構(gòu)、分支(選擇)結(jié)構(gòu)和循環(huán)結(jié)構(gòu)。
循環(huán)結(jié)構(gòu)(a)當(dāng)型循環(huán);(b)直到型循環(huán)1.順序程序順序程序是指無分支、無循環(huán)結(jié)構(gòu)的程序。其執(zhí)行流程是依指令在存儲器中的存放順序進行的。一、數(shù)據(jù)傳送例內(nèi)部RAM的2AH~2EH單元中存儲的數(shù)據(jù)如圖所示。試編寫程序?qū)崿F(xiàn)圖示的數(shù)據(jù)傳送結(jié)果。方法一:MOVA,2EH;2字節(jié),1個機器周期MOV2EH,2DH;3字節(jié),2個機器周期MOV2DH,2CH;3字節(jié),2個機器周期MOV2CH,2BH;3字節(jié),2個機器周期MOV2BH,#00H;3字節(jié),2個機器周期方法二:CLRA;1字節(jié),1個機器周期XCHA,2BH;2字節(jié),1個機器周期XCHA,2CH;2字節(jié),1個機器周期XCHA,2DH;2字節(jié),1個機器周期XCHA,2EH;2字節(jié),1個機器周期以上兩種方法均可以實現(xiàn)所要求的傳送任務(wù)。方法一使用14個字節(jié)的指令代碼,執(zhí)行時間為9個機器周期;方法二僅用了9個字節(jié)的代碼,執(zhí)行時間也減少到了5個機器周期。實際應(yīng)用中應(yīng)盡量采用指令代碼字節(jié)數(shù)少、執(zhí)行時間短的高效率程序,即注意程序的優(yōu)化。
例有一變量存放在片內(nèi)RAM的20H單元,其取值范圍為:00H~05H。要求編制一段程序,根據(jù)變量值求其平方值,并存入片內(nèi)RAM的21H單元。程序如下:
ORG1000HSTART:MOVDPTR,#2000HMOVA,20HMOVCA,@A+DPTRMOV21H,ASJMP$ORG2000HTABLE:DB00,01,04,09,16,25END。
在程序存儲器的一片存儲單元中建立起該變量的平方表。用數(shù)據(jù)指針DPTR指向平方表的首址,則變量與數(shù)據(jù)指針之和的地址單元中的內(nèi)容就是變量的平方值。采樣MOVCA,@A+PC指令也可以實現(xiàn)查表功能,且不破壞DPTR的內(nèi)容,從而可以減少保護DPTR的內(nèi)容所需的開銷。但表格只能存放在MOVCA,@A+PC指令后的256字節(jié)內(nèi),即表格存放的地點和空間有一定限制。
簡單運算由于80C51指令系統(tǒng)中只有單字節(jié)加法指令,因此對于多字節(jié)的相加運算必須從低位字節(jié)開始分字節(jié)進行。除最低字節(jié)可以使用ADD指令外,其他字節(jié)相加時要把低字節(jié)的進位考慮進去,這時就應(yīng)該使用ADDC指令。例雙字節(jié)無符號數(shù)加法。設(shè)被加數(shù)存放在內(nèi)部RAM的51H、50H單元,加數(shù)存放在內(nèi)部RAM的61H、60H單元,相加的結(jié)果存放在內(nèi)部RAM的51H、50H單元,進位存放在位尋址區(qū)的00H位中。
程序段如下:MOVR0,#50H;被加數(shù)的低字節(jié)地址 MOVR1,#60H;加數(shù)的低字節(jié)地址 MOVA,@R0;取被加數(shù)低字節(jié)ADDA,@R1;加上加數(shù)低字節(jié)MOV@R0,A;保存低字節(jié)相加結(jié)果INCR0;指向被加數(shù)高字節(jié)INCR1;指向加數(shù)高字節(jié)MOVA,@R0;取被加數(shù)高字節(jié)ADDCA,@R1;加上加數(shù)高字節(jié)(帶進位加)MOV@R0,A;存高字節(jié)相加結(jié)果MOV00H,C;保存進位。
2.分支程序分支結(jié)構(gòu)可以分成單分支、雙分支和多分支幾種情況:1)單分支程序例求單字節(jié)有符號數(shù)的二進制補碼。設(shè)有一個單字節(jié)二進制數(shù)存于A中,編寫程序求起補碼。程序如下:START:JNBACC.7,OK;(A)>0,MOVC,ACC.7WOVA,@R0CPLAADDA,#1MOVACC.7COK:RET
例求雙字節(jié)補碼。設(shè)在內(nèi)部RAM的addr1和addr+1單元存有一個雙字節(jié)數(shù)(高位字節(jié)存于高地址單元)。編寫程序?qū)⑵渥x出取補后再存入addr2和addr2+1單元。首先對低字節(jié)取補,然后判其結(jié)果是否為全“0”。若是,則高字節(jié)取補,否則高字節(jié)取反。
START:MOVR0,#addr1;原碼低字節(jié)地址送R0 MOVR1,#addr2;補碼低字節(jié)地址送R1 MOVA,@R0;原碼低字節(jié)送A CPLA;A內(nèi)容取補
INCAMOV@R1,A;存補碼低字節(jié)
INCR0;調(diào)整地址,指向下一單元
INCR1JZZERO;(A)=0時轉(zhuǎn)ZEROMOVA,@R0;原碼高字節(jié)送A CPLAMOV@R1,A;高字節(jié)反碼存入addr2+1單元
SJMPLOOP1ZERO:MOVA,@R0;高字節(jié)取補存入addr2+1單元
CPLAINCAMOV@R1,ALOOP1:RET2)雙分支程序例設(shè)變量x以補碼的形式存放在片內(nèi)RAM的30H單元,變量y與x的關(guān)系是:當(dāng)x大于0時,y=x;當(dāng)x=0時,y=20H;當(dāng)x小于0時,y=x+5。編制程序,根據(jù)x的大小求y并送回原單元。程序段如下:START:MOVA,30HJZNEXTANLA,#80H;判斷符號位
JZLPMOVA,#05HADDA,30HMOV30H,ASJMPLPNEXT:MOV30H,#20HLP:SJMP$
3)多分支程序例:根據(jù)R7的內(nèi)容轉(zhuǎn)向相應(yīng)的處理程序。設(shè)R7的內(nèi)容為0~N,對應(yīng)的處理程序的入口地址分別為PP0~PPN。程序段如下:START:MOVDPTR,#TAB;置分支入口地址表首址
MOVA,R7;分支轉(zhuǎn)移序號送AADDA,R7;分支轉(zhuǎn)移序號乘以2MOVR3,A;暫存于R3MOVCA,@A+DPTR;取高位地址
XCHA,R3INCAMOVCA,@A+DPTR;取低位地址
MOVDPL,A;處理程序入口地址低8位送DPLMOVDPH,R3;處理程序入口地址高8位送DPHCLRAJMP@A+DPTRTAB:DWPP0DWPP1………DWPPN
3.循環(huán)程序按某種控制規(guī)律重復(fù)執(zhí)行的程序稱為循環(huán)程序。循環(huán)程序有先執(zhí)行后判斷和先判斷后執(zhí)行兩種基本結(jié)構(gòu):1)先執(zhí)行后判斷例50ms延時程序。若晶振頻率為12MHz,則一個機器周期為1μs。執(zhí)行一條DJNZ指令需要2個機器周期,即2μs。采用循環(huán)計數(shù)法實現(xiàn)延時,循環(huán)次數(shù)可以通過計算獲得,并選擇先執(zhí)行后判斷的循環(huán)結(jié)構(gòu)。程序段如下:
DEL:MOVR7,#200;1μsDEL1:MOVR6,#123;1μsNOP ;1μsDEL2:DJNZR6,DEL2;2μs,計(2×123)μsDJNZR7,DEL1;2μs,
RET
共計[(2×123+2+2)×200+1]μs,即50.001ms
例:無符號數(shù)排序程序。在片內(nèi)RAM中,起始地址為30H的8個單元中存放有8個無符號數(shù)。試對這些無符號數(shù)進行升序排序。數(shù)據(jù)排序常用的方法是冒泡排序法。執(zhí)行時從前向后進行相鄰數(shù)的比較,如數(shù)據(jù)的大小次序與要求的順序不符就將這兩個數(shù)互換,否則不互換。對于升序排序,通過這種相鄰數(shù)的互換,使小數(shù)向前移動,大數(shù)向后移動。從前向后進行一次冒泡(相鄰數(shù)的互換),就會把最大的數(shù)換到最后。再進行一次冒泡,就會把次大的數(shù)排在倒數(shù)第二的位置。設(shè)R7為比較次數(shù)計數(shù)器,初始值為07H,位地址00H為數(shù)據(jù)互換標(biāo)志位。
START:CLR00H;互換標(biāo)志清0 MOVR7,#07H;各次冒泡比較次數(shù)
MOVR0,#30H;數(shù)據(jù)區(qū)首址
LOOP:MOVA,@R0;取前數(shù)
MOV2BH,A;暫存
INCR0MOV2AH,@R0;取后數(shù)
CLRCSUBBA,@R0;前數(shù)減后數(shù)
JCNEXT;前數(shù)小于后數(shù),不互換
MOV@R0,2BHDECR0MOV@R0,2AH;兩數(shù)交換
INCR0;準(zhǔn)備下一次比較
SETB00H;置互換標(biāo)志
NEXT:DJNZR7,LOOP;進行下一次比較
JB00H,START;進行下一輪冒泡
SJMP$2)先判斷后執(zhí)行
例將內(nèi)部RAM中起始地址為data的數(shù)據(jù)串傳送到外部RAM中起始地址為buffer的存儲區(qū)域內(nèi),直到發(fā)現(xiàn)‘$’字符停止傳送。由于循環(huán)次數(shù)事先不知道,但循環(huán)條件可以測試到。所以,采用先判斷后執(zhí)行的結(jié)構(gòu)比較適宜。程序段如下:
MOVR0,#dataMOVDPTR,#bufferLOOP0:MOVA,@R0CJNEA,#24H,LOOP1;判斷是否為‘$’字符
SJMPLOOP2;是‘$’字符,轉(zhuǎn)結(jié)束LOOP1:MOVX@DPTR,A;不是‘$’字符,執(zhí)行傳送
INCR0INCDPTRSJMPLOOP0;傳送下一數(shù)據(jù)
LOOP2:……4.子程序及其調(diào)用1)子程序的調(diào)用在實際應(yīng)用中,經(jīng)常會遇到一些帶有通用性的問題,例如:數(shù)值轉(zhuǎn)換、數(shù)值計算等,在一個程序中可能要使用多次。這時可以將其設(shè)計成通用的子程序供隨時調(diào)用。
子程序主要特點是,在執(zhí)行過程中需要由其它程序來調(diào)用,執(zhí)行完后又需要把執(zhí)行流程返回到調(diào)用該子程序的主程序。
子程序調(diào)用時要注意兩點:一是現(xiàn)場的保護和恢復(fù);二是主程序與子程序的參數(shù)傳遞。2)現(xiàn)場保護與恢復(fù)
在子程序執(zhí)行過程中常常要用到單片機的一些通用單元,如工作寄存器R0~R7、累加器A、數(shù)據(jù)指針DPTR,以及有關(guān)標(biāo)志和狀態(tài)等。而這些單元中的內(nèi)容在調(diào)用結(jié)束后的主程序中仍有用,所以需要進行保護,稱為現(xiàn)場保護。在執(zhí)行完子程序,返回繼續(xù)執(zhí)行主程序前恢復(fù)其原內(nèi)容,稱為現(xiàn)場恢復(fù)。保護與恢復(fù)的方法有以下兩種:在主程序中實現(xiàn);在子程序中實現(xiàn)。
在主程序中實現(xiàn)示例如下:
PUSHPSW;保護現(xiàn)場
PUSHACC;
PUSHB;
MOVPSW,#10H;換當(dāng)前工作寄存器組
LCALLaddr16;子程序調(diào)用
POPB;恢復(fù)現(xiàn)場
POPACC;
POPPSW;
……
其特點是結(jié)構(gòu)靈活。
在子程序中實現(xiàn)示例如下:SUB1:PUSHPSW;保護現(xiàn)場
PUSHACC;
PUSHB;
……MOVPSW,#10H;換當(dāng)前工作寄存器組
……POPB;恢復(fù)現(xiàn)場
POPACC;
POPPSW;
RET其特點是程序規(guī)范、清晰。注意,無論哪種方法保護與恢復(fù)的順序要對應(yīng)。3)參數(shù)傳遞
由于子程序是主程序的一部分,所以,在程序的執(zhí)行時必然要發(fā)生數(shù)據(jù)上的聯(lián)系。在調(diào)用子程序時,主程序應(yīng)通過某種方式把有關(guān)參數(shù)(即子程序的入口參數(shù))傳給子程序,當(dāng)子程序執(zhí)行完畢后,又需要通過某種方式把有關(guān)參數(shù)(即子程序的出口參數(shù))傳給主程序。在80C51單片機中,傳遞參數(shù)的方法有三種:
利用累加器或寄存器在這種方式中,要把預(yù)傳遞的參數(shù)存放在累加器A或工作寄存器R0~R7中。即在主程序調(diào)用子程序時,應(yīng)事先把子程序需要的數(shù)據(jù)送入累加器A或指定的工作寄存器中,當(dāng)子程序執(zhí)行時,可以從指定的單元中取得數(shù)據(jù),執(zhí)行運算。反之,子程序也可以用同樣的方法把結(jié)果傳送給主程序。
例編寫程序,實現(xiàn)c=a2+b2。設(shè)a,b,c分別存于內(nèi)部RAM的30H,31H,32H三個單元中。程序段如下:START:MOVA,30H;取aACALLSQR;調(diào)用查平方表
MOVR1,A;a2暫存于R1中
MOVA,31H;取bACALLSQR;調(diào)用查平方表
ADDA,R1;a2+b2存于A中
MOV32H,A;存結(jié)果
SJMP$SQR:MOVDPTR,#TAB;子程序
MOVCA,@A+DPTR;
RETTAB:DB0,1,4,9,16,25,36,49,64,81
利用存儲器當(dāng)傳送的數(shù)據(jù)量比較大時,可以利用存儲器實現(xiàn)參數(shù)的傳遞。在這種方式中,事先要建立一個參數(shù)表,用指針指示參數(shù)表所在的位置。當(dāng)參數(shù)表建立在內(nèi)部RAM時,用R0或R1作參數(shù)表的指針。當(dāng)參數(shù)表建立在外部RAM時,用DPTR作參數(shù)表的指針。例將R0和R1指向的內(nèi)部RAM中兩個3字節(jié)無符號整數(shù)相加,結(jié)果送到由R0指向的內(nèi)部RAM中。入口時,R0和R1分別指向加數(shù)和被加數(shù)的低位字節(jié);出口時,R0指向結(jié)果的高位字節(jié)。低字節(jié)在高地址,高字節(jié)在低地址。
實現(xiàn)程序:NADD:MOVR7,#3;三字節(jié)加法
CLRC;NADD1:MOVA,@R0;取加數(shù)低字節(jié)
ADDCA,@R1;被加數(shù)低字節(jié)加AMOV@R0,A;
DECR0DECR1DJNZR7,NADD1INCR0RET
利用堆棧利用堆棧傳遞參數(shù)是在子程序嵌套中常采用的一種方法。在調(diào)用子程序前,用PUSH指令將子程序中所需數(shù)據(jù)壓入堆棧,進入執(zhí)行子程序時,再用POP指令從堆棧中彈出數(shù)據(jù)。
例把內(nèi)部RAM中20H單元中的1個字節(jié)十六進制數(shù)轉(zhuǎn)換為2位ASCII碼,存放在R0指示的兩個單元中。
MAIN:MOVA,20H;
SWAPAPUSHACC;參數(shù)入棧
ACALLHEASCPOPACCMOV@R0,A;存高位十六進制數(shù)轉(zhuǎn)換結(jié)果
INCR0;修改指針
PUSH20H;參數(shù)入棧
ACALLHEASCPOPACCMOV@R0,A;存低位十六進制數(shù)轉(zhuǎn)換結(jié)果
SJMP$
HEASC:MOVR1,SP;借用R1為堆棧指針
DECR1DECR1;R1指向被轉(zhuǎn)換數(shù)據(jù)
XCHA,@R1;取被轉(zhuǎn)換數(shù)據(jù)
ANLA,#0FH;取一位十六進制數(shù)
ADDA,#2;所加值為MOVC與DB間字節(jié)數(shù)
MOVCA,@A+PC;查表
XCHA,@R1;1字節(jié)指令,存結(jié)果于堆棧
RET;1字節(jié)指令A(yù)SCTAB:DB30H,31H,32H,33H,34H,35H,36H,37HDB38H,39H,41H,42H,43H,44H,45H,46H
一般說來:當(dāng)相互傳遞的數(shù)據(jù)較少時,采用寄存器傳遞方式可以獲得較快的傳遞速度;當(dāng)相互傳遞的數(shù)據(jù)較多時,宜采用存儲器或堆棧方式傳遞;如果是子程序嵌套時,最好是采用堆棧方式。4.1.4常用程序舉例1.算術(shù)運算程序
1)多字節(jié)數(shù)的加、減運算
80C51單片機的指令系統(tǒng)提供的是字節(jié)運算指令,所以在處理多字節(jié)數(shù)的加減運算時,要合理地運用進位(借位)標(biāo)志。例:多字節(jié)無符號數(shù)的加法。設(shè)兩個N字節(jié)的無符號數(shù)分別存放在內(nèi)部RAM中以DATA1和DATA2開始的單元中。相加后的結(jié)果要求存放在DATA2數(shù)據(jù)區(qū)。
MOVR0,#DATA1;
MOVR1,#DATA2;
MOVR7,#N; 置字節(jié)數(shù)
CLRC;LOOP:MOVA,@R0;
ADDCA,@R1;求和
MOV@R1,A;存結(jié)果
INCR0;修改指針
INCR1;
DJNZR7,LOOP;例:多字節(jié)無符號數(shù)的減法。
設(shè)兩個N字節(jié)的無符號數(shù)分別存放在內(nèi)部RAM中以DATA1和DATA2開始的單元中。相減后的結(jié)果要求存放在DATA2數(shù)據(jù)區(qū)。
MOVR0,#DATA1;
MOVR1,#DATA2;
MOVR7,#N;置字節(jié)數(shù)
CLRC;LOOP:MOVA,@R0;
SUBBA,@R1;求差
MOV@R1,A;存結(jié)果
INCR0;修改指針
INCR1;
DJNZR7,LOOP;2)多字節(jié)數(shù)乘法運算例雙字節(jié)無符號數(shù)的乘法。設(shè)雙字節(jié)的無符號被乘數(shù)存放在R3、R2中,乘數(shù)存放在R5、R4中,R0指向積的高位。
主程序段如下:MULTB:MOVR7,#04;結(jié)果單元清0LOOP:MOV@R0,#00H;
DJNZR7,LOOP;
DECR0ACALLBMUL;
SJMP$另有2段子程序:
BMULRADD(在BMUL中被調(diào)用)先看子程序段:
RADD:ADDA,@R0;
MOV@R0,A;
MOVA,B;
INCR0;
ADDCA,@R0;
MOV@R0,A;
INCR0;
MOVA,@R0;
ADDCA,#00H;加進位
MOV@R0,A;
RETBMUL:MOVA,R2;
MOVB,R4;
MULAB;低位乘
ACALLRADD;
MOVA,R2;
MOVB,R5;
MULAB;交叉乘
DECR0;
ACALLRADD;
MOVA,R4;
MOVB,R3;
MULAB;交叉乘
DECR0;
DECR0;
ACALLRADD;
MOVA,R5;
MOVB,R3;
MULAB;高字節(jié)乘
DECR0;
ACALLRADD;
DECR0RET1)十六進制數(shù)與ASCII碼間的轉(zhuǎn)換
十六進制數(shù)與ASCII碼的對應(yīng)關(guān)系如表所示。當(dāng)十六進制數(shù)在0~9之間時,其對應(yīng)的ASCII碼值為該十六進制數(shù)加30H;當(dāng)十六進制數(shù)在A~F之間時,其對應(yīng)的ASCII碼值為該十六進制數(shù)加37H。2.碼型轉(zhuǎn)換
例將1位十六進制數(shù)轉(zhuǎn)換成相應(yīng)的ASCII碼。設(shè)十六進制數(shù)存放在R0中,轉(zhuǎn)換后的ASCII碼存放于R2中。實現(xiàn)程序如下:HASC:MOVA,R0;取4位二進制數(shù)
ANLA,#0FH;屏蔽掉高4位
PUSHACC;4位二進制數(shù)入棧
CLRC;清進(借)位位
SUBBA,#0AH;用借位位的狀態(tài)判斷該數(shù)在0~9還是A~F之間
POPACC;彈出原4位二進制數(shù)
JCLOOP;借位位為1,跳轉(zhuǎn)至LOOPADDA,#07H;借位位為0,該數(shù)在A~F之間,加37HLOOP:ADDA,#30H;該數(shù)在0~9之間,加30HMOVR2,A;ASCII碼存于R2RET
例將多位十六進制數(shù)轉(zhuǎn)換成ASCII碼。設(shè)地址指針R0指向十六進制數(shù)低位,R2中存放字節(jié)數(shù),轉(zhuǎn)換后地址指針R0指向十六進制數(shù)的高位。R1指向要存放的ASCII碼的高位地址。實現(xiàn)程序如下:HTASC:MOVA,@R0;取低4位二進制數(shù)
ANLA,#0FH;
ADDA,#15;偏移量修正
MOVCA,@A+PC;查表
MOV@R1,A;存ASCII碼
INCR1;
MOVA,@R0;取十六進制高4位
SWAPAANLA,#0FH;
ADDA,#06H;偏移值修正
MOVCA,@A+PC;
MOV@R1,AINCR0;指向下一單元
INCR1;
DJNZR2,HTASC;字節(jié)數(shù)存于R2RETASCTAB:DB30H,31H,32H,33H,34H,35H,36H,37HDB38H,39H,41H,42H,43H,44H,45H,46H2)BCD碼與二進制數(shù)之間的轉(zhuǎn)換在計算機中,十進制數(shù)要用BCD碼來表示。通常,用四位二進制數(shù)表示一位BCD碼,用1個字節(jié)表示2位BCD碼(稱為壓縮型BCD碼)。例雙字節(jié)二進制數(shù)轉(zhuǎn)換成BCD碼。設(shè)(R2R3)為雙字節(jié)二進制數(shù),(R4R5R6)為轉(zhuǎn)換完的壓縮型BCD碼。十進制數(shù)B與一個8位的二進制數(shù)的關(guān)系可以表示為:
只要依十進制運算法則,將bi(i=7,6,……,1,0)按權(quán)相加,就可以得到對應(yīng)的十進制數(shù)B。(逐次得到:b7×20;b7×21+b6×20;b7×22+b6×21+b5×20;…)。DCDTH:CLRA;
MOVR4,A;R4清0MOVR5,A;R5清0MOVR6,A;R6清0MOVR7,#16;計數(shù)初值LOOP:CLRC;
MOVA,R3;
RLCA;
MOVR3,A;R3左移一位并送回
MOVA,R2;
RLCA;
MOVR2,A;R2左移一位并送回
MOVA,R6;
ADDCA,R6;
DAA;
MOVR6,A;(R6)乘2并調(diào)整后送回
MOVA,R5;
ADDCA,R5;
DAA;
MOVR5,A;(R5)乘2并調(diào)整后送回
MOVA,R4;
ADDCA,R4;
DAA;
MOVR4,A;(R4)乘2并調(diào)整后送回
DJNZR7,LOOP;4.2C51程序設(shè)計方法4.2.1C語言的特點及程序結(jié)構(gòu)
1.C語言的特點語言簡潔、緊湊,使用方便、靈活。運算符豐富。數(shù)據(jù)結(jié)構(gòu)豐富。具有現(xiàn)代化語言的各種數(shù)據(jù)結(jié)構(gòu)。可進行結(jié)構(gòu)化程序設(shè)計??梢灾苯訉τ嬎銠C硬件進行操作。生成的目標(biāo)代碼質(zhì)量高,程序執(zhí)行效率高。可移植性好。2.C語言的程序結(jié)構(gòu)C語言程序采用函數(shù)結(jié)構(gòu),每個C語言程序由一個或多個函數(shù)組成,在這些函數(shù)中至少應(yīng)包含一個主函數(shù)main(),也可以包含一個main()函數(shù)和若干個其它的功能函數(shù)。不管main()函數(shù)放于何處,程序總是從main()
函數(shù)開始執(zhí)行,執(zhí)行到main()函數(shù)結(jié)束則結(jié)束。在main()函數(shù)中調(diào)用其它函數(shù),其它函數(shù)也可以相互調(diào)用,但main()函數(shù)只能調(diào)用其它的功能函數(shù),而不能被其它的函數(shù)所調(diào)用。功能函數(shù)可以是C語言編譯器提供的庫函數(shù),也可以是由用戶定義的自定義函數(shù)。在編制C程序時,程序的開始部分一般是預(yù)處理命令、函數(shù)說明和變量定義等。3.C語言程序結(jié)構(gòu)一般如下:預(yù)處理命令include<>函數(shù)說明longfun1()floatfun2();
int
x,y;floatz;功能函數(shù)主函數(shù)功能函數(shù)功能函數(shù)1fun1(){
函數(shù)體…}主函數(shù)
main(){
主函數(shù)體…}功能函數(shù)2fun2(){
函數(shù)體…}4.2.2C51的數(shù)據(jù)類型
C51的數(shù)據(jù)類型分為基本數(shù)據(jù)類型和組合數(shù)據(jù)類型,情況與標(biāo)準(zhǔn)C中的數(shù)據(jù)類型基本相同,但其中char型與short型相同,float型與double型相同,另外,C51中還有專門針對于MCS-51單片機的特殊功能寄存器型和位類型。1.字符型char
有signedchar和unsignedchar之分,默認(rèn)為signedchar。它們的長度均為一個字節(jié),用于存放一個單字節(jié)的數(shù)據(jù)。對于signedchar,它用于定義帶符號字節(jié)數(shù)據(jù),其字節(jié)的最高位為符號位,“0”表示正數(shù),“1”表示負(fù)數(shù),補碼表示,所能表示的數(shù)值范圍是-128~+127;對于unsignedchar,它用于定義無符號字節(jié)數(shù)據(jù)或字符,可以存放一個字節(jié)的無符號數(shù),其取值范圍為0~255。unsignedchar可以用來存放無符號數(shù),也可以存放西文字符,一個西文字符占一個字節(jié),在計算機內(nèi)部用ASCII碼存放。2.int整型分singedint和unsignedint。默認(rèn)為signedint。它們的長度均為兩個字節(jié),用于存放一個雙字節(jié)數(shù)據(jù)。對于signedint,用于存放兩字節(jié)帶符號數(shù),補碼表示,數(shù)的范疇為-32768~+32767。對于unsignedint,用于存放兩字節(jié)無符號數(shù),數(shù)的范圍為0~65535。3.long長整型分singedlong和unsignedlong。默認(rèn)為signedlong。它們的長度均為四個字節(jié),用于存放一個四字節(jié)數(shù)據(jù)。對于signedlong,用于存放四字節(jié)帶符號數(shù),補碼表示,數(shù)的范疇為-2147483648~+2147483647。對于unsignedlong,用于存放四字節(jié)無符號數(shù),數(shù)的范圍為0~4294967295。4.float浮點型
float型數(shù)據(jù)的長度為四個字節(jié),格式符合IEEE-754標(biāo)準(zhǔn)的單精度浮點型數(shù)據(jù),包含指數(shù)和尾數(shù)兩部分,最高位為符號位,“1”表示負(fù)數(shù),“0”表示正數(shù),其次的8位為階碼,最后的23位為尾數(shù)的有效數(shù)位,由于尾數(shù)的整數(shù)部分隱含為“1”,所以尾數(shù)的精度為24位。5.指針型指針型本身就是一個變量,在這個變量中存放的指向另一個數(shù)據(jù)的地址。這個指針變量要占用一定的內(nèi)存單元,對不同的處理器其長度不一樣,在C51中它的長度一般為1~3個字節(jié)。6.特殊功能寄存器型這是C51擴充的數(shù)據(jù)類型,用于訪問MCS-51單片機中的特殊功能寄存器數(shù)據(jù),它分sfr和sfr16兩種類型,其中sfr為字節(jié)型特殊功能寄存器類型,占一個內(nèi)存單元,利用它可以訪問MCS-51內(nèi)部的所有特殊功能寄存器;sfr16為雙字節(jié)型特殊功能寄存器類型,占用兩個字節(jié)單元,利用它可以訪問MCS-51內(nèi)部的所有兩個字節(jié)的特殊功能寄存器。在C51中對特殊功能寄存器的訪問必須先用sfr或sfr16進行聲明。7.位類型這也是C51中擴充的數(shù)據(jù)類型,用于訪問MCS-51單片機中的可尋址的位單元。在C51中,支持兩種位類型:bit型和sbit型。它們在內(nèi)存中都只占一個二進制位,其值可以是“1”或“0”。其中用bit定義的位變量在C51編譯器編譯時,在不同的時候位地址是可以變化的,而用sbit定義的位變量必須與MCS-51單片機的一個可以尋址位單元或可位尋址的字節(jié)單元中的某一位聯(lián)系在一起,在C51編譯器編譯時,其對應(yīng)的位地址是不可變化的?;緮?shù)據(jù)類型長度取值范圍unsignedchar1字節(jié)0~255signedchar1字節(jié)-128~+127unsignedint2字節(jié)0~65535signedint2字節(jié)-32768~+32767unsignedlong4字節(jié)0~4294967295signedlong4字節(jié)-2147483648~+2147483647float4字節(jié)1.175494E-38~3.402823E+38bit1位0或1Sbit1位0或1sfr1字節(jié)0~255sfr162字節(jié)0~65535在C51語言程序中,有可能會出現(xiàn)在運算中數(shù)據(jù)類型不一致的情況。C51允許任何標(biāo)準(zhǔn)數(shù)據(jù)類型的隱式轉(zhuǎn)換,隱式轉(zhuǎn)換的優(yōu)先級順序如下:bitcharintlongfloatsignedunsigned也就是說,當(dāng)char型與int型進行運算時,先自動對char型擴展為int型,然后與int型進行運算,運算結(jié)果為int型。C51除了支持隱式類型轉(zhuǎn)換外,還可以通過強制類型轉(zhuǎn)換符“()”對數(shù)據(jù)類型進行人為的強制轉(zhuǎn)換。C5l編譯器除了能支持以上這些基本數(shù)據(jù)類型之外,還能支持一些復(fù)雜的組合型數(shù)據(jù)類型,如數(shù)組類型、指針類型、結(jié)構(gòu)類型、聯(lián)合類型等這些復(fù)雜的數(shù)據(jù)類型,在本書的后面將相繼介紹。4.2.351的運算量
1.常量常量是指在程序執(zhí)行過程中其值不能改變的量。在C51中支持整型常量、浮點型常量、字符型常量和字符串型常量。
整型常量:整型常量也就是整型常數(shù),根據(jù)其值范圍在計算機中分配不同的字節(jié)數(shù)來存放。在C51中它可以表示成以下幾種形式:十進制整數(shù)。如234、-56、0等。十六進制整數(shù)。以0x開頭表示,如0x12表示十六進制數(shù)12H。長整數(shù)。在C51中當(dāng)一個整數(shù)的值達到長整型的范圍,則該數(shù)按長整型存放,在存儲器中占四個字節(jié),另外,如一個整數(shù)后面加一個字母L,這個數(shù)在存儲器中也按長整型存放。如123L在存儲器中占四個字節(jié)。浮點型常量:浮點型常量也就是實型常數(shù)。有十進制表示形式和指數(shù)表示形式。十進制表示形式又稱定點表示形式,由數(shù)字和小數(shù)點組成。如0.123、34.645等都是十進制數(shù)表示形式的浮點型常量。指數(shù)表示形式為:[]數(shù)字[.數(shù)字]e[]數(shù)字例如:123.456e-3、-3.123e2等都是指數(shù)形式的浮點型常量。字符型常量:字符型常量是用單引號引起的字符,如‘a(chǎn)’、‘1’、‘F’等??梢允强娠@示的ASCII字符,也可以是不可顯示的控制字符。對不可顯示的控制字符須在前面加上反斜杠“\”組成轉(zhuǎn)義字符。利用它可以完成一些特殊功能和輸出時的格式控制。常用的轉(zhuǎn)義字符如表4-2所示。轉(zhuǎn)義字符含
義ASCII碼(十六進制數(shù))\o空字符(null)00H\n換行符(LF)0AH\r回車符(CR)0DH\t水平制表符(HT)09H\b退格符(BS)08H\f換頁符(FF)0CH\‘單引號27H\”雙引號22H\\反斜杠5CH字符串型常量:字符串型常量由雙引號“”括起的字符組成。如“D”、“1234”、“ABCD”等。注意字符串常量與字符常量是不一樣,一個字符常量在計算機內(nèi)只用一個字節(jié)存放,而一個字符串常量在內(nèi)存中存放時不僅雙引號內(nèi)的字符一個占一個字節(jié),而且系統(tǒng)會自動的在后面加一個轉(zhuǎn)義字符“\o”作為字符串結(jié)束符。因此不要將字符常量和字符串常量混淆,如字符常量‘A’和字符串常量“A”是不一樣的。2變量變量是在程序運行過程中其值可以改變的量。一個變量由兩部分組成:變量名和變量值。在C51中,變量在使用前必須對變量進行定義,指出變量的數(shù)據(jù)類型和存儲模式。以便編譯系統(tǒng)為它分配相應(yīng)的存儲單元。定義的格式如下:
[存儲種類]數(shù)據(jù)類型說明符[存儲器類型]變量名1[=初值],變量名2[初值]…;數(shù)據(jù)類型說明符:在定義變量時,必須通過數(shù)據(jù)類型說明符指明變量的數(shù)據(jù)類型,指明變量在存儲器中占用的字節(jié)數(shù)??梢允腔緮?shù)據(jù)類型說明符,也可以是組合數(shù)據(jù)類型說明符,還可以是用typedef定義的類型別名。在C51中,為了增加程序的可讀性,允許用戶為系統(tǒng)固有的數(shù)據(jù)類型說明符用typedef起別名,格式如下:
typedefc51固有的數(shù)據(jù)類型說明符別名;定義別名后,就可以用別名代替數(shù)據(jù)類型說明符對變量進行定義。別名可以用大寫,也可以用小寫,為了區(qū)別一般用大寫字母表示?!纠?-1】
typedef的使用。typedefunsignedintWORD;typedefunsignedcharBYTE;BYTEa1=0x12;WORDa2=0x1234;變量名:變量名是C51區(qū)分不同變量,為不同變量取的名稱。在C51中規(guī)定變量名可以由字母、數(shù)字和下劃線三種字符組成,且第一個字母必須為字母或下劃線。變量名有兩種:普通變量名和指針變量名。它們的區(qū)別是指針變量名前面要帶“*”號。存儲種類:存儲種類是指變量在程序執(zhí)行過程中的作用范圍。C51變量的存儲種類有四種,分別是自動(auto)、外部(extern)、靜態(tài)(static)和寄存器(register)。auto:使用auto定義的變量稱為自動變量,其作用范圍在定義它的函數(shù)體或復(fù)合語句內(nèi)部,當(dāng)定義它的函數(shù)體或復(fù)合語句執(zhí)行時,C51才為該變量分配內(nèi)存空間,結(jié)束時占用的內(nèi)存空間釋放。自動變量一般分配在內(nèi)存的堆??臻g中。定義變量時,如果省略存儲種類,則該變量默認(rèn)為自動(auto)變量。extern:使用extern定義的變量稱為外部變量。在一個函數(shù)體內(nèi),要使用一個已在該函數(shù)體外或別的程序中定義過的外部變量時,該變量在該函數(shù)體內(nèi)要用extern說明。外部變量被定義后分配固定的內(nèi)存空間,在程序整個執(zhí)行時間內(nèi)都有效,直到程序結(jié)束才釋放。static:使用static定義的變量稱為靜態(tài)變量。它又分為內(nèi)部靜態(tài)變量和外部靜態(tài)變量。在函數(shù)體內(nèi)部定義的靜態(tài)變量為內(nèi)部靜態(tài)變量,它在對應(yīng)的函數(shù)體內(nèi)有效,一直存在,但在函數(shù)體外不可見,這樣不僅使變量在定義它的函數(shù)體外被保護,還可以實現(xiàn)當(dāng)離開函數(shù)時值不被改變。外部靜態(tài)變量上在函數(shù)外部定義的靜態(tài)變量。它在程序中一直存在,但在定義的范圍之外是不可見的。如在多文件或多模塊處理中,外部靜態(tài)變量只在文件內(nèi)部或模塊內(nèi)部有效。register:使用register定義的變量稱為寄存器變量。它定義的變量存放在CPU內(nèi)部的寄存器中,處理速度快,但數(shù)目少。C51編譯器編譯時能自動識別程序中使用頻率最高的變量,并自動將其作為寄存器變量,用戶可以無需專門聲明。3.存儲器類型存儲器類型是用于指明變量所處的單片機的存儲器區(qū)域情況。存儲器類型與存儲種類完全不同。C51編譯器能識別的存儲器類型有以下幾種,見表所示。存儲器類型描
述
data直接尋址的片內(nèi)RAM低128B,訪問速度快
bdata片內(nèi)RAM的可位尋址區(qū)(20H~2FH),允許字節(jié)和位混合訪問
idata間接尋址訪問的片內(nèi)RAM,允許訪問全部片內(nèi)RAM
pdata用Ri間接訪問的片外RAM的低256B
xdata用DPTR間接訪問的片外RAM,允許訪問全部64k片外RAM
code程序存儲器ROM64k空間定義變量時也可以省“存儲器類型”,省時C51編譯器將按編譯模式默認(rèn)存儲器類型,具體編譯模式的情況在后面介紹?!纠?-2】變量定義存儲種類和存儲器類型相關(guān)情況。
chardatavarl;/*在片內(nèi)RAM低128B定義用直接尋址方式訪問的字符型變量var1*/
int
idatavar2;/*在片內(nèi)RAM256B定
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 有機化學(xué)原料的廢棄物處理與資源化考核試卷
- 智能服務(wù)機器人技術(shù)創(chuàng)新考核試卷
- 機械式停車設(shè)備故障預(yù)防與診斷技巧考核試卷
- 木材采運的數(shù)字化轉(zhuǎn)型與智能化考核試卷
- 中介居間費合同范本
- 房主房子出租合同范本
- 維修農(nóng)村管道合同范本
- 畜牧產(chǎn)品加工與供應(yīng)合作協(xié)議
- 物聯(lián)網(wǎng)技術(shù)應(yīng)用研發(fā)生產(chǎn)合同書
- 電信運營商合作協(xié)議具體內(nèi)容
- 廣東義務(wù)教育標(biāo)準(zhǔn)化學(xué)校
- 煤質(zhì)化驗員測試題(附參考答案)
- 全電發(fā)票樣式
- (完整版)供應(yīng)商審核表
- 饅頭工藝流程圖
- (二次供水單位)生活飲用水衛(wèi)生許可證延續(xù)申請表
- 鈉電池正極材料PPT
- 體能訓(xùn)練概論(NSCA)
- 青島版三年級數(shù)學(xué)下冊《美麗的街景》教學(xué)課件7
- 液壓傳動全套ppt課件(完整版)
- 內(nèi)部控制五要素圖解
評論
0/150
提交評論