【大學(xué)】單片機(jī)課件-匯編語言程序設(shè)計PPT_第1頁
【大學(xué)】單片機(jī)課件-匯編語言程序設(shè)計PPT_第2頁
【大學(xué)】單片機(jī)課件-匯編語言程序設(shè)計PPT_第3頁
【大學(xué)】單片機(jī)課件-匯編語言程序設(shè)計PPT_第4頁
【大學(xué)】單片機(jī)課件-匯編語言程序設(shè)計PPT_第5頁
已閱讀5頁,還剩223頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、第四章匯編語言程序設(shè)計4.1 概述 4.2 順序結(jié)構(gòu)程序4.3 分支結(jié)構(gòu)程序4.4 循環(huán)結(jié)構(gòu)程序4.5 子程序結(jié)構(gòu)4.6 綜合程序舉例4.7 本章小節(jié)4.8 思考與練習(xí)題第四章匯編語言程序設(shè)計 主要內(nèi)容:本章從程序結(jié)構(gòu)和實用角度出發(fā),通過典型的應(yīng)用實例介紹匯編語言程序的基本結(jié)構(gòu)及模塊化程序設(shè)計,使學(xué)生進(jìn)一步理解和掌握51系列單片機(jī)的指令系統(tǒng),并掌握匯編語言程序設(shè)計的基本語言和技巧。 要求: 1、熟練運(yùn)用指令系統(tǒng),掌握循環(huán)程序、分支程序和搜索程序的設(shè)計方法; 2、熟練運(yùn)用指令系統(tǒng),掌握基本的運(yùn)算程序設(shè)計方法; 第四章匯編語言程序設(shè)計 3、熟練運(yùn)用指令系統(tǒng),掌握數(shù)制和碼制轉(zhuǎn)換程序的設(shè)計方法; 4、

2、熟練掌握子程序結(jié)構(gòu),實現(xiàn)模塊化程序設(shè)計; 5、深刻理解軟件、硬件的相互作用,不斷提高實際問題處理程序編寫能力。 4.1 概述 4.1 概述 程序設(shè)計:為了解決某一個問題,將所設(shè)計應(yīng)用系統(tǒng)(單片機(jī)類型)的指令按一定順序組合在一起。即用計算機(jī)所能接受的語言把解決問題的步驟描述出來。 單片機(jī)匯編源程序結(jié)構(gòu)與通用微機(jī)匯編源程序結(jié)構(gòu)略有不同,原因是: 1、一般沒有可以直接利用的監(jiān)控程序,所有程序均要自己編寫。4.1 概述 2、沒有像X86匯編語言程序那樣,可直接調(diào)用系統(tǒng)提供的中斷功能(如:BIOS中斷、DOS中斷)或Windows的API函數(shù)完成特定操作,即所有子程序(如鍵盤監(jiān)控子程序、顯示驅(qū)動程序、中

3、斷服務(wù)程序等)均需要自己編寫。 匯編語言語句三種基本類型:指令語句、偽指令語句、宏指令語句。4.1 概述 一、匯編語言偽指令 偽指令 匯編程序某些指令在匯編時并不產(chǎn)生目標(biāo)代碼,不影響程序的執(zhí)行,不是CPU能執(zhí)行的指令,只提供一些匯編控制信息的指令。常用的偽指令: (1)設(shè)置起始地址ORG 格式:ORG nn 1、ORG:表明為后續(xù)源程序經(jīng)匯編后的目標(biāo)程序安排存放位置,nn則給出了存放的起始地址值; 4.1 概述 2、ORG總是出現(xiàn)在每段源程序或數(shù)據(jù)塊的開始; 3、在一個源程序中,可以多次使用ORG規(guī)定不同程序段的起始位置,但定義的地址順序應(yīng)從小到大,且不能重疊; 4、若不用ORG,則匯編將從0

4、000H單元開始存放目標(biāo)程序; 例4.1ORG 3000H;表示后續(xù)的目標(biāo)程序代碼從3000H單元開始存放。MOV A,30H 4.1 概述 (2)定義字節(jié)DB 格式:標(biāo)號:DB字節(jié)數(shù)據(jù)項表 1、標(biāo)號區(qū)段可有可無,項表指中間用逗號分開的字節(jié)、數(shù)、字符串或用引號括起來的ASC碼字符串(一個字符用ASC碼表示,就相當(dāng)于一個字節(jié))。 2、功能:把項表的數(shù)據(jù)存入從標(biāo)號開始的連續(xù)單元中。 例4.2ORG 2000HSEG1:DB 35H,78H4.1 概述 SEG2:DB DAY END則 (2000H)=35H,(2001H)=78H,(2002H)=44H,(2003H)=41H,(2004H)=5

5、9H 注意:項表中若為數(shù)值,其取值范圍應(yīng)為00HFFH,若為字符串,其長度應(yīng)限制在80個字符內(nèi)。 (3)定義字DW 格式:標(biāo)號:DW字節(jié)數(shù)據(jù)項表 DW的基本含義與DB相同,不同的是DW定義16位數(shù)據(jù),常用來建立地址表。存放時一個字需兩個單元,高8位先存放,低8位后存放。4.1 概述例4.3 ORG 8000HHETAB:DW 7234H,8AH,10 匯編后:(8000H)=72H,(8001H)=34H,(8002H)=00H,(8003H)=8AH,(8004H)=00H,(8005H)=0AH (4)數(shù)據(jù)地址賦值DATA 格式為: 字符名稱 DATA 數(shù)據(jù)或表達(dá)式 把數(shù)據(jù)地址或代碼地址賦

6、予字符名稱。常用于定義數(shù)據(jù)地址,它可以先使用后定義(因為DATA定義的字符名稱作為標(biāo)號登記在符號表中,而EQU沒定義),這點與EQU不同。表達(dá)式應(yīng)是可求值的。4.1 概述例4.4ORG8000H INDEXJDATA 8096H LJMP INDEXJ END 等價于ORG8000H LJMP 8096H END 4.1 概述 (5)賦值(等值)EQU 格式:標(biāo)號 EQU 項或表達(dá)式 功能:將語句操作數(shù)的值賦于本語句的標(biāo)號,用EQU賦過值的標(biāo)號名可以用作數(shù)據(jù)地址、代碼地址、位地址或是一個立即數(shù),它可以是8位、也可以是16位。 注意: 1、在同一程序中,用EQU偽指令對標(biāo)號賦值后,該標(biāo)號的值在整

7、個程序中不能再改變; 2、用EQU定義的字符須先定義后使用。4.1 概述 例4.5 ORG8000H AAEQUR6;AA與R6等值MOV A,AA ;(R6)的值送入A中 (6)位地址符號命令BIT 格式: 字符名稱 BIT 位地址 功能:給一個可位尋址的位單元起一個名字。用BIT定義過的位單元可用名字使用。 注意:名字必須是以字母開頭的字母數(shù)字串,它必須是事先未定義過的。 4.1 概述 例4.6 A1BITP1.0A2BIT02H (7)源程序結(jié)束END 格式:標(biāo)號:END 表達(dá)式 1、標(biāo)號和表達(dá)式是可有可無的。 2、END是一個結(jié)束標(biāo)志,在一個程序中只允許出現(xiàn)一個END語句,而且它必須放

8、在整個程序的最后面。 (8)定義存儲空間DS 格式: 標(biāo)號:DS 表達(dá)式 1、由標(biāo)號指定單元開始,定義一個存儲區(qū),以備源程序使用。4.1 概述2、存儲區(qū)內(nèi)預(yù)留的存儲單元數(shù)由數(shù)據(jù)或字符表達(dá)式的值決定。例4.7 ORG 8000HTEMP:DS 08HDB 30H,8AH即8000H8007H單元保留備用,(8008H)=30H,(8009H)=8AH。二、匯編語言程序設(shè)計的基本步驟1、分析問題(調(diào)研),確定方案和計算方法 目的:對需要解決的問題進(jìn)行分析,以求對問題有正確的理解。 4.1 概述2、了解應(yīng)用系統(tǒng)的硬件配置、性能指標(biāo)。3、建立系統(tǒng)數(shù)學(xué)模型,確定控制算法和操作步驟。4、編制說明要解決問題

9、的程序框圖。畫程序框圖:用各種圖形、符號、指向線等來說明程序設(shè)計的過程??驁D步驟寫得越細(xì)致,編程時也就越方便。目的:把具有一定功能的各個部分有機(jī)地聯(lián)系起來,可以使人們抓住程序的基本線索,對全局有完整的了解。4.1 概述好處:(1)容易發(fā)現(xiàn)設(shè)計思想上的錯誤和矛盾,便于找出解決問題的途徑。(2)便于把較大的程序分成若干個模塊,從而分頭進(jìn)行設(shè)計,最后合在一起聯(lián)調(diào)。5、按所使用計算機(jī)的指令系統(tǒng),依據(jù)框圖寫出匯編語言程序。編程的三個原則:盡可能的節(jié)省數(shù)據(jù)存儲單元;縮短程序長度;減少執(zhí)行時間。4.1 概述.合理分配存儲器單元和了解I/O接口地址。.按功能設(shè)計程序,明確各程序之間的相互關(guān)系。.用注釋行說明程

10、序,便于閱讀、調(diào)試和修改。6、上機(jī)調(diào)試程序,直至完成預(yù)定功能。 MCS-51 程序總體組成MCS-51匯編語言源程序一般由程序頭、主程序、完成特定操作的子程序(可能不止一個)及相應(yīng)功能的中斷服務(wù)程序等部分組成。結(jié)構(gòu)如下:4.1 概述 - 程序頭( 即定義變量和等值符號)- SCL BIT P1.2 ;定義SCL位變量SDA BIT P1.3 ;定義SDA位變量ByteCon DATA 30H ;定義字節(jié)變量ByteCon ORG nnnn ;CPU復(fù)位后,第一指令機(jī)器碼存放單元地址,具體值由CPU類型決定。 例4.8 在51系列中,復(fù)位后PC=0000,因此在51系列中,第一條指令存放在ROM

11、的0000H單元中,即nnnn為“0000H”。 4.1 概述 LJMP Main ;一般第一條指令是跳轉(zhuǎn)指令,跳到主程序入口地址,其中“Main”是主程序入口地址標(biāo)號。 主程序不能直接存放在復(fù)位后PC指向的存儲單元,原因是這一區(qū)域往往是中斷服務(wù)程序的入口地址,不能覆蓋,否則不能使用相應(yīng)的中斷功能。 例4.9 在51系列中,外部中斷0的入口地址為 0003H,顯然只有0000H、0001H和0002H三個單元,剛好可以存放一條長跳轉(zhuǎn)指令的機(jī)器碼。4.1 概述- 主程序 - ORG yyyy ;其中yyyy就是主程序代碼存放區(qū)的首地址,如0100H Main: MOV SP,#5FH ;初始化有

12、關(guān)寄存器,如設(shè)置SP、選擇工作寄存器組。 ;初始化中斷控制寄存器等 ;主程序?qū)嶓w,具體指令由程序功能決定 LCALL SUB1 ;調(diào)用子程序1 ,其中SUB1為子程序名 ; END 4.1 概述 - 子程序結(jié)構(gòu) - ORG zzzz ;其中zzzz就是子程序代碼存放區(qū)的首地址,可以不用ORG指令,直接將子程序存放主程序后。 SUB1:PUSH PSW PUSH Acc;通過PUSH指令保護(hù)子程序中用到的有關(guān)寄存器,如Acc、PSW 等,即保護(hù)現(xiàn)場 ;子程序?qū)嶓w,具體指令由程序功能決定 POP Acc POP PSW ;恢復(fù)現(xiàn)場RET ;子程序最后一條指令,使子程序指令運(yùn)行結(jié)束后,返回主程序斷點

13、。 4.1 概述 - 中斷服務(wù)程序結(jié)構(gòu) - ORG kkkk ;其中kkkk就是中斷程序代碼存放區(qū)的首地址 PUSH PSW PUSH Acc ;通過PUSH指令保護(hù)中斷服務(wù)程序中用到的有關(guān)寄存器,如 Acc、PSW等,即保護(hù)現(xiàn)場 ;中斷服務(wù)程序?qū)嶓w,具體指令由程序功能決定POP AccPOP PSW ;恢復(fù)現(xiàn)場4.1 概述CLR TI ;清除中斷標(biāo)志(在51系列中,對于電平觸發(fā)的外中斷INT0和 INT1、串行接收及發(fā)送中斷 RI、TI等,不自動清除,需要在中斷服務(wù)結(jié)束前,通過CLR指令清除。RETI ;中斷服務(wù)程序最后一條指令,返回主程序斷點。為了確保子程序、中斷服務(wù)程序運(yùn)行結(jié)束后,能夠正

14、確返回,從斷點處繼續(xù)執(zhí)行主程序,必須注意在子程序以及中斷服務(wù)程序中堆棧操作指令的匹配問題,否則將無法返回。4.1 概述例4.10 在上述子程序結(jié)構(gòu)中,假設(shè)SUB1子程序入口地址為2000H,即主程序內(nèi)“LCALL SUB1”指令等效于“LCALL 2000”。假設(shè)該指令機(jī)器碼首地址為1000H,且指令執(zhí)行前,SP=5FH,則“LCALL 2000” 指令執(zhí)行過程中PC和SP內(nèi)容如下: (1) PCPC+3 ,即PC=1003H( 即斷點地址 ); (2) SPSP+1,即SP=60H,并把PC低8位壓入堆棧,于是(60H)=03; (3) SPSP+1,即SP=61H,并把PC高8位壓入堆 棧

15、,于是(61H)=10;4.1 概述 (4) 把 SUB1入口地址裝入PC,即 PC=2000H。 可見,“LCALL 2000”指令執(zhí)行后,PC=2000H,已指向子程序SUB1第一條指令所在的存儲單元地址;SP=61H。 在子程序中 PUSH Acc ;執(zhí)行后,SP=62H,(62H)就是Acc的當(dāng)前值,假設(shè)為XX PUSH PSW ;執(zhí)行后,SP=63H,(63H)就是PSW的當(dāng) 前值,假設(shè)為YY返回前 POP PSW ;執(zhí)行后,PSW(SP),即將(63H)單元4.1 概述中原來的PSW返回給PSW;SPSP1,即SP=62HPOP Acc ;執(zhí)行后,ACC(SP),即將(62H)單元

16、中原來的Acc返回給Acc ;SPSP1,即SP=61HRET ;執(zhí)行后,PC高8位(SP),即將(61H)單元內(nèi)容10H傳給PC高8位,SPSP1,即SP=60H;PC低8位(SP),即將(60H)單元內(nèi)容03H傳給PC;低8位,SPSP1,即SP=5FH 結(jié)果PC=1003H(重新裝入主程序斷點地址) 4.1 概述匯編語言程序按其結(jié)構(gòu)可分為以下四類: (1)順序結(jié)構(gòu); (2)分支結(jié)構(gòu); (3)循環(huán)結(jié)構(gòu); (4)子程序結(jié)構(gòu)。4.2 順序結(jié)構(gòu)程序4.2 順序結(jié)構(gòu)程序 最簡單的一種結(jié)構(gòu),又稱簡單程序。 特點: 按照程序編寫的順序依次執(zhí)行,不發(fā)生任何分支 或轉(zhuǎn)移。(程序走向只有一條路徑。)例4.1

17、1 將兩個半字節(jié)數(shù)組合成一個字節(jié)數(shù)。 設(shè)內(nèi)部RAM中40H、41H單元分別存放著8位二進(jìn)制數(shù),要求將兩個單元中的低半字節(jié)合并成一個字節(jié)后,存入42H單元。40H的低4位作為42H的高4位。4.2 順序結(jié)構(gòu)程序分析: 首先要取數(shù)送A(傳送指令),分離出低4位(邏輯與0FH),用A半字節(jié)交換送到高4位,地址加1,取另一個數(shù)低4位數(shù)(邏輯與0FH),用或合成一個字節(jié)。 解: START:MOV R1,#40H MOV A,R1 ANL A,#0FH ;取第一個半字節(jié) SWAP A ;移至高4位4.2 順序結(jié)構(gòu)程序 INC R1XCH A,R1;取第二個字節(jié)ANL A,#0FH ;取第二個半字節(jié)ORL

18、 A,R1;拼字INC R1MOV R1,A ;存放結(jié)果RET例4.12 將20H單元的兩個BCD碼拆開并變成ASC碼,存入21H、22H單元。注意:ASC碼09為30H39H。分析: 4.2 順序結(jié)構(gòu)程序把BCD數(shù)除以10,商A余B,剛好把兩個BCD碼分別移到A、B的低4位,然后再各自與30H相“或”,即變成ASC碼。其程序框圖如圖4-1所示。 采用先把20H中低4位BCD碼交換出來加以轉(zhuǎn)換、存放,然后再把高4位BCD碼交換至低4位加以轉(zhuǎn)換、存放。其程序框圖如圖4-2所示。4.2 順序結(jié)構(gòu)程序圖4-1 BCD碼轉(zhuǎn)換為ASCII碼方法一流程圖解 4.2 順序結(jié)構(gòu)程序 編程: ORG 2000H

19、MOV A,20HMOV B,#0AH ;用0AH作除數(shù)DIV ABORL B,#30H ;低4位BCD碼變成ASC碼MOV 22H,B ORL A,#30H ;高4位BCD碼變成ASC碼 MOV 21H,AEND 4.2 順序結(jié)構(gòu)程序圖4-2 BCD碼轉(zhuǎn)換為ASCII碼方法二流程圖解 4.2 順序結(jié)構(gòu)程序 編程: ORG 2000HMOV R0,#22HMOV R0,#00H MOV A,20HXCHD A,R0 ORL 22H,#30H SWAP AORL A,#30HMOV 21H,AEND 4.3 分支結(jié)構(gòu)程序4.3 分支結(jié)構(gòu)程序一、分支程序設(shè)計綜述分支結(jié)構(gòu)程序:根據(jù)程序要求無條件或有

20、條件改變程序執(zhí)行的順序,選擇程序的流向。 特點:程序中含有轉(zhuǎn)移類指令。 關(guān)鍵:正確選用轉(zhuǎn)移指令。 單重分支程序:一個判斷決策框,程序有兩條出路。4.3 分支結(jié)構(gòu)程序兩種分支結(jié)構(gòu) 4.3 分支結(jié)構(gòu)程序轉(zhuǎn)移指令有3種: 1、無條件轉(zhuǎn)移 程序轉(zhuǎn)移方向是設(shè)計者事先安排的,與已執(zhí)行程序的結(jié)果無關(guān),使用時只需給出正確的轉(zhuǎn)移目標(biāo)地址或偏移量即可。(LJMP、AJMP 、SJMP) 2、條件轉(zhuǎn)移 根據(jù)已執(zhí)行程序?qū)?biāo)志位或A或?qū)?nèi)部RAM某位的影響結(jié)果,決定程序的走向,形成各種分支。(JZ/JNZ、CJNE、DJNZ、位控制轉(zhuǎn)移類指令) 在編寫有條件轉(zhuǎn)移語句時要特別注意以下兩點: (1)在使用條件轉(zhuǎn)移指令形成分

21、支前,一定要安排可供條件轉(zhuǎn)移指令進(jìn)行判別的條件。4.3 分支結(jié)構(gòu)程序例如,若采用“JC rel”指令,在執(zhí)行此指令前必須使用影響Cy標(biāo)志的指令;若采用“CJNE A,#data,rel”指令,在執(zhí)行此指令前必須使用改變A內(nèi)容的指令,以便為測試做準(zhǔn)備。 (2)要正確選定所用的轉(zhuǎn)移條件和轉(zhuǎn)移目標(biāo)地址。3、散轉(zhuǎn)(JMPA+DPTR ) 它是根據(jù)某種已輸入的“或”運(yùn)算的結(jié)果,使程序轉(zhuǎn)向各個處理程序中去。 操作:把16位DPTR的內(nèi)容與“或”運(yùn)算的結(jié)果與在A中的8位無符號數(shù)相加,形成地址,裝入PC,即散轉(zhuǎn)的目的地址。其操作結(jié)果不影響A和DPTR。(JMP)4.3 分支結(jié)構(gòu)程序二、無條件/條件轉(zhuǎn)移程序 分

22、支程序中最常見的一類。其中,條件轉(zhuǎn)移類程序編寫較容易出錯,編寫時需要確定轉(zhuǎn)移條件。 例4.13 兩個無符號數(shù)比較大小。同P59頁例4-7 解 設(shè)外部RAM存儲單元ST1和ST2中存放兩個不帶符號的二進(jìn)制數(shù),找出其中的大數(shù)存入ST3單元中。4.3 分支結(jié)構(gòu)程序圖4-3 兩個無符號數(shù)比較大小程序框圖 4.3 分支結(jié)構(gòu)程序解: ORG 8000H ST1 EQU 8040HSTART:CLR C ;進(jìn)位位清0 MOV DPTR,#ST1 ;讀數(shù)據(jù)指針 MOVX A,DPTR ;取第一個數(shù) MOV R2,A ;暫存R2 INC DPTR MOVX A,DPTR ;取第二個數(shù) SUBB A,R2 ;兩數(shù)

23、比較 JNC BIG1 ;若Cy=0,則轉(zhuǎn)BIG1(第二個數(shù)大)4.3 分支結(jié)構(gòu)程序 XCH A,R2 ;第一個數(shù)大 BIG0:INC DPTR MOVX DPTR,A ;存大數(shù) RET BIG1:MOVX A,DPTR ;第二個數(shù)大 SJMP BIG0 END 上面程序中,應(yīng)用帶借位的減法指令SUBB比較兩數(shù)的大小。在執(zhí)行指令前,應(yīng)先把進(jìn)位位清“0”。執(zhí)行JNC指令后形成分支,指令中BIG1為標(biāo)號地址,表示相對偏移量rel。 4.3 分支結(jié)構(gòu)程序例4.14 設(shè)5AH單元中有一變量X,請編寫計算下列函數(shù)式的程序,結(jié)果存入5BH單元。 同P61頁例4-8. 4.3 分支結(jié)構(gòu)程序圖4-4 例4.6

24、程序流程圖4.3 分支結(jié)構(gòu)程序 解:根據(jù)題意首先計算X2(使用乘法)并暫存于R1中,因為X2最大值為225,可只用一個寄存器,然后根據(jù)X值的范圍,決定Y的值。R0作中間寄存器。 編程:ORG 2000H MOV A,5AH MOV B,A MUL AB ;AX2 MOV R1,A MOV A,5AH ;重新把X裝入A CJNE A,#10,L14.3 分支結(jié)構(gòu)程序L1:JC L2 ;C=1,X10轉(zhuǎn)L2MOV R0,#41 ;先假設(shè)X15 CJNE A,#10H,L3 ;與16比較 L3:JNC L4 ; C=0,X15轉(zhuǎn)L4 MOV A,R1 ADD A,#8 ;10X15,Y=X2+8 M

25、OV R0,A SJMP L4 L2:MOV A,R1CLR CSUBB A,#01 ;X10,Y=X2-14.3 分支結(jié)構(gòu)程序 MOV R0,A L4:MOV 5BH,R0 ;存結(jié)果 SJMP $ END 由于本題的具體情況,在判別(A)10和(A)15時采用的是“CJNE”和“JC”以及“CJNE”和“JNC”兩條指令相結(jié)合的方法。 條件分支程序與簡單程序的區(qū)別在于:分支程序存在兩個或兩個以上的結(jié)果。要根據(jù)給定的條件進(jìn)行判斷,以得到某一個結(jié)果。這樣,就要用到比較命令、測試指令以及無條件/條件轉(zhuǎn)移指令。條件分支程序設(shè)計 的技巧,就在于正確而巧妙地使用這些命令。 4.3 分支結(jié)構(gòu)程序例題:求符

26、號函數(shù)的值。已知片內(nèi)RAM的40H單元內(nèi)有一自變量X,編制程序按如下條件求函數(shù)Y的值,并將其存入片內(nèi)RAM的41H單元中。 1 X0Y= 0 X=0 -1X255,因此單重循環(huán)程序無法實現(xiàn),可采用雙重循環(huán)的方法編寫50ms延時程序。 程序如下: ORG 1000H DELAY: MOV R7, #200 ; 設(shè)置外循環(huán)次數(shù)(此條指令需要1個機(jī)器周期) DLY1: MOV R6, #123 ; 設(shè)置內(nèi)循環(huán)次數(shù) DLY2: DJNZ R6, DLY2 ;(R6)1=0,則順序執(zhí)行,否則轉(zhuǎn)回DLY2繼續(xù)循環(huán),延時時間為2s123=246s NOP ; 延時時間為1s DJNZ R7,DLY1 ;(R

27、7)1=0,則順序執(zhí)行,否則轉(zhuǎn)回DLY1繼續(xù)循環(huán),延時時間為(246211)20021=50.003ms RET ; 子程序結(jié)束 END4.4 循環(huán)結(jié)構(gòu)程序例4.13 將20H單元內(nèi)的兩個BCD數(shù)相乘,相乘的結(jié)果要求仍為BCD數(shù),乘積存入21H單元。 分析:兩個BCD數(shù)最大的是99,99=81。若采用“MUL”指令,則結(jié)果為51H,而對乘法沒有十進(jìn)制調(diào)整指令。所以,在此必須采用加法與十進(jìn)制調(diào)整指令重復(fù)執(zhí)行的方法。4.4 循環(huán)結(jié)構(gòu)程序 圖4-8 BCD數(shù)乘法流程圖 4.4 循環(huán)結(jié)構(gòu)程序 解 ORG 2000H MOV A,20H ANL A,#0FH;把BCD數(shù)的低位分離出來 MOV R0,A

28、MOV A,20H SWAP A;變換BCD數(shù)的高低位 ANL A,#0FH;把BCD數(shù)的高位分離出來 MOV R1,A CLR A;清A4.4 循環(huán)結(jié)構(gòu)程序 LP:ADD A,R1 DA A DJNZ R0,LP ;R0個R1相加 MOV 21H,A LP1:SJMP LP1 END本程序中,循環(huán)體只有ADD、DA、DJNZ 3條指令,這3條指令的作用是把乘法變?yōu)槔奂印?.4 循環(huán)結(jié)構(gòu)程序例4.14 冒泡程序。 設(shè)有n個數(shù),分別存放在RAM中LIST地址開始的連續(xù)存儲單元中,要求將n個數(shù)比較大小之后,按由小到大的次序排列,再存入原存儲區(qū)。設(shè)n=7,參與比較的數(shù)為0,13,3,90,27,32

29、,11。 分析: 依次將相鄰兩個單元的內(nèi)容進(jìn)行比較。即第一個數(shù)與第二個數(shù)進(jìn)行比較,第二個數(shù)與第三個數(shù)進(jìn)行比較,依此進(jìn)行,如符合由小到大的順序,則不改變它們在內(nèi)存中的位置,否則交換它們之間的位置。如此反復(fù)比較,直到數(shù)列排完為止。 4.4 循環(huán)結(jié)構(gòu)程序 由于在比較過程中,小數(shù)向上冒,因此這種排序程序稱為“冒泡程序”,比較過程如下: 4.4 循環(huán)結(jié)構(gòu)程序 第一輪經(jīng)過6次兩兩比較,得到一個最大數(shù);第二輪經(jīng)過5次兩兩比較,得到一個次大數(shù); 依此類推。每輪比較后得到本輪最大數(shù),該數(shù)就不再參與下一輪的比較,故每輪比較次數(shù)減1。為加快排序速度,程序中設(shè)置一個標(biāo)志位,只要在比較過程中兩數(shù)之間沒有發(fā)生過交換,就表

30、示數(shù)列已按由小到大的順序排列好了,就可以結(jié)束比較。 4.4 循環(huán)結(jié)構(gòu)程序 圖4-9 冒泡程序流程圖 4.4 循環(huán)結(jié)構(gòu)程序 設(shè)數(shù)列首地址存于R0中,R2為外循環(huán)次數(shù)計數(shù)器,R3為內(nèi)循環(huán)次數(shù)計數(shù)器,R1為交換標(biāo)志。解 ORG 0050H LIST DB 0,13,3,90,27,32,11 CNT EQU 07H ORG 8000H MOV R2,#CNT-1 ;數(shù)列個數(shù)減1,這里(R2)=7-1 4.4 循環(huán)結(jié)構(gòu)程序 LOOP1: MOV A,R2 ;外循環(huán)計數(shù)值 MOV R3,A ;內(nèi)循環(huán)計數(shù) MOV R1,#01H ;交換標(biāo)志位 LOOP2:MOV A,R0;取數(shù)據(jù) MOV B,A ;暫存B

31、 INC R0 CLR C SUBB A,R0 ;兩數(shù)比較 JC LESS ;XiXi+1轉(zhuǎn)LESS4.4 循環(huán)結(jié)構(gòu)程序 MOV A,B ;取大數(shù) XCH A,R0 ;兩數(shù)交換位置 DEC R0 MOV R0,A INC R0 ;恢復(fù)數(shù)據(jù)指針 MOV R1,#02H;置交換標(biāo)志位為2 LESS:DJNZ R3,LOOP2 ;內(nèi)循環(huán)計數(shù)減1,判一遍查完? DJNZ R2,LOOP3;外循環(huán)計數(shù)減1,判排序結(jié)束? STOP:RET4.4 循環(huán)結(jié)構(gòu)程序 LOOP3:DJNZ R1,LOOP1 ;發(fā)生交換轉(zhuǎn)移 SJMP STOP END 練習(xí)題:200名學(xué)生參加考試,成績放在80C51的外部RAM的一

32、個連續(xù)存儲單元,95100分頒發(fā)A級證書,9094分頒發(fā)B級證書,低于90分不計。編寫程序,統(tǒng)計獲A、B級證書的人數(shù)。將結(jié)果存入內(nèi)部RAM的兩個單元。 注意:地址指針的分配 參考程序:4.4 循環(huán)結(jié)構(gòu)程序 ORG 0030H EGX DATA 1000H;存放成績的外部連續(xù)存儲單元起始地址 GA DATA 20H;設(shè)置存放獲取A級證書人數(shù)的單元 GB DATA 21H;設(shè)置存放獲取B級證書人數(shù)的單元 MOV GA,#00 MOV GB,#00 MOV DPTR,#EGX ;初始化,數(shù)據(jù)塊首地址 MOV R2,#200 ;定義計數(shù)器,200名學(xué)生數(shù)LOOP: MOVX A,DPTR CJNE A

33、,#95, LOOP1 4.4 循環(huán)結(jié)構(gòu)程序 LOOP1:JNC NEXT1 ;C=0,A=95轉(zhuǎn)至NEXT1 CJNE A,#90,LOOP2 LOOP2:JC NEXT INC GB SJMP NEXT NEXT1:INC GA NEXT:INC DPTR DJNZ R2,LOOP SJMP $ END4.5 子程序結(jié)構(gòu)4.5 子程序結(jié)構(gòu)一、概念子程序:完成確定任務(wù),并能為其他程序反復(fù)調(diào)用的程序段。 要求子程序在結(jié)構(gòu)上具有通用性和獨立性。例如:代碼轉(zhuǎn)換,運(yùn)算程序,任意數(shù)的平方等。 子程序的調(diào)用與返回: 主程序調(diào)用子程序的過程:在主程序中需要執(zhí)行這種操作的地方執(zhí)行一條調(diào)用指令(LCALL或A

34、CALL),轉(zhuǎn)到子程序,而完成規(guī)定的操作后,再在子程序最后應(yīng)用RET返回指令返回到主程序斷點處,繼續(xù)執(zhí)行下去。4.5 子程序結(jié)構(gòu)子程序的調(diào)用子程序的入口地址:子程序的第一條指令地址,常用標(biāo)號表示。程序的調(diào)用過程:單片機(jī)收到ACALL或LCALL指令后,首先將當(dāng)前的PC值(調(diào)用指令的下一條指令的首地址)壓入堆棧保存(低8位先進(jìn)棧,高8位后進(jìn)棧),然后將子程序的入口地址送入PC,轉(zhuǎn)去執(zhí)行子程序。子程序的返回主程序的斷點地址:子程序執(zhí)行完畢后,返回主程序的地址,它在堆棧中保存。子程序的返回過程:子程序執(zhí)行到RET指令后,將壓入堆棧的斷點地址彈回給PC(先彈回PC的高8位,后彈回PC的低8位),使程序

35、回到原先被中斷的主程序地址(斷點地址)去繼續(xù)執(zhí)行。4.5 子程序結(jié)構(gòu)注意:中斷服務(wù)程序是一種特殊的子程序,它是在計算機(jī)響應(yīng)中斷時,由硬件完成調(diào)用而進(jìn)入相應(yīng)的中斷服務(wù)程序。RETI指令與RET指令相似,區(qū)別在于RET是從子程序返回,RETI是從中斷服務(wù)程序返回。 子程序優(yōu)點: 簡化了程序的邏輯結(jié)構(gòu);提高編程效率,便于調(diào)試;節(jié)省存儲器的空間。4.5 子程序結(jié)構(gòu)與子程序調(diào)用有關(guān)的指令: 兩條調(diào)用子程序指令:ACALL addr11;LCALL addr16一條返回主程序指令:RET二、子程序設(shè)計要點 1、第一條語句前必須有標(biāo)號。 2、子程序最后應(yīng)以返回指令(RET)結(jié)尾。 3、在主程序中設(shè)置堆棧。凡

36、有子程序的程序,主程序初始化一定要設(shè)置棧底和棧區(qū),以免造成混亂和錯誤。因調(diào)用子程序時,主程序的斷點將自動入棧,轉(zhuǎn)入子程序后,現(xiàn)場的保護(hù)都要占用堆棧工作單元。4.5 子程序結(jié)構(gòu) 4、保護(hù)和恢復(fù)現(xiàn)場 在轉(zhuǎn)入子程序時,特別是進(jìn)入中斷服務(wù)子程序時,要特別注意保護(hù)現(xiàn)場的問題。主程序使用的A、DPTR、PWS、R0R7等,不應(yīng)因轉(zhuǎn)入子程序而改變。若兩者使用的寄存器有沖突,則必須在轉(zhuǎn)入子程序后首先保護(hù)現(xiàn)場,即把要保護(hù)的單元壓堆棧;返回主程序前恢復(fù)現(xiàn)場,即出棧。4.5 子程序結(jié)構(gòu) 5、參數(shù)傳遞 指調(diào)用子程序時,主程序應(yīng)把有關(guān)的參數(shù)(入口參數(shù))存放在約定的位置,子程序在執(zhí)行時,可以從約定的位置取得參數(shù),當(dāng)子程序

37、執(zhí)行完,將得到的結(jié)果(出口參數(shù))存入約定的位置,返回主程序后,主程序可以從這些約定的位置上取得需要的結(jié)果。4.5 子程序結(jié)構(gòu)幾種參數(shù)傳遞方法: 用A或寄存器傳遞;(如:例4.15) 用地址指針寄存器(R0、R1、DPTR)傳遞;(如:例4.16) 用堆棧傳遞參數(shù)。(如:例4.17)三、子程序的嵌套 在實際應(yīng)用中,子程序中調(diào)用子程序的情況。4.5 子程序結(jié)構(gòu)四、舉例例4.15 設(shè)a、b、c分別存放在內(nèi)部RAM的40H、41H、42H單元中,a、b均小于10。試編程計算: 分析:用子程序來實現(xiàn)某數(shù)的平方,即通過調(diào)用子程序查平方表,結(jié)果在主程序中得到。4.5 子程序結(jié)構(gòu) 圖4-10 程序框圖 4.5

38、 子程序結(jié)構(gòu) 主程序: MAIN: MOV A,40H ACALL SQR ;調(diào)查表子程序MOV R1,A ;a2暫存R1中MOV A,41H ACALL SQR ;調(diào)查表子程序ADD A,R1MOV 42H,ASJMP $ ;等待4.5 子程序結(jié)構(gòu) 子程序: SQR: INC A MOVC A,A+PC ;查平方表 RET ;單字節(jié) TAB: DB 0,1,4,9,16 DB 25,36,49,64,81 該程序中子程序的入口條件(A)=待查表的數(shù),出口條件(A)=待查表數(shù)的平方。4.5 子程序結(jié)構(gòu)例4.16 求兩個無符號數(shù)據(jù)塊中的最大值。數(shù)據(jù)塊的首地址分別為60H和70H,每個數(shù)據(jù)塊的第一

39、個字節(jié)都存放數(shù)據(jù)塊長度。結(jié)果存入5FH單元。 分析:可采用分別求出兩個數(shù)據(jù)塊的最大值,然后比較其大小的方法。求最大值的過程可采用子程序。子程序的入口條件是數(shù)據(jù)塊首地址,返回參數(shù)即為最大值,放在A中。4.5 子程序結(jié)構(gòu) 解:主程序:ORG 2000HMOV R1,#60H ;置入口條件參數(shù)ACALL QMAX ;調(diào)用求最大值子程序MOV 40H,A ;第一個數(shù)據(jù)塊的最大值暫存40H MOV R1,#70H ;置入口條件參數(shù)ACALL QMAX ;調(diào)求最大值子程序CJNE A,40H,NEXT ;兩個最大值進(jìn)行比較NEXT:JNC LP ;A大則轉(zhuǎn)LP MOV A,40H ;A小則把40H單元中的

40、內(nèi)容送入A LP: MOV 5FH,A;把兩個數(shù)據(jù)塊的最大值送入5FH SJMP $4.5 子程序結(jié)構(gòu)子程序: ORG 2200HQMAX:MOV A,R1 ;取數(shù)據(jù)塊長度MOV R2,A ;設(shè)置計數(shù)值CLR A ;設(shè)0為最大值,最大值放入A中 LP1:INC R1 ;修改地址指針 CLR C SUBB A,R1 ;兩數(shù)相減 JNC LP3 ;原數(shù)仍為最大值,轉(zhuǎn)LP3 MOV A,R1 ;否,用此數(shù)代替最大值 SJMP LP4 ;無條件轉(zhuǎn)LP4 LP3: ADD A,R1 ;恢復(fù)原最大值 LP4: DJNZ R2,LP1 ;若沒比較完,繼續(xù)比較 RET ;比較完,返回 4.5 子程序結(jié)構(gòu)例4.

41、17 在50H單元中存放著兩個十六進(jìn)制數(shù)字,編程使它們分別轉(zhuǎn)換成ASC碼,并存入51H和52H單元。 解:十六進(jìn)制數(shù)轉(zhuǎn)換成ASC碼的過程可采用子程序。這里采用堆棧來傳遞參數(shù)。 主程序:ORG 2000HMOV SP,#3FH;設(shè)堆棧指針PUSH 50H ;把50H單元內(nèi)的數(shù)壓入堆棧ACALL HASC ;調(diào)子程序,并把主程序的斷點地址高、低位(PCH、PCL)分別壓入41H、42H單元 POP 51H ;把已轉(zhuǎn)換的低半字節(jié)的ASC碼彈入51H單元接下頁4.5 子程序結(jié)構(gòu)MOV A,50H SWAP A ;準(zhǔn)備處理高半字節(jié)的十六進(jìn)制數(shù) PUSH A ACALL HASC POP 52H ;把已轉(zhuǎn)

42、換的高半字節(jié)的ASC碼彈入52H單元 SJMP $接下頁4.5 子程序結(jié)構(gòu)子程序: ORG 3000H HASC:DEC SP DEC SP ;兩次執(zhí)行“DEC SP”,把堆棧指針修正到40H POP A ;把40H中的原50H單元內(nèi)的數(shù)據(jù)彈入到A中 ANL A,#0FH ;屏蔽高4位 ADD A,#07 ;修正查表位置 MOVC A,APC ;取表中數(shù)至A PUSH A ;將已轉(zhuǎn)換的ASC碼值壓入堆棧的40H單元,2字節(jié)指令 INC SP ;修改SP指針到斷點位置, 2字節(jié)指令 INC SP ;兩次執(zhí)行“INC SP”,SP變?yōu)?2H, 2字節(jié)指令 RET ;把原斷點內(nèi)容又送回PC,SP又指

43、向40H 1字節(jié)指令 TAB:DB 0,1,2,3,4,5,6,7 DB 8,9,A,B,C,D,E,F(xiàn) 4.5 子程序結(jié)構(gòu) 圖4-11 堆棧操作示意圖 4.5 子程序結(jié)構(gòu)說明:本題也可以不采用堆棧傳遞參數(shù)的辦法,此時可以用ACC既作為入口條件,也作為出口條件來傳遞參數(shù)。在主程序中把“PUSH 50H”改為“MOV A,50H”;把“POP 51H”改為“MOV 51H,A”;依次類推。在子程序中把6條有關(guān)堆棧的操作指令都去掉;再把“ADD A,#07”改為“ADD A,#01”即可。4.5 子程序結(jié)構(gòu)練習(xí)題1: M1和M1+1單元存有16位二進(jìn)制數(shù),試編程將其擴(kuò)大二倍。 參考答案: CLR

44、C MOV R1,#M1 MOV A,R1 RLC A MOV R1,A INC R1 MOV A,R1 RLC A MOV R1,ASJMP $4.5 子程序結(jié)構(gòu) 練習(xí)題2:將內(nèi)部ROM的60H、61H單元中的連續(xù)存放著4位BCD碼。試編寫一段程序?qū)⑦@4位BCD碼倒序排列。 參考答案: MOV R0,#60H MOV R1,#61H MOV A,R0 SWAP A XCH A,R1 SWAP A MOV R0,A4.5 子程序結(jié)構(gòu) 練習(xí)題3:已知外部RAM的3000H開始放一數(shù)據(jù)區(qū),緩沖區(qū)中以回車符0DH結(jié)束。 編程:將正數(shù)送入片內(nèi)RAM以30H開始的正數(shù)區(qū),將負(fù)數(shù)放入以40H開始的負(fù)數(shù)區(qū)。

45、 參考答案: 4.5 子程序結(jié)構(gòu) 解法一: MOV R0,#30HMOV R1,#40HMOV DPTR,#3000HNEXT: MOVX A, DPTRMOV 10H,ACJNE A,#0DH,END1;#0DH與A中內(nèi)容不相等轉(zhuǎn)至END1處,(A)0DH,C=0;(A)0DH,C=1SJMP OVER ;相對轉(zhuǎn)移到OVER處4.5 子程序結(jié)構(gòu) END1: ANL A,#10000000B;判斷正負(fù)數(shù)JZ ZH;(A)=0,轉(zhuǎn)移到ZH處SJMP NEG ZH: MOV R0,10H;存放正數(shù)程序段INC R0INC DPTRSJMP NEXT NEG: MOV R1,10H;存放負(fù)數(shù)程序段

46、INC R1 INC DPTR SJMP NEXTOVER: RET 4.5 子程序結(jié)構(gòu)解法二: MOV R0,#30HMOV R1,#40HMOV DPTR,#3000H NEXT: MOVX A, DPTRCJNE A,#0DH,COMPSJMP OVER COMP: JB ACC.7,LOOP;ACC.7=1程序轉(zhuǎn)移到LOOPMOV R0,A;存放正數(shù)程序段INC R0INC DPTR4.5 子程序結(jié)構(gòu) SJMP NEXTLOOP: MOV R1,A;存放負(fù)數(shù)程序段INC R1INC DPTRSJMP NEXTOVER: RET 4.6 綜合程序舉例4.6 綜合程序舉例一、查表程序 1、

47、查表程序 查表:根據(jù)變量x在表格中查找y,使y=f(x)。函數(shù)值y事先根據(jù)變量x的取值范圍計算出,并按一定規(guī)律編成表格存放在計算機(jī)的ROM中。當(dāng)用戶程序中需要用這些數(shù)據(jù)時,直接按編排的索引值(或程序號)尋找答案。 主要用于: LED顯示器控制、智能化儀表控制、打印機(jī)的打印以及數(shù)據(jù)計算、復(fù)雜函數(shù)計算:Y=SIN(X); 數(shù)據(jù)補(bǔ)償:傳感器補(bǔ)償、復(fù)雜代碼轉(zhuǎn)換顯示等功能程序中。4.6 綜合程序舉例 在51中有兩條查表指令: MOVC A,A+DPTR;MOVC A,A+PC1.采用MOVC A, A+DPTR指令查表程序的設(shè)計方法在ROM中建立相應(yīng)的函數(shù)表(設(shè)自變量為X)。計算出這個表中所有的函數(shù)值Y

48、。將這群函數(shù)值按順序存放在起始(基)地址為TABLE的ROM中。將表格首地址TABLE送入DPTR,X送入A,采用查表指令MOVC A, A+DPTR完成查表,就可以得到與X相對應(yīng)的Y值于A中。4.6 綜合程序舉例2.采用MOVC A, A+PC指令查表程序的設(shè)計方法 當(dāng)使用PC作為基址寄存器時,由于PC本身是一個程序計數(shù)器,與指令的存放地址有關(guān),查表時其操作有所不同。在ROM中建立相應(yīng)的函數(shù)表(設(shè)自變量為X)。計算出這個表中所有的函數(shù)值Y。將這群函數(shù)值按順序存放在起始(基)地址為TABLE的ROM中。X送入A,使用ADD A, #data指令對A的內(nèi)容進(jìn)行修正,偏移量data由公式data=

49、函數(shù)數(shù)據(jù)表首地址PC1確定,即data值等于查表指令和函數(shù)表之間的字節(jié)數(shù)。采用查表指令MOVC A, A+PC完成查表。 4.6 綜合程序舉例例題利用查表的方法編寫Y=X2(X=0, 1, 2, 9)的程序解:設(shè)變量X的值存放在內(nèi)存30H單元中,求得的Y的值存放在內(nèi)存31H單元中。平方表存放在首地址為TABLE的ROM中。方法一:采用MOVC A, A+DPTR指令實現(xiàn),查表過程如下圖所示。程序如下: ORG 1000H START: MOV A, 30H ; 將查表的變量X送入A MOV DPTR, #TABLE ; 將查表的16位基地址TABLE送DPTR MOVC A, A+DPTR ;

50、 將查表結(jié)果Y送A MOV 31H, A ; Y值最后放入31H中 TABLE: DB 0, 1, 4, 9, 16 DB 25, 36, 49, 64, 81 END方法二:采用MOVC A, A+PC指令實現(xiàn),查表過程如下頁圖所示。程序如下: ORG 1000H START: MOV A, 30H ; 將查表的變量X送入A ADD A, #02H ; 定位修正 MOVC A, A+PC ; 將查表結(jié)果Y送A MOV 31H, A ; Y值最后放入31H中 TABLE: DB 0, 1, 4, 9, 16 DB 25, 36, 49, 64, 81 END 4.6 綜合程序舉例2、查表程序優(yōu)

51、點 程序簡單、執(zhí)行速度快。3、查表程序有多種結(jié)構(gòu)形式,下面介紹兩種常用查表程序。 例4.18 設(shè)計一個將16進(jìn)制數(shù)轉(zhuǎn)換成ASC碼的子程序。設(shè)16進(jìn)制數(shù)存放在R0中的低4位,要求將轉(zhuǎn)換后的ASC碼送回R0中。 解:已知09的ASC碼為30H39H,AF的ASC碼為41H46H。按題意程序的入口和出口都在R0中,表中所有的值都是單字節(jié),表格長度為16個字節(jié)(0F)。4.6 綜合程序舉例參考程序: ORG 2160H MOV A,R0 ANL A,#0FH ;保留低4位 ADD A,#02H ;變址調(diào)整,因為“MOVC A,A+PC”指令與表格首址相隔兩個字節(jié),故變址調(diào)整值為2 MOVC A,A+P

52、C ;查表得ASC值 MOV R0,A RET4.6 綜合程序舉例 TAB:DB 30H,31H,32H DB 33H,34H,35H DB 36H,37H,38H DB 39H,41H,42H DB 43H,44H,45H,46H 4.6 綜合程序舉例 例4.19 某智能化儀器的鍵盤程序中,根據(jù)命令的鍵值(0,1,2,9),轉(zhuǎn)換成相應(yīng)的雙字節(jié)16位命令操作地址,其鍵入值與對應(yīng)入口關(guān)系如下: 設(shè)鍵值存放在20H單元中,出口地址值存放在22H,23H單元中。參考程序: ORG 2200H MOV DPTR,#TAB ;指向表首高8位 MOV A,20H ;取鍵值 鍵值 0 12 3 456789

53、入口地址01230186023403160415052006260710081809294.6 綜合程序舉例 RL A ;因函數(shù)值y為雙字節(jié),所以把鍵值乘2作查表偏移量 MOV 20H,A ;暫存偏移量 MOVC A,A+DPTR ;取高8位地址 MOV 22H,A ;暫存高8位地址 INC DPTR ;指向表首低8位 MOV A,20H ;取偏移量 MOVC A,A+DPTR ;取低8位地址 MOV 23H,A ;暫存低8位地址 RET TAB: DB 01,23H ;“0”鍵入口地址 DB 01,86H ;“1”鍵入口地址 4.6 綜合程序舉例 DB 02,34H ;“2”鍵入口地址 DB

54、 03,16H ;“3”鍵入口地址 DB 04,15H ;“4”鍵入口地址 DB 05,20H ;“5”鍵入口地址 DB 06,26H ;“6”鍵入口地址 DB 07,10H ;“7”鍵入口地址 DB 08,18H ;“8”鍵入口地址 DB 09,29H ;“9”鍵入口地址 4.6 綜合程序舉例二、代碼轉(zhuǎn)換程序 例4.20 將A中00FF范圍內(nèi)二進(jìn)制數(shù)轉(zhuǎn)換為BCD碼(0255)。分析:BCD碼是四位二進(jìn)制數(shù)表示的十進(jìn)制數(shù)。它在單片機(jī)中有兩種存放形式: 一種是一個字節(jié)放一位BCD碼,高半字節(jié)取0,適用于顯示和輸出; 另一種是一個字節(jié)存放兩位BCD碼,即壓縮BCD碼,有利于節(jié)省存儲空間。本題所轉(zhuǎn)換

55、的最大BCD數(shù)是255,超過了一個字節(jié),因而把十位、個位以壓縮BCD碼的形式存放,把百位單獨存放。 .4.6 綜合程序舉例 編程思路:將A中十進(jìn)制數(shù)除以100、10,所得商即為百、十位數(shù),余數(shù)為個位數(shù)。結(jié)果存放在R0內(nèi)容為初始地址的單元中。參考程序: MOV B,#100 DIV AB ;A中為百位數(shù),B內(nèi)為余數(shù) MOV R0,A ;存入RAM單元 INC R0 ;修改地址指針 MOV A,#10 XCH A,B DIV AB ;A中為十位數(shù),B中為個位數(shù) SWAP A ;十位數(shù)移到高半字節(jié) ADD A,B ;形成十位和個位數(shù)的壓縮BCD碼 MOV R0,A ;存入RAM單元 RET4.6 綜

56、合程序舉例*例4.21 編寫多字節(jié)二進(jìn)制數(shù)轉(zhuǎn)換為BCD碼的程序。分析:若本例采用上例算法,需進(jìn)行多字節(jié)除法運(yùn)算,運(yùn)算速度慢,且程序通用性差。本程序采用圖4-12所示流程圖的算法編制。(a15a14a1a0)=( (02+a15)2+a14)2+a0,所以將二進(jìn)制數(shù)從最高位逐次向左移入BCD碼的最低位,并且每次都實現(xiàn)()*2+ai的運(yùn)算。 編程時應(yīng)注意兩點: (1)BCD碼數(shù)乘2不能用左移指令,只能用ADDC指令對BCD數(shù)自身相加一次且要用十進(jìn)制調(diào)整指令;4.6 綜合程序舉例 (2)二進(jìn)制數(shù)轉(zhuǎn)換后的壓縮BCD碼可能要比原來二進(jìn)制數(shù)多占一個字節(jié)單元。 入口:(BIND)= 二進(jìn)制數(shù)低位字節(jié)地址指針

57、; (BCDD)= BCD數(shù)個位數(shù)地址指針; (BYTES)= 二進(jìn)制數(shù)字節(jié)數(shù)。 出口:(BCDD)= BCD數(shù)個位數(shù)地址指針。4.6 綜合程序舉例 圖4-12 二進(jìn)制數(shù)轉(zhuǎn)換為BCD碼程序流程圖 4.6 綜合程序舉例 參考程序: ORG 2000H MOV R1,BCDD ;取BCD碼數(shù)個位地址 MOV R2,BYTES ;取二進(jìn)制數(shù)字節(jié)數(shù) INC R2 CLR A BB0:MOV R1,A ;清BCD單元 INC R1 DJNZ R2,BB0 4.6 綜合程序舉例 MOV A,BYTES MOV B,#08H MUL AB MOV R3,A ;存放二進(jìn)制數(shù)位數(shù) BB3: MOV R0,BIN

58、D ;取二進(jìn)制數(shù)位數(shù)低位地址 MOV R2,BYTES ;取二進(jìn)制數(shù)字節(jié)數(shù) CLR C BB1: MOV A,R0 4.6 綜合程序舉例 RLC A MOV R0,A INC R0 DJNZ R2,BB1 ;二進(jìn)制數(shù)左移 MOV R2,BYTES INC R2 MOV R1,BCDD BB2: MOV A,R1 4.6 綜合程序舉例 ADDC A,R1 ;BCD碼乘2 DA A ;十進(jìn)制調(diào)整 MOV R1,A INC R1 DJNZ R2,BB2 DJNZ R3,BB3 ;反復(fù)循環(huán) RET 4.6 綜合程序舉例例4.22 把A中的壓縮BCD碼轉(zhuǎn)換成二進(jìn)制數(shù)。 解: MOV R2,A ;暫存 A

59、NL A,#0F0H ;屏蔽低4位 SWAP A ;高、低4位交換 MOV B,#10 MUL AB ;乘法運(yùn)算,A中高半字節(jié)乘10 MOV R3,A ;暫存 MOV A,R2 ;取原數(shù) ANL A,#0FH ;取BCD個位 ADD A,R3 ;個位與十位數(shù)相加 RET4.6 綜合程序舉例 例4.23 將R0所指出單元中的ASC碼轉(zhuǎn)換成十六進(jìn)制數(shù),并把結(jié)果存放于原單元。 分析: 對于不大于9的數(shù),ASC代碼減去30H; 對于大于9的數(shù),ASC代碼減去37H,即得轉(zhuǎn)換后的十六進(jìn)制數(shù)。4.6 綜合程序舉例參考程序: MOV A,R0 ;取操作數(shù) CLR C SUBB A,#30H ;09的轉(zhuǎn)換 M

60、OV R0,A ;暫存結(jié)果 SUBB A,#0AH ;結(jié)果是否大于9 JC SB2 ;不大于9則返回 XCH A,R0 SUBB A,#07H ;大于9,則減37H MOV R0,A ;存結(jié)果 SB2: RET4.6 綜合程序舉例*例4.24 將R2中兩位16進(jìn)制數(shù)轉(zhuǎn)換成七段代碼,并存入R2R3中。 解:七段代碼是用七段發(fā)光二極管顯示一個數(shù),該數(shù)對應(yīng)的代碼為七段代碼。 圖4-13在七段代碼顯示器共陽極接法中,相應(yīng)段加上“0”電平時,該段亮。 由七段代碼表4-1可以看出,七段代碼和數(shù)字之間沒有什么規(guī)律,所以適合用查表的方法進(jìn)行轉(zhuǎn)換。先把七段代碼按0F的順序存入存儲器,表首地址TABS。利用代碼首

溫馨提示

  • 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

提交評論