單片機(jī)匯編語言程序設(shè)計(jì)_第1頁
單片機(jī)匯編語言程序設(shè)計(jì)_第2頁
單片機(jī)匯編語言程序設(shè)計(jì)_第3頁
單片機(jī)匯編語言程序設(shè)計(jì)_第4頁
單片機(jī)匯編語言程序設(shè)計(jì)_第5頁
已閱讀5頁,還剩60頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

第4章匯編語言程序設(shè)計(jì)4-1匯編程序約定4-2匯編程序設(shè)計(jì)步驟4-3順序程序4-4分支程序4-5循環(huán)程序4-6算術(shù)運(yùn)算程序2024/4/191

4-1

匯編程序約定匯編語言程序:用匯編語言編寫的、完成特定功能的指令序列。匯編程序:

能將匯編語言源程序轉(zhuǎn)換成機(jī)器語言目標(biāo)程序的系統(tǒng)軟件。

匯編語言程序到機(jī)器語言程序的轉(zhuǎn)換過程稱為匯編。1、手工匯編:人工查指令表匯編。用于設(shè)計(jì)短小程序或調(diào)試程序的場合。2、機(jī)器匯編:用匯編程序進(jìn)行匯編。2024/4/192源程序使用機(jī)器匯編要考慮匯編程序的約定:1)按指令格式和語法規(guī)則編寫程序。常數(shù)的表示: 十進(jìn)制數(shù):20 十六進(jìn)制數(shù):87H,0F0H

二進(jìn)制數(shù):01011001B

字符: ‘H’

字符串: “Hello”。

2)使用偽指令提供匯編信息。2024/4/193匯編的主要任務(wù):1)確定程序中每條匯編語言指令的指令機(jī)器碼。2)確定每條指令在存儲器中的存放地址。3)提供錯(cuò)誤信息。 4)提供目標(biāo)執(zhí)行文件(*.OBJ/*.HEX)和列表文件(*.LST)。匯編語言的語句格式

語句行由四個(gè)字段組成:

[標(biāo)號:]操作碼[操作數(shù)][;注釋]

括號內(nèi)的部分可以根據(jù)實(shí)際情況取舍。每個(gè)字段之間要用分隔符分隔,可以用作分隔符的符號有空格、冒號、逗號、分號等。如:LOOP:MOVA,#7FH;A←7FH2024/4/194一、標(biāo)號標(biāo)號是語句地址的標(biāo)志符號,用于引導(dǎo)對該語句的非順序訪問。有關(guān)標(biāo)號的規(guī)定為:標(biāo)號由1~8個(gè)ASCII字符組成。第一個(gè)字符必須是字母,其余字符可以是字母、數(shù)字或其他特定字符;不能使用該匯編語言已經(jīng)定義了的符號作為標(biāo)號。如指令助記符、寄存器符號名稱等;標(biāo)號后邊必須跟冒號。二、操作碼操作碼用于規(guī)定語句執(zhí)行的操作。它是匯編語句中唯一不能空缺的部分。它由指令助記符表示。

2024/4/195三、操作數(shù)操作數(shù)用于給指令的操作提供數(shù)據(jù)或地址。在一條匯編語句中操作數(shù)可能是空缺的,也可能包括一項(xiàng),還可能包括兩項(xiàng)或三項(xiàng)。各操作數(shù)間以逗號分隔。操作數(shù)字段的內(nèi)容可能包括以下幾種情況:(1)工作寄存器名;(2)特殊功能寄存器名;(3)標(biāo)號名;(4)常數(shù);(5)符號“$”,表示程序計(jì)數(shù)器PC的當(dāng)前值;(6)表達(dá)式。2024/4/196四、注釋

注釋不屬于匯編語句的功能部分,它只是對語句的說明。注釋字段可以增加程序的可讀性,有助于編程人員的閱讀和維護(hù)。注釋字段必須以分號“;”開頭,長度不限,當(dāng)一行書寫不下時(shí),可以換行接著書寫,但換行時(shí)應(yīng)注意在開頭使用分號“;”。匯編語言指令類型:

1.機(jī)器指令:

指令系統(tǒng)中的全部指令,每條指令有對應(yīng)的機(jī)器代碼。2.偽指令:

匯編控制指令,僅提供匯編信息,沒有指令代碼。2024/4/1973.宏指令:

宏匯編功能:將需要多次反復(fù)執(zhí)行的程序段定義成一個(gè)宏指令名(宏定義),編程時(shí),可在程序中使用宏指令名來替代一段程序(宏調(diào)用)。宏定義過程:宏指令名MACRO

形式參數(shù) … ;定義程序段

ENDM宏調(diào)用過程: … 宏指令名實(shí)際參數(shù) … 宏指令名實(shí)際參數(shù)2024/4/198二、匯編控制指令(偽指令):偽指令是放在匯編語言源程序中用于指示匯編程序如何對源程序進(jìn)行匯編的指令,它不同于指令系統(tǒng)中的指令,指令系統(tǒng)中的指令在匯編程序匯編時(shí)能夠產(chǎn)生相應(yīng)的指令代碼,而偽指令在匯編程序匯編時(shí)不會產(chǎn)生代碼,只是對匯編過程進(jìn)行相應(yīng)的控制和說明。偽指令通常在匯編語言源程序中用于定義數(shù)據(jù)、分配存儲空間、控制程序的輸入輸出等。MCS-51匯編語言源程序相對于一般的微型計(jì)算機(jī)匯編語言源程序結(jié)構(gòu)簡單,偽指令數(shù)目少,常用的偽指令只有幾條。2024/4/1991.ORG—起始地址指令:指明程序和數(shù)據(jù)塊起始地址。該指令的功能是向匯編程序說明下面緊接的程序段或數(shù)據(jù)段存放的起始地址。表達(dá)式通常為16進(jìn)制地址,也可以是已定義的標(biāo)號地址。常用偽指令及其功能:

ORG8000HSTART:MOVA,#30H……

此時(shí)規(guī)定該段程序的機(jī)器碼從地址8000H單元開始存放。在每一個(gè)匯編語言源程序的開始,都要設(shè)置一條ORG偽指令來指定該程序在存儲器中存放的起始位置。若省略O(shè)RG偽指令,則該程序段從0000H單元開始存放。在一個(gè)源程序中,可以多次使用ORG偽指令規(guī)定不同程序段或數(shù)據(jù)段存放的起始地址,但要求地址值由小到大依序排列,不允許空間重疊。2024/4/19102.DB偽指令格式:[標(biāo)號:]DB項(xiàng)或項(xiàng)表

DB偽指令用于定義字節(jié)數(shù)據(jù),可以定義一個(gè)字節(jié),也可定義多個(gè)字節(jié),字義多個(gè)字節(jié)時(shí),兩兩之間用逗號間隔,定義的多個(gè)字節(jié)在存儲器中是連續(xù)存放的。定義的字節(jié)可以是一般常數(shù),也可以為字符,還可以是字符串,字符和字符串以引號括起來,字符數(shù)據(jù)在存儲器中以ASCII碼形式存放。在定義時(shí)前面可以帶標(biāo)號,定義的標(biāo)號在程序中是起始單元的地址?!纠?-19】ORG3000HTAB1:DB12H,34HDB'5','A','abc'匯編后,各個(gè)數(shù)據(jù)在存儲單元中的存放情況如下:12H34H35H41H61H62H63H3000H3001H3002H3003H3004H3005H3006H2024/4/19113.DW偽指令格式:[標(biāo)號:]DW項(xiàng)或項(xiàng)表這條指令與DB相似,但用于定義字?jǐn)?shù)據(jù)。項(xiàng)或項(xiàng)表指所定義的一個(gè)字在存儲器中占兩個(gè)字節(jié)。匯編時(shí),機(jī)器自動(dòng)按低字節(jié)在前,高字節(jié)在后,即低字節(jié)存放在低地址單元,高字節(jié)存放在高地址單元?!纠?-20】ORG3000HTAB2:DW1234H,5678H匯編后,各個(gè)數(shù)據(jù)在存儲單元中的存放情況如下:34H12H78H56H3000H3001H3002H3003H2024/4/19124.DS偽指令格式:[標(biāo)號:]DS數(shù)值表達(dá)式該偽指令用在存儲器中保留一定數(shù)量的字節(jié)單元。保留存貯空間主要為以后存放數(shù)據(jù)。保留的字節(jié)單元數(shù)由表達(dá)式的值決定。【例3-21】ORG2000HTAB1:DB12H,34HDS4HDB'5'匯編后,存儲單元中的分配情況如下:12H34H----35H3000H3001H3002H3003H3004H3005H3006H2024/4/19135.EQU偽指令格式:符號EQU項(xiàng)該偽指令的功能是將指令中的項(xiàng)的值賦予EQU前面的符號。項(xiàng)可以是常數(shù)、地址標(biāo)號或表達(dá)式。以后可以通過使用該符號使用相應(yīng)的項(xiàng)?!纠?-22】TAB1EQU1000HTAB2EQU2000H匯編后TAB1、TAB2分別等于1000H、2000H。程序后面使用1000H、2000H的地方就可以用符號TAB1、TAB2替換。用EQU偽指令對某標(biāo)號賦值后,該符號的值在整個(gè)程序中不能再改變。2024/4/19147.END偽指令格式:END

該指令放于程序最后位置,用于指明匯編語言源程序的結(jié)束位置,當(dāng)匯編程序匯編到END偽指令時(shí),匯編結(jié)束。END后面的指令,匯編程序都不予處理。一個(gè)源程序只能有一個(gè)END命令,否則就有一部分指令不能被匯編。6.bit偽指令格式:符號bit位地址bit該偽指令用于給位地址賦予符號,經(jīng)賦值后可用該符號代替bit后面的位地址?!纠?-23】FLGbitF0AIbit P1.0定義后,在程序中位地址F0、P1.0就可以通過FLG和AI來使用。2024/4/19154-2匯編語言程序設(shè)計(jì)步驟一、確定方案和計(jì)算方法;二、了解應(yīng)用系統(tǒng)的硬件配置、性能指標(biāo);三、建立系統(tǒng)數(shù)學(xué)模型,確定控制算法和操作步驟;四、畫程序流程圖;表示程序結(jié)構(gòu)和程序功能。五、編制源程序。1.合理分配存儲器單元和了解I/O接口地址。2.按功能設(shè)計(jì)程序,明確各程序之間的相互關(guān)系。3.用注釋行說明程序,便于閱讀、修改和調(diào)試。2024/4/1916常用程序結(jié)構(gòu):4-3順序程序順序程序是指無分支、無循環(huán)結(jié)構(gòu)的程序。其執(zhí)行流程是依指令在存儲器中的存放順序進(jìn)行的。順序程序又稱簡單程序,程序走向只有一條路徑。例:雙字節(jié)變補(bǔ)程序(設(shè)數(shù)據(jù)在R4R5中): MOV A,R5

;取低字節(jié) CPL A ADD A,#01H ;低字節(jié)變補(bǔ) MOV R5,A MOV A,R4

;取高字節(jié) CPL A ADDCA,#00H ;高字節(jié)變補(bǔ) MOV R4,A

順序程序、分支程序、循環(huán)程序。

2024/4/1917例題(順序)[例4.1]

三字節(jié)無符號數(shù)相加,其中被加數(shù)在內(nèi)部RAM的50H、51H和52H單元中;加數(shù)在內(nèi)部RAM的53H、54H和55H單元中;要求把相加之和存放在50H、51H和52H單元中,進(jìn)位存放在位尋址區(qū)的00H位中。低字節(jié)低字節(jié)中字節(jié)中字節(jié)高字節(jié)高字節(jié)高字節(jié)高字節(jié)低字節(jié)低字節(jié)R0→R1→2024/4/1918MOV R0,#52HMOV R1,#55HMOV A,@R0ADD A,@R1MOV @R0,ADEC R0DEC R1MOV A,@R0ADDC A,@R1MOV @R0,ADEC R0DEC R1MOV A,@R0ADDC A,@R1MOV @R0,ACLR AADDC A,#00HMOV R0,#00HMOV @R0,A;被加數(shù)的低字節(jié)地址;加數(shù)的低字節(jié)地址;低字節(jié)相加;存低字節(jié)相加結(jié)果;中間字節(jié)帶進(jìn)位相加;存中間字節(jié)相加結(jié)果;高字節(jié)帶進(jìn)位相加;存高字節(jié)相加結(jié)果;存放進(jìn)位的單元地址;進(jìn)位送00H位保存程序:MOV C,ACC.0MOV 00H,CMOV R0,#20HMOV @R0,A2024/4/1919例:壓縮式BCD碼分解成為單字節(jié)BCD碼。MOV R0,#40H ;設(shè)指針MOV A,@R0

;取一個(gè)字節(jié)MOV R2,A ;暫存ANL A,#0FH ;高半字節(jié)清0INC R0MOV @R0,A ;保存數(shù)據(jù)個(gè)位MOV A,R2SWAPA ;十位換到低半字節(jié)ANL A,#0FHINC R0MOV @R0,A ;保存數(shù)據(jù)十位十個(gè)2024/4/19204-4 分支程序

4-4-1 單重分支程序一個(gè)判斷決策框,程序有兩條出路。兩種分支結(jié)構(gòu):例:求R2中補(bǔ)碼絕對值:正數(shù)不變,負(fù)數(shù)變補(bǔ)。

MOVA,R2 JNBACC.7,NEXT;為正數(shù)?為0跳

CPLA ;負(fù)數(shù)變補(bǔ)

INCA MOVR2,ANEXT:SJMPNEXT;結(jié)束由條件轉(zhuǎn)移指令構(gòu)成程序判斷框部分,形成程序分支結(jié)構(gòu)。2024/4/1921P85:例題(單分支)[例4.2]假定在外部RAM中有ST1、ST2和ST3共3個(gè)連續(xù)單元,其中ST1和ST2單元中分別存放著兩個(gè)8位無符號二進(jìn)制數(shù),要求找出其中的大數(shù)并存入ST3

單元中。START:CLRC MOVDPTR,#ST1MOVXA,@DPTRMOVR2,AINCDPTR MOVXA,@DPTRSUBBA,R2JNCBIG1XCHA,R2BIG0:INCDPTRMOVX@DPTR,ARETBIG1:MOVXA,@DPTRSJMPBIG0;進(jìn)位位清“0”;設(shè)置數(shù)據(jù)指針,指向ST1;取第一個(gè)數(shù);第一個(gè)數(shù)存R2;數(shù)據(jù)指針加1,指向ST2;取第二個(gè)數(shù);兩數(shù)比較(第二個(gè)數(shù)-第一個(gè)數(shù));第二個(gè)數(shù)大轉(zhuǎn)BIG1(C=0無借位跳);第一個(gè)數(shù)大整字節(jié)交換繼續(xù);指向ST3單元;存大數(shù)2024/4/1922例:FRT:MOVA,40H ;取行李重量計(jì)價(jià)單位G MOVR3,A MOVB,#03H ;M=G×3 MULAB MOVR2,A ;暫存3G MOVA,R3

;取回G CJNEA,#05H,L1;G=5?G≠5跳L1 SJMPWETC L1:JCWETC ;是,轉(zhuǎn)至WETC(C=1即G<5跳) SUBBA,#05H ;否則M=3G+2(G-5)

RLCA ADDA,R2

SJMPL2WETC:MOVA,R2L2:MOV41H,A ;存結(jié)果M RETG=5?=:跳WETC

≠:G<5:跳WETC

G>5:順序執(zhí)行行李計(jì)價(jià):當(dāng)G≤5,M=G×3;

當(dāng)G>5,M=G×3+(G-5)×(5-3)。2024/4/1923例求雙字節(jié)補(bǔ)碼。設(shè)在內(nèi)部RAM的addr1和addr+1單元存有一個(gè)雙字節(jié)數(shù)(高位字節(jié)存于高地址單元)。編寫程序?qū)⑵渥x出取補(bǔ)后再存入addr2和addr2+1單元。首先對低字節(jié)取補(bǔ),然后判其結(jié)果是否為全“0”。若是,則高字節(jié)取補(bǔ),否則高字節(jié)取反。

START:MOVR0,#addr1;原碼低字節(jié)地址送R0 MOVR1,#addr2;補(bǔ)碼低字節(jié)地址送R1 MOVA,@R0;原碼低字節(jié)送A CPLA;A內(nèi)容取補(bǔ)

INCAMOV@R1,A;存補(bǔ)碼低字節(jié)

INCR0;調(diào)整地址,指向下一單元

INCR1JZZERO;(A)=0時(shí)轉(zhuǎn)ZEROMOVA,@R0;原碼高字節(jié)送A CPLAMOV@R1,A;高字節(jié)反碼存入addr2+1單元

SJMPLOOP1ZERO:MOVA,@R0;高字節(jié)取補(bǔ)存入addr2+1單元

CPLAINCAMOV@R1,ALOOP1:RET2024/4/19244-4-2多重分支程序例:求符號函數(shù)Y=SGN(X)

+1(當(dāng)X>0)SGN(X)=0(當(dāng)X=0)-1(當(dāng)X<0)SYMB:MOVA,40H ;取X JZ STOR ;X=0跳,Y=X JB ACC.7,MINUS;X<0(A.7=1跳)MOVA,#01H ;X>0,Y=+1SJMPSTORMINUS:MOVA,#0FFH

;X<0,Y=-1STOR:MOV41H,A ;保存YRET一、多次使用條件轉(zhuǎn)移指令,形成兩個(gè)以上判斷框。2024/4/1925溫控系統(tǒng)結(jié)構(gòu)框圖電熱箱采用電熱絲加熱,由雙向可控硅控制加熱量的大??;溫度傳感器檢測電熱箱內(nèi)的溫度,經(jīng)放大與A/D轉(zhuǎn)換后進(jìn)入單片機(jī);單片機(jī)將設(shè)定的溫度值與檢測到的電熱箱中的實(shí)際溫度進(jìn)行比較,并調(diào)節(jié)運(yùn)算后,發(fā)出控制信號經(jīng)光電隔離器去驅(qū)動(dòng)雙向可控硅以調(diào)節(jié)加在電熱絲的電壓,從而控制電熱箱的溫度。電熱箱單片機(jī)溫控系統(tǒng)結(jié)構(gòu)框圖2024/4/1926例題(多分支)[例4.3]某溫度控制系統(tǒng),采集的溫度值(Ta)放在累加器A中。此外,在內(nèi)部RAM54H單元存放控制溫度下限值(T54),

在55H單元存放控制溫度上限值(T55)。若Ta>T55,程序轉(zhuǎn)向JW(降溫處理子程序);

若Ta<T54,則程序轉(zhuǎn)向SW(升溫處理子程序);

若T55≥Ta≥T54,則程序轉(zhuǎn)向FH(返回主程序)。

=:去FH思路:Ta=T55?≠:Ta>T55:去JW

Ta<T55:Ta=T54?=:去FH

≠:Ta<T54:去SW

Ta>T54:去FH算法:(1)Ta>T55:去JW

(2)Ta<T54:去SW

(3)T55≥Ta≥T54:去FH2024/4/1927程序:

CJNEA,55H,LOOP1 AJMPFHLOOP1:JNCJWCJNEA,54H,LOOP2AJMPFHLOOP2:JCSWFH:RET;Ta

≠T55:轉(zhuǎn)向LOOP1;Ta=T55:返回;若CY=0,表明Ta>T55,轉(zhuǎn)降溫處理程序;Ta

≠T54:轉(zhuǎn)向LOOP2;Ta=T54:返回;若CY=1,表明Ta<T54,轉(zhuǎn)升溫處理程序;T55≥Ta≥T54,返回主程序若Ta>T55,程序轉(zhuǎn)向JW(降溫處理子程序);若Ta<T54,則程序轉(zhuǎn)向SW(升溫處理子程序);若T55≥Ta≥T54,則程序轉(zhuǎn)向FH(返回主程序)。2024/4/1928二、按分支號轉(zhuǎn)移。如:當(dāng)分支號=0,程序轉(zhuǎn)移到ADDR0處;當(dāng)分支號=1,程序轉(zhuǎn)移到ADDR1處;…。[例4.4]有BR0、BR1、BR2和BR3共4個(gè)分支程序段,各分支程序段的功能依次是從內(nèi)部RAM256B范圍取數(shù)、從外部RAM低256B范圍取數(shù)、從外部RAM4KB范圍取數(shù)和從外部RAM64KB范圍取數(shù)。并假定R0

中存放取數(shù)地址低8位地址,R1中存放高8位地址,R3中存放分支序號值。假定以BRTAB作差值表首地址,BR0_BRTAB~BR3_BRTAB為差值。

分析:差值表=分支入口地址-該表首址1、利用查地址表法:2024/4/1929

MOV A,R3 MOV DPTR,#BRTAB MOVC A,@A+DPTR JMP @A+DPTRBRTAB: DB BR0_BRTAB DB BR1_BRTAB DB BR2_BRTAB DB BR3_BRTABBR0: MOV A,@R0 SJMP BREBR1: MOVX A,@R0 SJMP BREBR2: MOV A,R1 ANL A,#0FH ANL P2,#0F0H ORL P2,A MOVX A,@R0

SJMP BREBR3: MOV DPL,R0 MOV DPH,R1 MOVX A,@DPTRBRE:SJMP $;分支轉(zhuǎn)移值送A(如R3=2);差值表首址(BRTAB=3000H);查表[A+DPTR=3002H,(A)=40H];轉(zhuǎn)移(A+DPTR=3040H);差值表(=10H)

(=20H)

(=40H)

(=60H);從內(nèi)部RAM取數(shù);從外部RAM256B取數(shù);從外部RAM4KB取數(shù);高位地址取低4位;清P2口低4位;發(fā)高位地址;從外部RAM64KB取數(shù)程序:入口地址:3010H3020H3040H3060H差值表=分支入口地址-該表首址2024/4/1930例題(查轉(zhuǎn)移指令表)[4.5]假定鍵盤上有3個(gè)操作鍵,功能說明如下表: … MOV DPTR,#3000H CLR C RLC A JMP @A+DPTR AJMP DS AJMP XS AJMP CR …

3000H3001H3002H3003H3004H3005H3006H;3000H為基址;進(jìn)位位CY清“0”;A帶進(jìn)位位循環(huán)左移;轉(zhuǎn)操作鍵處理程序;轉(zhuǎn)讀數(shù)據(jù)程序;轉(zhuǎn)寫數(shù)據(jù)程序;轉(zhuǎn)插入程序2、使用轉(zhuǎn)移指令表法。用分支轉(zhuǎn)移指令A(yù)JMP…對AJMP指令應(yīng)將分支序號乘以2,轉(zhuǎn)移范圍為2KB;

對LJMP指令應(yīng)將分支序號乘以3,轉(zhuǎn)移范圍為64KB。2024/4/1931

設(shè)分支號已存入A。把分支程序入口地址存放在表中。MTJS:MOVSP,#30H MOVDPTR,#TAB;取分支入口地址表首地址

CLRC ;分支號×2

RLCA MOVR2,A MOVCA,@A+DPTR;取分支地址低位

PUSHA ;入棧保存

MOVA,R2 INCA MOVCA,@A+DPTR;取分支地址高位

PUSHA ;入棧保存RET ;分支地址→PC,轉(zhuǎn)移TAB:DWADDR0

;分支程序入口地址表

DWADDR1

… ADDR0:… ;程序段0…ADDR1:… ;程序段1…ADDR2:… ;程序段2…3、利用堆棧操作法:如:DPTR=3000H

A=2※※★★★★※※★★※※※※★★PC2024/4/19324-5 循環(huán)程序4-5-1 循環(huán)程序的構(gòu)成各個(gè)環(huán)節(jié)任務(wù):一、初始化部分:循環(huán)準(zhǔn)備工作。如:清結(jié)果單元、設(shè)指針、設(shè)循環(huán)控制變量初值等。二、循環(huán)體:循環(huán)工作部分:需多次重復(fù)處理的工作。循環(huán)控制部分:

1.修改指針和循環(huán)控制變量。2.檢測循環(huán)條件:滿足循環(huán)條件,繼續(xù)循環(huán),否則退出循環(huán)。三、結(jié)束部分:

處理和保存循環(huán)結(jié)果。允許0次循環(huán)的循環(huán)結(jié)構(gòu):在循環(huán)工作之前檢測循環(huán)條件。包含多次重復(fù)執(zhí)行的程序段,循環(huán)結(jié)構(gòu)使程序緊湊。

2024/4/19334-5-2單重循環(huán)簡單循環(huán)結(jié)構(gòu):循環(huán)體中不套循環(huán)。循環(huán)控制方法: 計(jì)數(shù)控制; 特征標(biāo)志控制。2024/4/1934例:求n個(gè)單字節(jié)數(shù)據(jù)的累加,設(shè)數(shù)據(jù)串已在43H起始單元,數(shù)據(jù)串長度在42H單元,累加和不超過2個(gè)字節(jié)。SUM: MOV R0,#42H ;設(shè)指針 MOV A,@R0 MOV R2,A ;循環(huán)計(jì)數(shù)器←n CLR A ;結(jié)果單元清0

MOV R3,AADD1:INC R0

;修改指針 ADD A,@R0

;累加

JNCNEXT ;處理進(jìn)位(C=0跳)

INC R3

;有進(jìn)位,高字節(jié)加1NEXT:DJNZ R2,ADD1 ;循環(huán)控制:數(shù)據(jù)是否加完?

MOV 40H,A ;循環(huán)結(jié)束,保存結(jié)果

MOV 41H,R3 RETR0→2024/4/1935一、計(jì)數(shù)控制:

例:為一串7位ASCII碼數(shù)據(jù)的D7位加上奇校驗(yàn),設(shè)數(shù)據(jù)存放在片外RAM的2101H起始單元,數(shù)據(jù)長度在2100H單元。MOVDPTR,#2100HMOVXA,@DPTRMOVR2,ANEXT:INCDPTRMOVXA,@DPTRORLA,#80HJNBP,PASS;P=0:1的個(gè)數(shù)為偶數(shù),跳MOVX@DPTR,APASS:DJNZR2,NEXTDONE:SJMPDONE設(shè)循環(huán)計(jì)數(shù)器,控制循環(huán)次數(shù)。正計(jì)數(shù)和倒計(jì)數(shù)兩種方式。2024/4/1936二、特征控制:例:找正數(shù)表最小值。正數(shù)表存在片外RAM中以LIST為起始單元,用-1作為結(jié)束標(biāo)志。START:MOVDPTR,#LIST ;數(shù)表首地址

MOVB,#127 ;預(yù)置最小值NEXT:MOVXA,@DPTR ;取數(shù)INCDPTR ;修改指針

CJNEA,#-1,NEXT1 ;是否為數(shù)表結(jié)尾?(A≠-1跳)

SJMPDONE ;循環(huán)結(jié)束NEXT1:CJNEA,B,NEXT2 ;比較(A≠B跳)NEXT2:JNCNEXT ;C=0跳MOVB,A ;保存較小值

SJMPNEXTDONE:SJMPDONE習(xí)題:統(tǒng)計(jì)一班考試為100分和不及格人數(shù),成績單在41H起始單元。設(shè)定循環(huán)結(jié)束標(biāo)志實(shí)現(xiàn)循環(huán)控制。2024/4/19374-5-3多重循環(huán)例:將內(nèi)存一串單字節(jié)無符號數(shù)升序排序步驟:每次取相鄰單元的兩個(gè)數(shù)比較,決定是否需要交換數(shù)據(jù)位置。第一次循環(huán),比較N-1次,取到數(shù)據(jù)表中最大值。第二次循環(huán),比較N-2次,取到次大值?!贜-1次循環(huán):比較一次,排序結(jié)束。循環(huán)體中套循環(huán)結(jié)構(gòu)。以雙重循環(huán)使用較多。2024/4/1938SORT:MOV A,#N-1 ;N個(gè)數(shù)據(jù)排序

MOV R4,A ;外循環(huán)次數(shù)LOOP1:MOV A,R4 MOV R3,A ;內(nèi)循環(huán)次數(shù)

MOV R0,#TAB ;設(shè)數(shù)據(jù)指針LOOP2:MOV A,@R0

;取二數(shù)

MOV B,A INC R0 MOV A,@R0 CJNEA,B,L1 ;比較(A≠B跳)L1:JNC UNEX ;A≥B,不交換

DEC R0

;否則交換數(shù)據(jù)

XCH A,@R0 INC R0 MOV @R0,AUNEX:DJNZR3,LOOP2 ;內(nèi)循環(huán)結(jié)束?

DJNZR4,LOOP1 ;外循環(huán)結(jié)束?

RET2024/4/19391、單循環(huán)定時(shí)程序:

(參看P88)

MOV R5,#TIME LOOP: NOP NOP DJNZR5,LOOP軟件延時(shí)程序:1T1T1T2T設(shè):fOSC=6MHz,

則T=12/6MHz=2

s

t=(1+4×TIME)×T=2+8×TIME(

s)用循環(huán)程序?qū)⒅噶钪貜?fù)多次執(zhí)行,實(shí)現(xiàn)軟件延時(shí)。2024/4/1940試計(jì)算延時(shí)程序的執(zhí)行時(shí)間。

源程序 指令周期(M)指令執(zhí)行次數(shù)習(xí)題:DELAY:MOVR6,#100 1D1:MOVR7,#10 1D2:NOP 1

DJNZR7,D2 2t=6.606ms

DJNZR6,D1 2 RET 2計(jì)算延時(shí)程序的執(zhí)行時(shí)間(設(shè)時(shí)鐘fOSC=6MHz,T=2

s

。DELAY:MOVR6,#64H(=100) 1 I1:MOVR7,#0FFH(=255) 1 I2:DJNZR7,I2 2 DJNZR6,I1 2 RET 2延時(shí)時(shí)間計(jì)算:(設(shè)時(shí)鐘fOSC=12MHz)T=1

st=(1×1+1×100+2×100×255+2×100+2×1)×T=51.303ms1100100×25510012、多重循環(huán)定時(shí):用循環(huán)程序?qū)⒅噶钪貜?fù)多次執(zhí)行,實(shí)現(xiàn)較長時(shí)間的延時(shí)。2024/4/19414-6算術(shù)運(yùn)算程序

4-6-1 多字節(jié)加減運(yùn)算程序多字節(jié)加法子程序,Z=X+Y。(參看P84)ADDS:CLR CMOVR2,#23H

LOOP:MOV A,@R0 ADDC A,@R1

;加一字節(jié)

MOV @R0,A ;存和一字節(jié)

INC R0

;修改指針

INC R1 DJNZ R2,LOOP ;全部字節(jié)加完?

RET習(xí)題1:編寫十進(jìn)制多字節(jié)加法子程序,Z=X+Y。習(xí)題2:編寫多字節(jié)減法子程序,Z=X-Y。思考題:修改程序使運(yùn)算結(jié)果保存到其他存儲單元。2024/4/1942設(shè)被乘數(shù)的高字節(jié)放在R7中,低字節(jié)放于R6中;乘數(shù)的高字節(jié)放于R5中,低字節(jié)放于R4中。乘得的積有4個(gè)字節(jié),按由低字節(jié)到高字節(jié)的次序存于片內(nèi)RAM中以ADDR為首址的區(qū)域中。由于MCS-51單片機(jī)只有一條單字節(jié)無符號數(shù)乘法指令MUL,而且要求參加運(yùn)算的兩個(gè)字節(jié)須放于累加器A和B寄存器中,而乘得的結(jié)果高字節(jié)放于B寄存器中,低字節(jié)放于累加器A中。因而兩字節(jié)乘法須用四次乘法指令來實(shí)現(xiàn),即R6

R4、R7R4、R6R5和R7R5,設(shè)R6R4的結(jié)果為B1A1,R7R4結(jié)果為B2A1,R6R5的結(jié)果為B3A3,R7R5的結(jié)果為B4A4,乘得的結(jié)果須按下面的關(guān)系加起來。R7R6R5R4

B1A1B2A2B3A3B4A4C2C1C4C3+4-6-2 多字節(jié)無符號數(shù)乘除運(yùn)算2024/4/1943即乘積的最低字節(jié)C1只由A1這部分得到,乘積的第二字節(jié)C2由B1、A2和A3相加得到,乘積的第三字節(jié)C3由B2、B3、A4以及C2部分的進(jìn)位相加得到,乘積的第四字節(jié)C4由B4和低字節(jié)的進(jìn)位相加得到。由于在計(jì)算機(jī)內(nèi)部不能同時(shí)實(shí)現(xiàn)多個(gè)數(shù)相加,因而我們用累加的方法來計(jì)算C2、C3和C4部分,用R3寄存器來累加C2部分,用R2寄存器來累加C3部分,用R1寄存器來累加C4部分,另外用R0作指針來依次存放C1、C2、C3、C4入存儲器。程序如下:

ORG0100H MOVR0,#ADDRMUL1:MOVA,R6 MOVB,R4 MULAB;R6

R4,結(jié)果的低字節(jié)直接存入積的第一字節(jié)單元

MOV@R0,A;結(jié)果的高字節(jié)存入R3中暫存起來

MOVR3,BMUL2:MOVA,R7 MOVB,R4 MULAB;R7R4,結(jié)果的低字節(jié)與R3相加后,再存入R3中

ADDA,R3 MOVR3,A2024/4/1944

MOVA,B;結(jié)果的高字節(jié)加上進(jìn)位位后存入R2中暫存起來

ADDCA,#00 MOVR2,AMUL3:MOVA,R6 MOVB,R5 MULAB;R6

R5,結(jié)果的低字節(jié)與R3相加存入積的第二字節(jié)單元

ADDA,R3 INCR0 MOV@R0,A MOVA,R2 ADDCA,B;結(jié)果的高字節(jié)加R2再加進(jìn)位位后,再存入R2中

MOVR2,A MOVA,#00 ADDCA,#00;相加的進(jìn)位位存入R1中

MOVR1,A2024/4/1945MUL4:MOVA,R7 MOVB,R5 MULAB;R7R5,結(jié)果的低字節(jié)與R2相加存入積的第三字節(jié)單元

ADDA,R2 INCR0 MOV@R0,A MOVA,B ADDCA,R1;結(jié)果的高字節(jié)加R1再加進(jìn)位后存入積的第四字節(jié)單元

INCR0 MOV@R0,A END2024/4/1946例:R2R3R4R5÷R6R7?R4R5(余數(shù)?R2R3)解:1.判斷R2R3<R6R7?使商不大于16位。

2.被除數(shù)左移1位,試減除數(shù)。 3.若夠減,商加1并保留余數(shù)。

101110101/01110100

0101 1001

01011000

0101

0110

0101 1

Cy←R2R3←R4R5←0

-R6R7+1夠減116÷5=23…1

R2R3

不夠減恢復(fù)余數(shù)循環(huán)16次相減計(jì)算多字節(jié)除法程序。步驟:1.對齊高位被除數(shù)試減除數(shù)。2.若夠減商上1,不夠減商上0且恢復(fù)余數(shù)。3.余數(shù)左移或除數(shù)右移對位。4.循環(huán)重復(fù)前3步,直至取夠相應(yīng)位數(shù)的商。

“四舍五入”:得到余數(shù)后,判斷余數(shù)乘2后

是否大于除數(shù),若大于除數(shù)則商再加“1”;否則不加。2024/4/19474-6-3代碼轉(zhuǎn)換程序(一)十六進(jìn)制數(shù)轉(zhuǎn)換為ASCII碼;(二)ASCII碼轉(zhuǎn)換為十六進(jìn)制數(shù)。0~9的ASCII碼:30~39H;(一)十六進(jìn)制數(shù)轉(zhuǎn)換為ASCII碼:HASC:CJNEA,#0AH,N

N:JNC N1(C=0跳N1)

ADD A,#30H SJMP SEN1:ADD A,#37HSE: RET

A~F的ASCII碼:41~46H。(二)ASCII碼轉(zhuǎn)換為十六進(jìn)制數(shù):AHEX:CLRC SUBB A,#30H CJNE A,#0AH,NN:JC N1 SJMP AEN1:SUBB A,#11H CJNE A,#06H,N2N2:JNC ERR ADD A,#0AH SJMP AEERR:MOV A,#0FFHAE: RET2024/4/1948P96:例題(數(shù)制轉(zhuǎn)換)[例4.11]在內(nèi)部RAM的hex單元中存有2位十六進(jìn)制數(shù),試將其轉(zhuǎn)換為ASCII碼,并存放于asc和asc+1兩個(gè)單元中。設(shè)(hex)=7BH

MOV SP,#3FHMAIN:PUSH hex ACALL HASC POP asc

(SP=40H)

MOV A,hex SWAP A PUSH ACC ACALL HASC POP asc+1 子程序(HASC):HASC:DEC SP DEC SP POP ACC ANL A,#0FH

ADD A,#7(A=12H) MOVC A,@A+PC

PUSH ACC INC SP INC SP7個(gè)字節(jié) RET(SP=40H)ASCTAB:DB “0,1,2,3,4,5,6,7” DB “8,9,A,B,C,D,E,F”;十六進(jìn)制數(shù)進(jìn)棧(SP=40H);調(diào)用轉(zhuǎn)換子程序(SP=41H→42H);第一位轉(zhuǎn)換結(jié)果送asc單元(SP=3FH);再取原十六進(jìn)制數(shù);高低半字節(jié)交換;交換后的十六進(jìn)制數(shù)進(jìn)棧(SP=40H);調(diào)用轉(zhuǎn)換子程序(SP=41H→42H);第二位轉(zhuǎn)換結(jié)果送asc+1單元;跨過斷點(diǎn)保護(hù)內(nèi)容(SP=41H);跨過斷點(diǎn)保護(hù)內(nèi)容(SP=40H);彈出轉(zhuǎn)換數(shù)據(jù)(SP=3FH);屏蔽高位 (A=0BH);修改變址寄存器內(nèi)容(PC=2008H);查表(12H+2009H=201BH);查表結(jié)果進(jìn)棧(SP=40H);修改堆棧指針回到斷點(diǎn)保護(hù)內(nèi)容;(42H)→PC8~15,(41H)→PC0~7;ASCII碼表;(201BH)=0BH2000H2001H2002H2004H2006H2008H2009H200BH200DH200FH2010H2018H22212024/4/1949(三)BCD碼與二進(jìn)制數(shù)之間的轉(zhuǎn)換

1.BCD碼轉(zhuǎn)換為二進(jìn)制數(shù):

D=dn-1×10n-1+dn-2×10n-2+…+d1×101+d0×100

=(((dn-1×10+dn-2)×10+dn-3)×10+…d1)×10+d0“整數(shù)十翻二”:從最高位開始,按二進(jìn)制運(yùn)算法則循環(huán)?!俺耸哟蔚臀弧保築=B×10+bi

。R3←0R4←010×R3R4+(R0)R3R4R0←R0+1有乘法和除法兩種轉(zhuǎn)換方式。2024/4/1950“整數(shù)二翻十”:從最高位開始,按十進(jìn)制運(yùn)算法則循環(huán)?!俺硕哟蔚臀弧保篋=D×2+di

。除法轉(zhuǎn)換式:bn-1×2n-1+bn-2×2n-2+…+b0=dm-1×10m-1+dm-2×10m-2+…+d0兩邊同時(shí)除基數(shù),兩邊的整數(shù)或小數(shù)應(yīng)該分別相等。除基數(shù),取出1位余數(shù),得到的商繼續(xù)除基數(shù)取余數(shù)。循環(huán)“除基取余”操作,得到轉(zhuǎn)換進(jìn)制的各位系數(shù)。編程習(xí)題要求:1.為程序標(biāo)明必要注釋。2.上機(jī)調(diào)試通過。3.給出程序執(zhí)行前設(shè)定的數(shù)據(jù),并記錄程序執(zhí)行后的結(jié)果數(shù)據(jù)。4.要求寫明數(shù)據(jù)的存儲單元。2.二進(jìn)制數(shù)轉(zhuǎn)換為BCD碼:

B=bn-1×2n-1+bn-2×2n-2+…+b1×21+b0×20

=(((bn-1×2+bn-2)×2+bn-3)×2+…b1)+b02024/4/19513.10.4子程序及其調(diào)用一、子程序的調(diào)用在實(shí)際應(yīng)用中,經(jīng)常會遇到一些帶有通用性的問題,例如:數(shù)值轉(zhuǎn)換、數(shù)值計(jì)算等,在一個(gè)程序中可能要使用多次。這時(shí)可以將其設(shè)計(jì)成通用的子程序供隨時(shí)調(diào)用。子程序的結(jié)構(gòu)與一般的程序并無多大區(qū)別,它的主要特點(diǎn)是,在執(zhí)行過程中需要由其它程序來調(diào)用,執(zhí)行完后又需要把執(zhí)行流程返回到調(diào)用該子程序的主程序。子程序調(diào)用時(shí)要注意兩點(diǎn):一是現(xiàn)場的保護(hù)和恢復(fù);二是主程序與子程序的參數(shù)傳遞。2024/4/1952二、現(xiàn)場保護(hù)與恢復(fù)在子程序執(zhí)行過程中常常要用到單片機(jī)的一些通用單元,如工作寄存器R0~R7、累加器A、數(shù)據(jù)指針DPTR,以及有關(guān)標(biāo)志和狀態(tài)等。而這些單元中的內(nèi)容在調(diào)用結(jié)束后的主程序中仍有用,所以需要進(jìn)行保護(hù),稱為現(xiàn)場保護(hù)。在執(zhí)行完子程序,返回繼續(xù)執(zhí)行主程序前恢復(fù)其原內(nèi)容,稱為現(xiàn)場恢復(fù)。保護(hù)與恢復(fù)的方法有以下兩種:在主程序中實(shí)現(xiàn);在子程序中實(shí)現(xiàn)。2024/4/1953

1、在主程序中實(shí)現(xiàn)示例如下:

PUSHPSW;保護(hù)現(xiàn)場

PUSHACC;

PUSHB;

MOVPSW,#10H;換當(dāng)前工作寄存器組

LCALLaddr16;子程序調(diào)用

POPB;恢復(fù)現(xiàn)場

POPACC;

POPPSW;

……

其特點(diǎn)是結(jié)構(gòu)靈活。2024/4/1954

2、在子程序中實(shí)現(xiàn)示例如下:SUB1:PUSHPSW;保護(hù)現(xiàn)場

PUSHACC;

PUSHB;

……MOVPSW,#10H;換當(dāng)前工作寄存器組

……POPB;恢復(fù)現(xiàn)場

POPACC;

POPPSW;

RET其特點(diǎn)是程序規(guī)范、清晰。注意,無論哪種方法保護(hù)與恢復(fù)的順序要對應(yīng)。2024/4/1955三、參數(shù)傳遞

由于子程序是主程序的一部分,所以,在程序的執(zhí)行時(shí)必然要發(fā)生數(shù)據(jù)上的聯(lián)系。在調(diào)用子程序時(shí),主程序應(yīng)通過某種方式把有關(guān)參數(shù)(即子程序的入口參數(shù))傳給子程序,當(dāng)子程序執(zhí)行完畢后,又需要通過某種方式把有關(guān)參數(shù)(即子程序的出口參數(shù))傳給主程序。在80C51單片機(jī)中,傳遞參數(shù)的方法有三種:

1、利用累加器或寄存器在這種方式中,要把預(yù)傳遞的參數(shù)存放在累加器A或工作寄存器R0~R7中。即在主程序調(diào)用子程序時(shí),應(yīng)事先把子程序需要的數(shù)據(jù)送入累加器A或指定的工作寄存器中,當(dāng)子程序執(zhí)行時(shí),可以從指定的單元中取得數(shù)據(jù),執(zhí)行運(yùn)算。反之,子程序也可以用同樣的方法把結(jié)果傳送給主程序。2024/4/1956例編寫程序,實(shí)現(xiàn)c=a2+b2。設(shè)a,b,c分別存于內(nèi)部RAM的30H,31H,32H三個(gè)單元中。程序段如下: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

2024/4/19572、利用存儲器當(dāng)傳送的數(shù)據(jù)量比較大時(shí),可以利用存儲器實(shí)現(xiàn)參數(shù)的傳遞。在這種方式中,事先要建立一個(gè)參數(shù)表,用指針指示參數(shù)表所在的位置。當(dāng)參數(shù)表建立在內(nèi)部RAM時(shí),用R0或R1作參數(shù)表的指針。當(dāng)參數(shù)表建立在外部RAM時(shí),用DPTR作參數(shù)表的指針。

例將R0和R1指向的內(nèi)部RAM中兩個(gè)3字節(jié)無符號整數(shù)相加,結(jié)果送到由R0指向的內(nèi)部RAM中。入口時(shí),R0和R1分別指向加數(shù)和被加數(shù)的低位字節(jié);出口時(shí),R0指向結(jié)果的高位字節(jié)。低字節(jié)在高地址,高字節(jié)在低地址。

2024/4/1958實(shí)現(xiàn)程序:NADD:MOVR7,#3;三字節(jié)加法

CLRC;NADD1:MOVA,@R0;取加數(shù)低字節(jié)

ADDCA,@R1;被加數(shù)低字節(jié)加AMOV@R0,A;

DECR0DECR1DJNZR7,NADD1INCR0RET

2024/4/19593、利用堆棧利用堆棧傳遞參數(shù)是在子程序嵌套中常采用的一種方法。在調(diào)用子程序前,用PUSH指令將子程序中所需數(shù)據(jù)壓入堆棧,進(jìn)入執(zhí)行子程序時(shí),再用POP指令從堆棧中彈出數(shù)據(jù)。

例把內(nèi)部RAM中20H單元中的1個(gè)字節(jié)十六進(jìn)制數(shù)轉(zhuǎn)換為2位ASCII碼,存放在R0指示的兩個(gè)單元中。

2024/4/1960

MAIN:MOVA,20H;

SWAPAPUSHACC;參數(shù)入棧

ACALLHEASCPOPACCMOV@R0,A;存高位十六進(jìn)制數(shù)轉(zhuǎn)換結(jié)果

溫馨提示

  • 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論