日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

您好,歡迎來電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

當(dāng)前位置:電子發(fā)燒友網(wǎng) > 圖書頻道 > 電子 > 《單片機(jī)原理與應(yīng)用》 > 第4章 匯編語言程序設(shè)計(jì)

第4節(jié) 程序設(shè)計(jì)舉例

【例4.1】拆字程序。將一個(gè)字節(jié)的兩個(gè)BCD碼十進(jìn)制數(shù)拆開并變成相應(yīng)的ASCII碼,并存入兩個(gè)RAM單元中。

設(shè)兩個(gè)BCD碼(一個(gè)字節(jié))已存入在內(nèi)部RAM的30H單元中,變換后的ASCII 碼分別存放在31H和32H單元,且高位BCD碼的ASCII碼的ASCII碼存于31H單元。數(shù)字0~9的ASCII為30H~39H,完成拆字轉(zhuǎn)換只需將一個(gè)字節(jié)的兩個(gè)BCD碼拆開存放在另兩個(gè)單元的低4位,并在其高4位賦以0011即可。程序段清單如下:

MOV  R0,#32H        ;將32H單元地址送R0

MOV  @R0,#00H      ;32H單元清0

MOV   A,30H         ;將30H單元中的BCD送A

XCHD  A,@R0         ;將低位BCD碼送32H單元

ORL   32H,#30H       ;完成低位BCD碼轉(zhuǎn)換

SWAP  A                ;將高位BCD碼交換到低位

ORL  A,#30H           ;完成高位BCD碼轉(zhuǎn)換

MOV  31H,A            ;將高位BCD的ASCII碼存入31H

上述程序段完成了將一個(gè)字節(jié)的BCD碼轉(zhuǎn)換成兩個(gè)ASCII碼的功能。共需占用15個(gè)程序存儲(chǔ)器字節(jié)單元,用9個(gè)機(jī)器周期執(zhí)行完畢。

【例4.2】 雙字節(jié)加法程序段

設(shè)被加數(shù)存放在內(nèi)部矛盾RAM的31H、32H單元,低位字節(jié)在前,加數(shù)存入于34H、35H單元(低字節(jié)在前),結(jié)果和存放于31H、32H、33H單元中。其程序段清單如下;

STRT:PUSH  A         ;將A內(nèi)容進(jìn)棧保護(hù)

MOV  R0­,#31H         ;將地址碼送R0和R1

MOV   R1,#34H

MOV   33H,#00H  ;將33H單元清0,存放和的最高字節(jié)數(shù)

MOV   A,R0      ;兩低字節(jié)數(shù)相加

ADD   A,@R1

MOV   @R0,A    ;低字節(jié)和存于31H單元

INC    R0            ;地址數(shù)分別加1

INC     R1

MOV   A,@R0      ;連用低位進(jìn)位進(jìn)行高字節(jié)數(shù)

ADDC  A,@R1      ;相加

MOV   @R0,A      ;高字節(jié)和存于32H單元

INC    R0           ;R0指針指向33H單元

MOV   A,#00H     ;清A為0

ADDC  A,#00H     ;求高字節(jié)和的進(jìn)位

MOV   @R0,A      ;將高字節(jié)進(jìn)位存于33H單元

POP    A            ;恢復(fù)A原內(nèi)容

【例4.3 】 求雙字節(jié)補(bǔ)碼程序段

設(shè):存于內(nèi)部RAM的addr1和addr1+1單元的雙字節(jié)數(shù)讀出取補(bǔ)后存入addr2和addr2+1單元中,其中高字節(jié)數(shù)存于高地址單元,圖4.7為雙字節(jié)數(shù)求補(bǔ)流程圖

 

圖4.7雙字節(jié)數(shù)取補(bǔ)流程圖 

8位字長(zhǎng)的單片機(jī)對(duì)雙字節(jié)數(shù)取補(bǔ)需分兩次進(jìn)行,首先對(duì)低字節(jié)數(shù)取補(bǔ)后判其結(jié)果是否為0,若為全0,則要對(duì)高字節(jié)數(shù)取補(bǔ),否則取反即可。雙字節(jié)數(shù)取補(bǔ)程序估如下:

START:MOV  R0,#addr1     ;原碼低字節(jié)數(shù)地址送R0

MOV  R1,#addr2     ;補(bǔ)碼低字節(jié)數(shù)地址送R1

MOV  A,@R0       ;原碼低字節(jié)數(shù)送A

CPL   A             ;對(duì)低字節(jié)數(shù)取補(bǔ)

INC   A              

MOV  @R1,A       ;低字節(jié)補(bǔ)碼存入addr2單元

INC   R0           ;R0、R1內(nèi)容分別加1

INC   R1         

JZ    ZERO         ;判(A)=0?當(dāng)(A)=0,則轉(zhuǎn)ZERO

MOV  A,@R0       ;原碼高字節(jié)數(shù)送A

CPL   A             ;對(duì)A內(nèi)容取反

MOV  @R1,A         ;高字節(jié)數(shù)補(bǔ)碼存addr2+1

SJMP  LOOP1         ;轉(zhuǎn)結(jié)束

ZERO:MOV  A,@R0       ;低字節(jié)取補(bǔ)后為0,則對(duì)高字節(jié)數(shù)取補(bǔ)

CPL   A

INC   A

MOV   @R1,A      ;將高字節(jié)補(bǔ)碼存addr2+2

LOOP1:END                  ;結(jié)束

所有條件判跳指令均屬相對(duì)尋址方式,其相對(duì)偏移量是一個(gè)帶符號(hào)的8位二進(jìn)制碼,常以補(bǔ)碼形式出現(xiàn)。其尋址范圍為-128~+127B。編程時(shí)應(yīng)多加注意。

【例4.4 】 由累加器A在動(dòng)態(tài)運(yùn)行中給出的結(jié)果值選擇對(duì)應(yīng)的轉(zhuǎn)移指令,其對(duì)應(yīng)關(guān)系為:

(A)=0,轉(zhuǎn)向分反處理程序0

(A)=1,轉(zhuǎn)向分支處理程序1

(A)=n,轉(zhuǎn)向分支處理程序n

一般轉(zhuǎn)移指令均為有條件轉(zhuǎn)移指令,而MCS-51單片機(jī)有兩條無條件轉(zhuǎn)移指令:AJMP和LJMP。前者為雙字節(jié)指令,后者為三字節(jié)指令,因此,需視選用何種跳轉(zhuǎn)指令而應(yīng)對(duì)A中值作相應(yīng)變換。如選用AJMP指令,則應(yīng)對(duì)A值變換成偶數(shù)值;如選用LJMP指令,則應(yīng)對(duì)A值乘3的變換。每個(gè)分支處理程序均為各自獨(dú)立的等程序段,分散在各自的程序存儲(chǔ)器區(qū)段。要皮,必須有一個(gè)中轉(zhuǎn)站,軒向各自的分支處理程序。這個(gè)無條件轉(zhuǎn)移指令串的首地址由DPTR指示?,F(xiàn)以AJMP為例,其程序段如下:

START:MOV  DPTR,#addr16     ;跳轉(zhuǎn)指令串首址送DPTR

           CLR  C                   ;清C為0

           RLC  A                   ;將A值變換成偶數(shù)

           JNC  TABEL               ;判(C)=0?不為0則轉(zhuǎn)

           INC  DPH                 ;(C)=1,則DPH內(nèi)容+1

TABEL:JMP  @A+DPTR            ;散轉(zhuǎn)

ADDR16:AJMP LOOP0             ;無條件轉(zhuǎn)移指令串

          AJMP LOOP1

          AJMP LOOPn

LOOP0:…                       ;分支程序段0

LOOP1:…                       ;分支程序段1

由于上例選用絕對(duì)值轉(zhuǎn)移指令A(yù)JMP是雙字節(jié)指令,因此,要求A中內(nèi)容必須換算成偶數(shù)。換算方式可以乘2,而這里采用左移一位的辦法來實(shí)現(xiàn)。如果n值等于或大于128,則左移一位將產(chǎn)生高位進(jìn)位,將進(jìn)位值加到DPH中去,等于將轉(zhuǎn)移指令串首址延伸256個(gè)存儲(chǔ)單元,所以在程序段中對(duì)C進(jìn)行測(cè)判。這樣,保證分支處理程序段可以在0-255個(gè)中任選。

如果選用長(zhǎng)調(diào)用LJMP,它是怎么樣三字節(jié)指令,在進(jìn)A值換算時(shí)應(yīng)乘3處理,將積的高字節(jié)值加到DPH中去。一般,DPTR+A的最終值應(yīng)不超過64KB范圍。

【例4.5】 采用循環(huán)程序?qū)崿F(xiàn)延時(shí),一般可達(dá)到任意延時(shí)要求,但需犧牲CPU的工作。

MOV   40H,#data           ;設(shè)置計(jì)數(shù)初值

AGIN:   NOP

NOP

DJNZ   40H,AGIN           ;當(dāng)(40H)-1≠0則繼續(xù)循環(huán)

上例每循環(huán)一次共需4個(gè)機(jī)器周期,實(shí)際總延時(shí)由40H單元內(nèi)容和主頻(fosc)的頻率所設(shè)置決定。

【例4.6】 數(shù)據(jù)塊搜索

設(shè)外部RAM從BLOCK單元開始有一個(gè)無符號(hào)數(shù)據(jù)塊,其長(zhǎng)度(即數(shù)據(jù)塊個(gè)數(shù))存于LEN單元,試求出數(shù)據(jù)塊 最大值數(shù)據(jù),并存于MAX單元中。

尋找最大值的方法很多,最基本的方法是比較和交換依次進(jìn)行,即先讀取第一個(gè)數(shù)與第二個(gè)數(shù)相比較,并把前一個(gè)數(shù)作為基準(zhǔn)。比較結(jié)果:若基準(zhǔn)數(shù)在,則不作交換,再取下一個(gè)數(shù)進(jìn)行比較;若基準(zhǔn)數(shù)小,則將大數(shù)取代原基準(zhǔn)數(shù),即作一次交換,然后再以新的基準(zhǔn)數(shù)與下一個(gè)數(shù)作比較,直到全部比較完畢?;鶞?zhǔn)數(shù)始終保持為最大數(shù)值。圖7.6為數(shù)據(jù)塊搜索流程圖。

設(shè)R1中存放基準(zhǔn)數(shù),R3為數(shù)據(jù)長(zhǎng)度,R2中存放每次讀出的新的數(shù)據(jù)塊。

其循環(huán)程序段如下;

START:CLR   A               ;A清0

CLR    R1                    ;清R1為0

MOV   R3,LEN                ;數(shù)據(jù)塊長(zhǎng)度送R3作控制計(jì)數(shù)

LOOP:MOVX A,@DPTR         ;讀數(shù)據(jù)塊

INC   DPTR                    指向下一個(gè)單元

MOV   R2 ,A                 ;將讀出的靈敏據(jù)塊送R2

CLR   C                      ;清C為0

MOV   A ,R1                 ;基準(zhǔn)值送A

SUBB  A,R2                  ;基準(zhǔn)數(shù)一讀出數(shù)

JNC   NEXT                   ;(C)=0,即(A)≥(R2),跳轉(zhuǎn)

MOV  R1,A   

NEXT:DJNZ   R3LOOP           ;判搜索完否

MOV  MAX,R1                  ;最大數(shù)據(jù)存入MAX單元

END                           ;結(jié)束

【例4.7 】 工作單元清0

設(shè)R1中存放被清0單元首地址,R3中存放清0字節(jié)數(shù),則其循環(huán)程序如下:

START;MOV  R1,#addr         ;清0單元首地址送R1

MOV  R3,#data                 ;清0字節(jié)數(shù)送R3

CLR   A                      ;A清0

LOOP:、MOV  @R1,A          ;指定單元清0

INC   R1工                 ;指向下一個(gè)單元

DJNZ   R3,LOOP               ;(R3)-1≠0,繼續(xù)清0

END                            ;結(jié)束

【例4.8】  4位BCD碼整數(shù)轉(zhuǎn)換成二進(jìn)制整數(shù)

入口參數(shù):BCD碼字節(jié)地址指針R0,位數(shù)存于R2中。

出口參數(shù):二進(jìn)制數(shù)存于R3R4中。

算法:A=103a3+102­a2+10a1+a0

程序流程如7.7所示。

子程序清單如下:

BCDA:PUSH  PSW               ;現(xiàn)場(chǎng)保護(hù)

PUSH  A

PUSH   B

MOV   PSW,#08H

MOV   R3,#00H

MOV   R2,#3          ;BCD碼D的位數(shù)

MOV   A,@R0             ;a0-R4

MOV   R4,A

BCKB:MOV   A,R3           ;(R3R4)×10

MOV   B,#10          ;R4

MUL   AB

MOV   R4,A

XCH   A,B

MOV   B,#10

XCH   A,R3

MUL   AB

ADD   A,R3

XCH   A,R4

INC    R0                           ;(R0)+1-R0

ADD   A,@R0           ;( R3R4)- ((R0))-RR3R4

XCH   A,R4

ADDC  A,#0

MOV   R3,A

DJNZ   R2,BCDB             ;循環(huán)n-1次

POP    B                    ;恢復(fù)現(xiàn)場(chǎng)

PIP     A

POP    PSW

RET                          ;返回

上例中的R2內(nèi)容是BCD碼的位數(shù)n,本例中n=4,即兩個(gè)字節(jié)4位BCD碼,在程序中作為循環(huán)控制寄存器的計(jì)數(shù)值為n-1=4-1=3,即本例循環(huán)3次即完成二次字節(jié)的BCD碼轉(zhuǎn)換。

本例采用乘10運(yùn)算,也可采用除2運(yùn)算進(jìn)行轉(zhuǎn)換。

【例4.9】 多字節(jié)十進(jìn)制數(shù)加法子程序

入口參數(shù):將R0指針的內(nèi)部RAM中N個(gè)字節(jié)的BCD碼被加數(shù),R1指針的內(nèi)產(chǎn)RAM中N個(gè)字節(jié)的BCD碼中數(shù)進(jìn)行相加。R2中存放字?jǐn)?shù)N。

出口參數(shù):相加結(jié)果的BCD碼和數(shù)存入R0指針的內(nèi)部RAM(原被加數(shù)單元)中。

圖4.8為多字節(jié)BCD碼加法子程序流程圖。子程序清單如下:

 

圖4.8多字節(jié)BCD碼加法子程序流程圖

BCDADD:PUSH  PSW

PUSH  A

MOV   PSW,#08H

MOV   A,R0

ADD   A,R2

MOV   R0,A

DEC   R0

MOV   A,R1­

ADD   A,R2

MOV   R1,A

DEC   R1

CLR   C

ADDA:MOV   A,@R0                                                         

ADDC  A,@R1

DA     A

MOV   @R0,A

DEC    R1

DEC    R0

DJNZ   R2,ADDA       ;判加完否

JNC    ADDB           ;若(C)=0則轉(zhuǎn)ADDB

MOV   A,#00H         ;清A為0

ADDC  A,#00H         ;若(C)=1,則為最高位進(jìn)位

MOV   @R0,A

ADDB:POP   A             ;現(xiàn)場(chǎng)恢復(fù)

POP   PSW

RET                   ;返回

本例中兩數(shù)均按高位字節(jié)數(shù)存放于低地址單元,而相國(guó)運(yùn)算則從低位字節(jié)數(shù)開始,R0、R1指針在運(yùn)算前均指向最高字節(jié)數(shù)的地址,故需轉(zhuǎn)換成指向最低字節(jié)數(shù)的地址,然后進(jìn)行相加運(yùn)算。

【例4.10】 應(yīng)用系統(tǒng)采用LED七段顯示,可將BCD碼或十六進(jìn)制碼以及某些符號(hào)通過查找LED顯示編碼進(jìn)行顯示輸出。

七段LED顯示器有共陰極和共陽極之分,其顯示編碼是不同的,共陽極是低電平為有效輸入;共陰極則是高電平輸入有效,LED的編碼不是序碼,即表格無規(guī)律可尋,可根據(jù)各自方便排列。例如BCD碼顯示,同是其顯示碼可按0~9的順序排列。假如顯示器是共陽極的,則BCD碼與顯示器編碼的對(duì)應(yīng)關(guān)系為:0的顯示編碼為0100 0000,即40H,1的編碼為0111 1001,即79H;2的編碼為24H,3的編碼為30H,…,對(duì)于這類問題,通過查表來實(shí)現(xiàn)比較方便。具體程序段如下:

MOV  DPTR,#LEDA         ;表格首址送DPTR

MOV  A,@A+DPTR      ;變址寄存器A中內(nèi)容為查表主序號(hào),                                                                即要顯示的內(nèi)容,如0,1,2,…,9

MOVC   A,@A+DPTR         ;讀出要顯示的內(nèi)容

                             ;進(jìn)行LED顯示

LEDA:DB    40H,79H,24H,30H,12H

DB    20H,78H,00H,18H,…

對(duì)于這類問題,一般均選用DPTR作為基址指針的查表指令為宜。這樣,表格串可設(shè)置在64KB的任何地址段,可實(shí)現(xiàn)任意次查表。

?
唐河县| 潍坊市| 平南县| 吴堡县| 昆明市| 南投市| 绥化市| 郁南县| 临夏县| 湘潭市| 义马市| 仙桃市| 揭阳市| 奉新县| 沈丘县| 孝昌县| 江西省| 乌拉特前旗| 遵义县| 靖西县| 茌平县| 土默特左旗| 运城市| 咸阳市| 襄樊市| 甘孜| 涞水县| 吉首市| 瑞昌市| 浙江省| 保靖县| 屏南县| 丹东市| 昔阳县| 苗栗县| 龙川县| 河北区| 临澧县| 盐山县| 孟州市| 禹城市|