人狗畜禽COMPANY LIMITED|全是肉的高H文〈男男〉|全篇肉高H秘书被C办公室四爱|全黄H全肉共妻|全黄H全肉短篇禁乱NP慕浅浅|全黄H全肉短篇N男男

技術(shù)熱線: 4007-888-234
設(shè)計開發(fā)

專注差異化嵌入式產(chǎn)品解決方案 給智能產(chǎn)品定制注入靈魂給予生命

開發(fā)工具

提供開發(fā)工具、應(yīng)用測試 完善的開發(fā)代碼案例庫分享

技術(shù)支持

從全面的產(chǎn)品導(dǎo)入到強大技術(shù)支援服務(wù) 全程貼心伴隨服務(wù),創(chuàng)造無限潛能!

新品推廣

提供新的芯片及解決方案,提升客戶產(chǎn)品競爭力

新聞中心

提供最新的單片機資訊,行業(yè)消息以及公司新聞動態(tài)

PIC單片機運算子程序(1)

更新時間: 2019-03-21
閱讀量:496

PIC16F877單片機運算子程序

 1  PIC16F877匯編語言程序主體框架

以下是一個典型的程序結(jié)構(gòu):

;***************程序說明區(qū)*******************

    LIST    p=16f877    ;指定微控制器型號和文件輸出格式

    INCLUDE    p16f877.inc    ;讀入MPLAB提供的定義文件P16F877.INC

;***片內(nèi)RAM常用資源、變量定義和相應(yīng)的說明*********

    ACCALO    EQU  20    ;存放加數(shù)或減數(shù)低8位

    ACCAHI     EQU  21    ;存放加數(shù)或減數(shù)高8位

    ACCBLO     EQU     23    ;存放被加數(shù)或被減數(shù)低8位

    ACCBHI     EQU     24    ;存放被加數(shù)或被減數(shù)高8位

    S_W    EQU     25    ;棧存W寄存器值

    S_STATUS    EQU    26    ;棧存STATUS寄存器值

;****************芯片復(fù)位矢量*******************

    ORG          0X0000    ;由于PIC16F877芯片復(fù)位矢量在0000h單

        ;元,所以常在0000h單元處放置一條跳轉(zhuǎn)

        ;指令,使單片機復(fù)位后能跳過中斷矢量,

                                ;直接執(zhí)行主程序

START    GOTO        MAIN        

;******************中斷矢量**********************

    ORG          0X0004    ;由于PIC16F877的中斷矢量為0004h,所以

        ;當中斷開放時, 需在此處加入中斷程序,

        ;使單片機能在中斷到來時及時進入相應(yīng)的

        ;中斷服務(wù)程序。為了可靠起見,如果單片

        ;機不使用中斷,則常常在該中斷矢量處放

        ;置RETFIE指令,可以使單片機不會因

        ;干擾產(chǎn)生誤中斷而導(dǎo)致程序跑飛

    CALL    PUSH    ;調(diào)用保護現(xiàn)場子程序

    BTFSS    PIR1,ADIF

    CALL    AD    ;若AD中斷到,則執(zhí)行中斷服務(wù)程序

    ……..        ;此處可放多個中斷子程序,并以軟件安排

            ;中斷優(yōu)先級

    CALL    POP    ;恢復(fù)中斷現(xiàn)場

    RETFIE    ;中斷返回

;****************主程序區(qū)*****************

    ORG    0X0100    ;將主程序、子程序和中斷服務(wù)程序等存放

        ;在0100h單元之后,在中斷矢量和主程序

        ;區(qū)之間預(yù)留一些存儲單元,以便寫入判

        ;跳指令和一些必要的現(xiàn)場保護程序。此外

        ;用戶也可以根據(jù)實際需要,使主程序從其

        ;它地址開始存放

MAIN    BSF          STATUS,RP0    ;選擇存儲體1

    MOVLW    0XFF    ;定義RA口為輸入端口

    MOVWF    TRISA

    BCF    STATUS,RP0    ;選擇存儲體0

    MOVLW    0X04    ;初值化ACCALO

    MOVWF    ACCALO    

    CALL    DX    ;調(diào)用DX子程序

LOOP1    ……    ;任務(wù)1

    ……    ;任務(wù)2

    :

    :

    :

    GOTO    LOOP1    ;反復(fù)執(zhí)行任務(wù)一和任務(wù)二等

;***************子程序區(qū)*********************

DX    MOVF        ACCALO,0    ;ACCB和ACCA低半字節(jié)相加

    ADDWF     ACCBLO

    RETURN        ;子程序返回

;****************************************

PUSH    MOVWF      S_W    ;保護W寄存器

    MOVF    STATUS,0    ;保護STATUS寄存器

    MOVWF    S_STATUS

    RETURN        ;子程序返回

;****************************************

POP    MOVF        S_STATUS,0    ;恢復(fù)STATUS寄存器

    MOVWF    STATUS

    MOVF    S_W,0    ;恢復(fù)W寄存器

    RETURN    ;子程序返回

;****************中斷服務(wù)子程序區(qū)************************

AD        BCF            PIR1,ADIF    ;清AD中斷標志

    ……                        ;中斷服務(wù)主體程序

    RETURN                    ;子程序返回

            END

 2  四則運算子程序

 2.1  16×16位定點數(shù)加、減法子程序

以下子程序?qū)崿F(xiàn)2個16×16位有符號數(shù)加、減運算,其和或差用一個16位數(shù)表示。在子程序中,減法是通過對減數(shù)求補后再與被減數(shù)相加來實現(xiàn)的。因此,當程序從D_sub進入子程序時為減法,當從D_add進入子程序時為加法。

子程序的入口條件和出口條件如下:

入口條件:16位被加數(shù)/被減數(shù)存放在ACCBHI、ACCBLO中;

              16位加數(shù)/減數(shù)存放在ACCAHI、ACCALO中;

出口條件:16位和/差存放在ACCBHI和ACCBLO中。

以下為16×16位有符號數(shù)加、減法子程序。

注意:在以下注釋程序中均以ACCA代替ACCAHI、ACCALO兩個字節(jié),以ACCB代替ACCBHI、ACCBLO兩個字節(jié)。


    LIST            p=16f877

    INCLUDE        p16f877.inc

    ACCALO     EQU     20    ;存放加數(shù)或減數(shù)低8位

    ACCAHI     EQU     21    ;存放加數(shù)或減數(shù)高8位

    ACCBLO     EQU     23    ;存放被加數(shù)或被減數(shù)低8位

    ACCBHI     EQU     24    ;存放被加數(shù)或被減數(shù)高8位

    ORG    0X0000

START    GOTO     MAIN

;***雙字節(jié)減法子程序,入口地址ACCB-ACCA,出口地址ACCB***

D_sub    CALL    NEG_A    ;求ACCA的補碼

;***雙字節(jié)加法子程序,入口地址ACCB+ACCA,出口地址ACCB***

D_add      MOVF     ACCALO,0    ;ACCB和ACCA低半字節(jié)相加

    ADDWF     ACCBLO

    BTFSC     STATUS,C    ;有進位否?

    INCF     ACCBHI    ;有,ACCB高字節(jié)加1,再加ACCAHI

    MOVF     ACCAHI,0    ;ACCA、ACCB高半字節(jié)相加

    ADDWF     ACCBHI

    RETURN    ;子程序返回

;************** ACCA取補子程序*****************

NEG_A    COMF     ACCALO    ;ACCALO取反加1

    INCF     ACCALO

    BTFSC     STATUS,Z    ;低8位有進位嗎?

    DECF     ACCAHI    ;有,ACCAHI減1,再取反

    COMF     ACCAHI    ;否則ACCAHI直接取反

    RETURN    ;子程序返回

【校驗舉例1】 19531+(-16594)=2937(十進制)

化為十六進制數(shù):4C46H+BF2EH

結(jié)果:0B79H(十六進制)

【校驗舉例2】 26222+3000=29222(十進制)

化為十六進制數(shù): 666EH+0BB8H

結(jié)果:7226H(十六進制)

【例程】

MAIN    MOVLW      0X6E    ;被加數(shù)666EH送ACCB

    MOVWF    ACCBLO

    MOVLW    0X66

    MOVWF    ACCBHI

    MOVLW    0XB8    ;加數(shù)BB8H送ACCA

    MOVWF    ACCALO

    MOVLW    0X0B

    MOVWF    ACCAHI

    CALL    D_add    ;調(diào)用雙字節(jié)加法子程序,求和

    END

 2.2  16×16位定點數(shù)乘法子程序

子程序采用部分積右移加法實現(xiàn)乘法運算。乘數(shù)和被乘數(shù)分別為16位二進制有符號數(shù)(均采用補碼表示,第16位為符號位),積為32位二進制有符號數(shù),第32位為符號位。子程序的入口條件和出口條件如下:

入口條件:被乘數(shù)存放在ACCBHI和ACCBLO單元中,

          乘數(shù)存放在ACCAHI和ACCALO單元中。

出口條件:積存放在ACCBHI、ACCBLO、ACCCHI和ACCCLO單元中,ACCB為高16位,ACCC為低16位。

以下為本子程序的程序清單:


    LIST    p=16f877

    INCLUDE    p16f877.inc

    ACCALO     EQU     20    ;存放乘數(shù)低8位

    ACCAHI     EQU     21    ;存放乘數(shù)高8位

    ACCBLO     EQU     23    ;存放被乘數(shù)低8位和乘積第16~23位

    ACCBHI     EQU     24    ;存放被乘數(shù)高8位和乘積第24~31位

    ACCCLO     EQU     26    ;存放乘積低8位

    ACCCHI     EQU     27    ;存放乘積高8位

    ACCDLO     EQU     28    ;臨時寄存器

    ACCDHI     EQU     29    ;臨時寄存器

    TEMP     EQU     2A    ;臨時寄存器

    SIGN     EQU     2B    ;存放乘積的符號

    ORG    0X0000

START    GOTO     MAIN

;***16×16位乘法子程序,入口地址ACCB×ACCA,出口地址ACCB和ACCC ***

    ORG    0X0100

D_mpy    CALL     S_SIGN    ;求取乘積的符號,并對負數(shù)取補

     CALL     SETUP    ;調(diào)用子程序,將ACCB的值送ACCD

    INCF    TEMP

    CLRF     ACCCHI    ;清ACCC

    CLRF     ACCCLO

MLOOP    BCF     STATUS,C    ;清進位位

    RRF     ACCDHI    ;ACCD右移

    RRF     ACCDLO

    BTFSC     STATUS,C    ;判斷是否需要相加

    CALL     D_add    ;加乘數(shù)至ACCB,見加法程序

    BCF     STATUS,C    ;清進位位

    RRF     ACCBHI    ;右移部分乘積

    RRF     ACCBLO

    RRF     ACCCHI

    RRF     ACCCLO

    DECFSZ     TEMP    ;乘法完成否?

    GOTO     MLOOP    ;否,繼續(xù)求乘積

    BTFSS     SIGN,7    ;是,確定乘積的符號

    GOTO     OVER    ;為正,乘法結(jié)束

    COMF     ACCCLO    ;為負,乘積取補

    INCF         ACCCLO

    BTFSC        STATUS,Z

    DECF         ACCCHI

    COMF         ACCCHI

    BTFSC         STATUS,Z

NEG_B    DECF         ACCBLO        ;

    COMF         ACCBLO

    BTFSC         STATUS,Z

    DECF         ACCBHI

    COMF         ACCBHI

OVER    RETURN        ;子程序返回

;****************************************

SETUP    MOVLW     .15    ;初始化TEMP寄存器        

    MOVWF     TEMP

    MOVF     ACCBHI,0    ;ACCB送ACCD

    MOVWF    ACCDHI

    MOVF     ACCBLO,0

    MOVWF     ACCDLO

    CLRF     ACCBHI    ;清ACCB

    CLRF     ACCBLO

    RETURN        ;子程序返回

;*******乘法運算確定結(jié)果符號判斷子程序******

S_SIGN    MOVF     ACCAHI,0    ;ACCAHI異或ACCBHI,結(jié)果送SIGN單元

    XORWF     ACCBHI,0

    MOVWF     SIGN            

    BTFSS     ACCBHI,7    ;ACCB為負嗎?

    GOTO     CHEK_A    ;否,檢查ACCA

    CALL    NEG_B    ;是,求取ACCB絕對值

CHEK_A    BTFSC     ACCAHI,7    ;ACCA為負嗎?

    CALL     NEG_A    ;ACCA為負,求取ACCA絕對值,

            ;見雙字節(jié)加法程序

    RETURN        ;ACCA和ACCB均為正,返回

【校驗舉例1】:-24555×(-7391)=181486005(十進制)

化為十六進制數(shù):A015H×E321H

結(jié)果:0AD141B5H(十六進制)

【校驗舉例2】 16405×13089=214725045(十進制)

化為十六進制數(shù):4015H×3321H

結(jié)果:0CCC71B5H(十六進制)

【例程】

MAIN    MOVLW    0X15    ;被乘數(shù)4015H送ACCB

    MOVWF    ACCBLO

    MOVLW    0X40

    MOVWF    ACCBHI

    MOVLW    0X21    ;乘數(shù)3321H送ACCA

    MOVWF    ACCALO

    MOVLW    0X33

    MOVWF    ACCAHI

    CALL    D_mpy    ;調(diào)用雙字節(jié)乘法子程序,求積

    END

 2.3  16×16位定點數(shù)除法子程序

子程序采用反復(fù)的減法算法,除數(shù)和被除數(shù)分別為16位二進制有符號數(shù)(均采用補碼表示,第16位為符號位),商為16位二進制有符號數(shù),第16位為符號位。子程序的入口條件和出口條件如下:

入口條件:被除數(shù)存放在ACCBHI、ACCBLO單元中;

      除數(shù)存放在ACCAHI、ACCALO單元中。

出口條件:商存放在ACCBHI、ACCBLO單元中;

          余數(shù)存放在ACCCHI、ACCCLO單元中。

    

    LIST    p=16f877

    INCLUDE    p16f877.inc

    ACCALO    EQU     20    ;存放除數(shù)低8位

    ACCAHI     EQU     21    ;存放除數(shù)高8位

  ACCBLO     EQU     22    ;存放被除數(shù)和商的低8位

    ACCBHI     EQU     23    ;存放被除數(shù)和商的高8位

    ACCCLO     EQU     24    ;存放余數(shù)低8位

    ACCCHI     EQU     25    ;存放余數(shù)高8位

    ACCDLO     EQU     26    ;臨時寄存器

    ACCDHI     EQU     27    ;臨時寄存器

    TEMP     EQU     28    ;臨時寄存器

    SIGN     EQU     29    ;存放商的符號

    ORG    0X0000

START    GOTO    MAIN

;***16×16位數(shù)除法子程序,入口地址ACCB /ACCA,出口地址ACCB ***

    ORG    0X0100

D_div    CALL     S_SIGN    ;確定商的符號,并將負數(shù)取補

    CALL    SETUP    ;初始化TEMP,將被除數(shù)移至ACCD,

            ;(SETUP子程序請參見16×16位定點數(shù)

            ;乘法子程序SETUP)

    INCF    TEMP

    CLRF    ACCCHI    ;清余數(shù)寄存器

    CLRF    ACCCLO

DLOOP    BCF    STATUS,C    ;清進位位

    RLF    ACCDLO    ;被除數(shù)、余數(shù)左移1位

    RLF    ACCDHI

    RLF    ACCCLO

    RLF    ACCCHI

    MOVF    ACCAHI,0    ;ACCCHI-ACCAHI

    SUBWF    ACCCHI,0

    BTFSS    STATUS,Z    ;ACCCHI=ACCAHI?

    GOTO    NOCHK

    MOVF    ACCALO,0    ;是,ACCCLO-ACCALO

    SUBWF    ACCCLO,0

NOCHK    BTFSS    STATUS,C    ;ACCC>ACCA?

    GOTO    NOGO

   MOVF    ACCALO,0    ;是,余數(shù)減除數(shù)

    SUBWF    ACCCLO

    BTFSS    STATUS,C

    DECF    ACCCHI

    MOVF    ACCAHI,0

    SUBWF    ACCCHI

    BSF    STATUS,C    ;置進位位

NOGO    RLF    ACCBLO    ;商左移1位

    RLF    ACCBHI

    DECFSZ    TEMP    ;循環(huán)完畢?

    GOTO    DLOOP

    BTFSS     SIGN,7    ;是,確定商的符號

    GOTO     DIVOVER    ;為正,除法結(jié)束,跳轉(zhuǎn)到結(jié)束行

    COMF     ACCCLO    ;為負,商和余數(shù)分別取補

    INCF     ACCCLO

    BTFSC    STATUS,Z

    DECF     ACCCHI

    COMF     ACCCHI

    CALL    NEG_B    ;見乘法程序中間NEG_B

DIVOVER    RETURN        ;子程序返回

;************除法運算確定結(jié)果符號子程序*******************

S_SIGN    MOVF     ACCAHI,0    ;ACCAHI異或ACCBHI,結(jié)果送SIGN單元

    XORWF     ACCBHI,0

    MOVWF     SIGN            

    BTFSS     ACCBHI,7    ;ACCB為負?

    GOTO     CHEK_A    ;否,檢查ACCA

    COMF     ACCBLO    ;是,ACCB取補

    INCF     ACCBLO

    BTFSC     STATUS,Z

    DECF     ACCBHI

    COMF     ACCBHI

CHEK_A    BTFSC     ACCAHI,7    ;ACCA為負?

    CALL     NEG_A    ;ACCA為負,取補(NEG_A子程序請參見

            ;16×16位定點數(shù)乘法子程序NEG_A)

    RETURN        ;ACCA和ACCB均為負,返回

【校驗舉例1】 -23775÷(-240)=99.0625(十進制)

化為十六進制數(shù):A321H÷FF10H;

結(jié)果:(商)0063H,(余數(shù))000FH(十六進制)。

【校驗舉例2】 769÷3856=0.199429(十進制)

化為十六進制數(shù):0301H÷0F10H;

結(jié)果:(商)0000H,(余數(shù))0301H(十六進制)。

【例程】

MAIN    MOVLW    0X01    ;被除數(shù)0301H送ACCB

    MOVWF    ACCBLO

    MOVLW    0X03

    MOVWF    ACCBHI

    MOVLW    0X10    ;除數(shù)0F10H送ACCA

    MOVWF    ACCALO

    MOVLW    0X0F

    MOVWF    ACCAHI

    CALL    D_div    ;調(diào)用雙字節(jié)除法子程序,求商

    END

 3  3字節(jié)浮點四則運算子程序

 3.1  浮點數(shù)加(減)法子程序

以下為浮點加(減)運算例程:


    LIST            p=16f877

    INCLUDE         p16f877.inc

    ACCALO         EQU     20        ;存放加數(shù)或減數(shù)的尾數(shù)

    ACCAHI         EQU    21

    EXPA        EQU     22        ;存放加數(shù)或減數(shù)階碼

    ACCBLO        EQU     23        ;存放被加數(shù)或被減數(shù)尾數(shù)以及和或差

    ACCBHI         EQU     24

    EXPB         EQU    25        ;存放被加數(shù)或被減數(shù)階碼

    ACCCLO        EQU     26        ;臨時寄存器

    ACCCHI         EQU     27        ;臨時寄存器

    ACCDLO        EQU     28        ;臨時寄存器

    ACCDHI         EQU     29        ;臨時寄存器

    TEMP         EQU     2A        ;臨時寄存器

    TEMP1         EQU     30        ;臨時寄存器

    TIMES         EQU     31        ;臨時寄存器


    ORG             0X000

START    GOTO        MAIN

    ORG            0X0100

;**************浮點減法子程序****************

F_sub    CALL         NEG_A        ;求ACCA的補碼,將減法轉(zhuǎn)換為補碼加法

;***********浮點加法子程序**************

F_add    CALL        SUBADJ        ;調(diào)子程序判斷EXPB和EXPA的大小

    BTFSC         STATUS,Z    ;參與運算的兩個數(shù)階碼相等?

    GOTO         PADD        ;是,求尾數(shù)的和

    BTFSC         STATUS,C    ;EXPB>EXPA?

    CALL         F_swap        ;是,ACCB與ACCA互換

    MOVF         EXPA,0        ;否,求取兩者的差值

    SUBWF         EXPB

SCLOOP    CALL         SHFTSR        ;ACCB右移規(guī)格化

    INCFSZ         EXPB        ;EXPB=EXPA?        

    GOTO         SCLOOP        ;否,繼續(xù)右移

    MOVF         EXPA,0        ;是,存和(差)的階碼

    MOVWF        EXPB

PADD    MOVF         ACCAHI,0    ;ACCAHI或ACCBHI

    IORWF         ACCBHI,0

    MOVWF         SIGN            ;存于SIGN寄存器

    MOVF        ACCBHI,0    ;暫存ACCBHI    

    MOVWF        EXPA

    CALL         D_add        ;尾數(shù)相加

    BTFSS         SIGN,7        ;ACCA和ACCB有負數(shù)?

               BTFSC         ACCBHI,7    ;否,把和的最高位和次高位同時進位?

    GOTO         ADD2        ;否,轉(zhuǎn)ADD2

    BTFSS        ACCAHI,7    ;ACCA為負嗎?

    GOTO        ADD3        ;ACCA和ACCB不同時為負,轉(zhuǎn)ADD3

    BTFSS        EXPA,7        ;是,ACCB為負嗎?

    GOTO        ADD3        

    BSF            STATUS,C    ;ACCA和ACCB同為負,帶負號右移

    RRF            ACCBHI

    RRF            ACCBLO

    INCF            EXPB

ADD3    CLRF         ACCCHI        ;和(差)規(guī)格化

    CLRF         ACCCLO

    CALL         F_norm

    RETURN                    ;子程序返回

ADD2    BCF             STATUS,C    ;最高位次高位不同時進位,ACCB右移

    INCF         EXPB

    GOTO         SHFTR

SHFTSR     BCF             STATUS,C    ;ACCB帶符號右移子程序

    BTFSC         ACCBHI,7

    BSF             STATUS,C

SHFTR      RRF             ACCBHI

    RRF             ACCBLO

    RETURN                    ;子程序返回

;********* ACCB、ACCA互換子程序************

F_swap    MOVF         ACCAHI,0    ;ACCAHI、ACCBHI互換

    MOVWF         TEMP

    MOVF         ACCBHI,0

    MOVWF         ACCAHI

    MOVF         TEMP,0

    MOVWF         ACCBHI

    MOVF         ACCALO,0    ;ACCALO、ACCBLO互換

    MOVWF         TEMP

    MOVF         ACCBLO,0

    MOVWF         ACCALO

    MOVF         TEMP,0

    MOVWF         ACCBLO

    MOVF         EXPA,0        ;EXPA、EXPB互換

    MOVWF         TEMP

    MOVF         EXPB,0

    MOVWF         EXPA

    MOVF         TEMP,0

    MOVWF         EXPB    

    RETURN

;*************比較EXPB、EXPA大小子程序*************

SUBADJ        MOVF        EXPA,0        ;EXPA異或EXPB,結(jié)果送C_DIV

    XORWF        EXPB,0

    MOVWF        C_DIV

    MOVF        EXPA,0        ;EXPB-EXPA

    SUBWF        EXPB,0

    BTFSS        C_DIV,7        ;EXPA和EXPB同號?

    RETURN                    ;是,進位位的值真確反映兩者的大小,返回

    BTFSS        STATUS,C    ;否,進位位的值取反

    GOTO        CHANGEC

    BCF            STATUS,C

    RETURN

CHANGEC    BSF            STATUS,C

    RETURN

;***********浮點數(shù)規(guī)格化子程序****************

F_norm     MOVF         ACCBHI        ;ACCB=0?

    BTFSS         STATUS,Z

    GOTO         C_norm

    MOVF         ACCBLO

    BTFSC         STATUS,Z

    RETURN                    ;是,不需規(guī)格化,返回

C_norm    BTFSC        ACCBHI,7    ;否。ACCB為負?

     GOTO        C_norm2    

C_norm1    BTFSC         ACCBHI,6    ;為正。規(guī)格化完畢?

    RETURN                    ;ACCBHI.6=1,規(guī)格化結(jié)束

    CALL         SHFTSL        ;否。ACCB左移

    DECF         EXPB        ;EXPB減1

    GOTO         C_norm1        ;重新判斷規(guī)格化完畢否?

C_norm2    BTFSS        ACCBHI,6    ;ACCB為負。規(guī)格化完畢否?

    RETURN                    ;ACCBHI.6=0,規(guī)格化結(jié)束

    BCF            STATUS,C    

    CALL        SHFTSL        ;否,ACCB左移

    BSF            ACCBHI,7    ;加符號

    DECF        EXPB        ;EXPB減1

    GOTO        C_norm2        ;重新判斷規(guī)格化完畢否?

SHFTSL      BCF             STATUS ,C    ;ACCB左移子程序    

    RLF             ACCCLO        

    RLF             ACCCHI

    RLF             ACCBLO

    RLF             ACCBHI

    RETURN

【校驗舉例1】 0.0019531+(-0.00016594)=0.00178716

化為十六進制數(shù):4000F8+A900F4

結(jié)果:7520F7

【校驗舉例2】 0.26222+3.5025=3.76478

化為十六進制數(shù): 4321FF+701502

結(jié)果:787902

【例程】

MAIN        MOVLW        0X21            ;被加數(shù)的尾數(shù)4321H送ACCB

    MOVWF        ACCBLO

    MOVLW        0X43

    MOVWF        ACCBHI

        MOVLW        0XFF            ;被加數(shù)的階碼FFH送EXPB

        MOVWF        EXPB

    MOVLW        0X15            ;加數(shù)尾數(shù)7015H送ACCA

    MOVWF        ACCALO

    MOVLW        0X70

    MOVWF        ACCAHI

    MOVLW        0X02            ;加數(shù)階碼送EXPA

    MOVWF        EXPA

    CALL        F_add        ;調(diào)用浮點數(shù)加法子程序,求和

    END

 3.2  浮點數(shù)乘法子程序

以下為浮點數(shù)乘法的程序清單。

    LIST            p=16f877

    INCLUDE        p16f877.inc

    ACCALO         EQU     20        ;存放乘數(shù)尾數(shù)

    ACCAHI         EQU     21

    EXPA        EQU     22        ;存放乘數(shù)階碼

    ACCBLO         EQU     23        ;存放被乘數(shù)尾數(shù)和乘積高16位

    ACCBHI         EQU     24

    EXPB         EQU     25        ;存放被乘數(shù)階碼

    ACCCLO         EQU     26        ;存放乘積低16位

    ACCCHI         EQU     27        

    ACCDLO         EQU     28        ;臨時寄存器

    ACCDHI         EQU     29        ;臨時寄存器

    TEMP         EQU     2A        ;臨時寄存器

    TEMP1         EQU     30        ;臨時寄存器

    TIMES         EQU     31        ;臨時寄存器

    SIGN         EQU     2B        ;存放乘積符號

    COUNT         EQU     2F        ;臨時寄存器

    ACCEHI        EQU    30        ;臨時寄存器

    ACCELO        EQU    31        ;臨時寄存器


    ORG            0X0000

START    GOTO        MAIN

    ORG            0X0100

;***浮點乘法子程序,入口地址(ACCB、EXPB)×(ACCA、EXPA),出口地址ACCB、EXPB ***

F_mpy    CALL         S_SIGN        ;求取乘積的符號,并對負數(shù)取補

     CALL         SETUP        ;調(diào)用子程序?qū)CCB的值送ACCD

    CLRF         ACCCHI        ;清ACCC

    CLRF         ACCCLO

MLOOP    BCF             STATUS,C    ;清進位位

    RRF             ACCDHI        ;ACCD右移

    RRF             ACCDLO

    BTFSC         STATUS,C    ;判斷是否需要相加

    CALL         D_add        ;加乘數(shù)至ACCB

    BCF             STATUS,C    ;清進位位

    RRF             ACCBHI        ;右移部分乘積

    RRF             ACCBLO

    RRF             ACCCHI

    RRF             ACCCLO

    DECFSZ         TEMP        ;乘法完成否?

    GOTO         MLOOP        ;否,繼續(xù)循環(huán)

    MOVF         EXPA,0        ;是,乘數(shù)與被乘數(shù)階碼相加,得積的階碼

    ADDWF        EXPB

    MOVF         ACCBHI        ;ACCBHI=0?

    BTFSS         STATUS,Z

    GOTO         FINUP        ;否,轉(zhuǎn)FINUP

    MOVF         ACCBLO        ;ACCB=0?

    BTFSS         STATUS ,Z

    GOTO         SHFT08        ;否,只有ACCBHI=0,轉(zhuǎn)SHFT08

    MOVF         ACCCHI,0    ;ACCB=0,將乘積左移15位

    MOVWF         ACCBHI

    MOVF         ACCCLO,0

    MOVWF         ACCBLO

    BCF             STATUS,C

    RRF             ACCBHI

    RRF             ACCBLO

    MOVLW         .15            ;乘積階碼減15(十進制數(shù))

    SUBWF         EXPB

    GOTO         FINUP

SHFT08    MOVF         ACCBLO,0    ;只有ACCBHI=0,乘積左移7位

    MOVWF         ACCBHI

    MOVF         ACCCHI,0

    MOVWF         ACCBLO

    BCF             STATUS,C

    RRF             ACCBHI

    RRF             ACCBLO

    MOVLW         .7            ;乘積階碼減7

    SUBWF         EXPB

FINUP    CALL         F_norm        ;對乘積進行規(guī)格化

    BTFSS         SIGN,7        ;確定乘積的符號

    GOTO         OVER        ;為正,乘法結(jié)束

    COMF         ACCCLO        ;為負,乘積取補

    INCF         ACCCLO

    BTFSC         STATUS,Z

    DECF         ACCCHI

    COMF         ACCCHI

    BTFSC         STATUS,Z

NEG_B    DECF         ACCBLO

    COMF         ACCBLO

    BTFSC         STATUS,Z

    DECF         ACCBHI

    COMF         ACCBHI

OVER    RETURN                    ;乘法結(jié)束,子程序返回

;********浮點乘除法運算確定結(jié)果符號子程序***********

S_SIGN    MOVF         ACCAHI,0    ;ACCAHI異或ACCBHI,結(jié)果送SIGN

    XORWF         ACCBHI,0

    MOVWF        SIGN            

    BTFSS         ACCBHI,7    ;ACCB為負?

    GOTO         CHEK_A        ;否,檢查ACCA

    COMF         ACCBLO        ;是,ACCB取補

    INCF         ACCBLO

    BTFSC         STATUS,Z

    DECF         ACCBHI

    COMF         ACCBHI

CHEK_A        BTFSC         ACCAHI,7    ;ACCA為負?

    CALL        NEG_A        ;ACCA取補

    RETURN                    ;返回

;*********浮點運算結(jié)果規(guī)格化子程序*************

F_norm      MOVF         ACCBHI        ;ACCB=0?

    BTFSS         STATUS,Z

    GOTO         C_norm

    MOVF         ACCBLO

    BTFSC         STATUS,Z

    RETURN                    ;是,不需規(guī)格化,返回

C_norm    BTFSC        ACCBHI,7    ;否。ACCB為負?

     GOTO        C_norm2

C_norm1    BTFSC         ACCBHI,6    ;為正。規(guī)格化完畢?

    RETURN                    ;ACCBHI.6=1,規(guī)格化結(jié)束

    CALL         SHFTSL        ;否。ACCB左移

    DECF         EXPB        ;EXPB減1

    GOTO         C_norm1        ;重新判斷規(guī)格化完畢否?

C_norm2    BTFSS        ACCBHI,6    ;ACCB為負。規(guī)格化完畢否?

    RETURN                    ;ACCBHI.6=0,規(guī)格化結(jié)束

    BCF            STATUS,C    

    CALL        SHFTSL        ;否,ACCB左移

    BSF            ACCBHI,7    ;加符號

    DECF        EXPB        ;EXPB減1

    GOTO        C_norm2        ;重新判斷規(guī)格化完畢否?

SHFTSL     BCF             STATUS ,C    ;ACCB左移子程序    

    RLF             ACCCLO        

    RLF             ACCCHI

    RLF             ACCBLO

    RLF             ACCBHI

    RETURN

【校驗舉例1】 0.0019531×(-0.00016594)=-0.000000324

化為十六進制數(shù):4000F8×A900F4

結(jié)果:A900EB

【校驗舉例2】 0.26222×3.5025=0.91842

化為十六進制數(shù): 4321FF×701502

結(jié)果: 758F00

【例程】

MAIN        MOVLW        0X21            ;被乘數(shù)的尾數(shù)4321H送ACCB

    MOVWF        ACCBLO

    MOVLW        0X43

    MOVWF        ACCBHI

        MOVLW        0XFF            ;被乘數(shù)的階碼FFH送EXPB

        MOVWF        EXPB

    MOVLW        0X15            ;乘數(shù)尾數(shù)7015H送ACCA

    MOVWF        ACCALO

    MOVLW        0X70

    MOVWF        ACCAHI

    MOVLW        0X02            ;乘數(shù)階碼送EXPA

    MOVWF        EXPA

    CALL        F_mpy        ;調(diào)用浮點數(shù)乘法子程序,求積

    END

 3.3  浮點數(shù)除法子程序

以下為浮點數(shù)除法子程序清單。

    LIST            p=16f877

    INCLUDE        p16f877.inc

    ACCALO         EQU     20        ;存放除數(shù)的尾數(shù)


    ACCAHI         EQU     21

    EXPA        EQU     22        ;存放除數(shù)的階碼

    ACCBLO         EQU     23        ;存放被除數(shù)的尾數(shù)和商的尾數(shù)

    ACCBHI         EQU     24

    EXPB         EQU     25        ;存放被除數(shù)和商的階碼

    ACCCLO         EQU     26        ;存放余數(shù)

    ACCCHI         EQU     27

    ACCDLO         EQU     28        ;臨時寄存器

    ACCDHI         EQU     29        ;臨時寄存器

    TEMP         EQU     2A        ;臨時寄存器

    TEMP1         EQU     30        ;臨時寄存器

    TIMES         EQU     31        ;臨時寄存器

    SIGN         EQU     2B        ;存放商的符號

    COUNT         EQU     2F        ;臨時寄存器

    ACCEHI        EQU    30        ;臨時寄存器

    ACCELO        EQU    31        ;臨時寄存器

    ORG            0X0000

START    GOTO        MAIN

    ORG            0X0100

;***浮點數(shù)除法子程序,入口地址(ACCB、EXPB)/(ACCA、EXPA),出口地址ACCB、EXPB***

F_div    CALL         S_SIGN        ;確定商的符號,并將負數(shù)取補

    CLRF        ACCCHI        ;初始化ACCC寄存器

    CLRF         ACCCLO

    CALL         F_norm        ;規(guī)格化ACCB

    CLRF         ACCCLO

    CLRF         ACCCHI

    CLRF         TIMES

    MOVF         ACCAHI        ;除數(shù)為零?

    BTFSS         STATUS,Z

    GOTO         FD0            ;否,求商

    MOVF         ACCALO

    BTFSC         STATUS,Z

    RETLW         01            ;是,返回

FD0    CALL         NEG_A        ;除數(shù)取補

FD1    MOVF         ACCBHI,0    ;ACCBHI送ACCDLO

    MOVWF         ACCDLO

    CALL         D_add1        ;被除數(shù)尾數(shù)大于除數(shù)尾數(shù)?

    BTFSS         STATUS,C

    GOTO         FD2

RRF1    BCF             STATUS,C    ;是,被除數(shù)右移規(guī)格化,直到小于除數(shù)為止

    RRF             ACCBHI

    RRF             ACCBLO

    INCF         TIMES

    RRF             ACCCHI

    BCF             STATUS,C

    GOTO         FD1

FD2    CALL         DDIV        ;否,調(diào)用雙字節(jié)除法子程序,求商的尾數(shù)

    MOVF         TIMES,0        ;根據(jù)右移規(guī)格化次數(shù)調(diào)整ACCB階碼

    ADDWF         EXPB

    MOVF         EXPA,0        ;求商的階碼

    SUBWF         EXPB

    CALL         F_norm        ;商規(guī)格化

    BTFSC         SIGN,7        ;商為負?

    CALL         NEG_B        ;是,取補

    CALL         NEG_A        ;除數(shù)還原

    RETURN                    ;浮點數(shù)除法完成,返回

;***********雙字節(jié)純小數(shù)除法子程序***************

DDIV    MOVLW         0X0F            ;初始化ACCDHI

    MOVWF         ACCDHI

DV1    BCF             STATUS,C

    RLF             ACCCLO        ;左移商

    RLF             ACCCHI

    RLF             ACCBLO        ;左移余數(shù)

    RLF             ACCBHI

    MOVF         STATUS,0    ;暫存STATUS寄存器

    MOVWF         ACCDLO

    MOVF         ACCBHI,0    ;ACCBHI送TEMP1

    MOVWF         TEMP1

    MOVF         ACCALO,0    ;ACCB-ACCA

    ADDWF         ACCBLO,0

    MOVWF         TEMP

    BTFSC         STATUS,C        

    INCF         TEMP1            

    MOVF         ACCAHI,0        

    ADDWF         TEMP1,0

    BTFSC         ACCDLO,0    ;左移余數(shù)時移出來的數(shù)為1?

    GOTO         DV2

TESTC    BTFSS         STATUS,C    ;是,再判斷ACCB尾數(shù)是否大于ACCA

    GOTO         DV3

DV2    MOVWF         ACCBHI        ;是,余數(shù)送ACCB

    MOVF         TEMP,0

    MOVWF         ACCBLO

    INCF         ACCCLO        ;商加1

DV3    DECFSZ        ACCDHI        ;商求取完畢?

    GOTO         DV1

    MOVF         ACCCHI,0    ;是,將商送ACCB

    MOVWF         ACCBHI

    MOVF         ACCCLO,0

    MOVWF         ACCBLO

    RETLW         00    

;**********本子程序用于判斷比較ACCB與ACCA的大小**********

D_add1    MOVF         ACCALO,0    ;加數(shù)、被加數(shù)低半字節(jié)相加

    ADDWF         ACCBLO,0

    BTFSC         STATUS,C    ;有進位?

    INCF         ACCDLO        ;ACCD低半字節(jié)加1

    MOVF         ACCAHI,0       ;ACCAHI+ACCDLO

    ADDWF         ACCDLO

    RETLW         0            ;子程序返回

;****************************************

SETUP    MOVLW         .15

    MOVWF         TEMP

    MOVF         ACCBHI,0

    MOVWF         ACCDHI

    MOVF         ACCBLO,0

    MOVWF         ACCDLO

    CLRF         ACCBHI

    CLRF         ACCBLO

    RETLW         0

;*************** ACCA取補子程序*************

NEG_A    COMF         ACCALO        ;ACCALO取反加1

    INCF         ACCALO

    BTFSC         STATUS,Z    ;低8位有進位嗎?

    DECF         ACCAHI        ;有,ACCAHI減1,再取反

    COMF         ACCAHI        ;否,ACCAHI直接取反

    RETLW         0

;********* ACCB取補子程序*************

NEG_B    DECF         ACCBLO        ;ACCBLO取反加1

    COMF         ACCBLO

    BTFSC         STATUS,Z    ;低8位有進位嗎?

    DECF         ACCBHI        ;有,ACCBHI減1,再取反

    COMF         ACCBHI        ;否,ACCBHI直接取反

    RETLW         0        

;*********浮點乘除法運算確定結(jié)果符號子程序**********

S_SIGN    MOVF        ACCAHI,0    ;ACCAHI異或ACCBHI,結(jié)果送SIGN單元

    XORWF         ACCBHI,0

    MOVWF         SIGN            

    BTFSS         ACCBHI,7    ;ACCB為負?

    GOTO         CHEK_A        ;否,檢查ACCA

    COMF         ACCBLO        ;是,ACCB取補

    INCF         ACCBLO

    BTFSC         STATUS,Z

    DECF         ACCBHI

    COMF         ACCBHI

CHEK_A        BTFSC         ACCAHI,7    ;ACCA為負?

    CALL         NEG_A        ;ACCA為負,取補

    RETLW         0            ;ACCA和ACCB均為負,返回

;************浮點運算結(jié)果規(guī)格化子程序***************

F_norm      MOVF         ACCBHI        ;ACCB=0?

    BTFSS         STATUS,Z

    GOTO         C_norm

    MOVF         ACCBLO

    BTFSC         STATUS,Z

    RETLW         0            ;是,不需規(guī)格化,返回

C_norm    BTFSC        ACCBHI,7    ;否。ACCB為負?

     GOTO        C_norm2

C_norm1    BTFSC         ACCBHI,6    ;為正。規(guī)格化完畢?

    RETLW         0            ;ACCBHI.6=1,規(guī)格化結(jié)束

    CALL         SHFTSL        ;否。ACCB左移

    DECF         EXPB        ;EXPB減1

    GOTO         C_norm1        ;重新判斷規(guī)格化完畢否?

C_norm2    BTFSS        ACCBHI,6    ;ACCB為負。規(guī)格化完畢否?

    RETLW        0            ;ACCBHI.6=0,規(guī)格化結(jié)束

    BCF            STATUS,C    

    CALL        SHFTSL        ;否,ACCB左移

    BSF            ACCBHI,7    ;加符號

    DECF        EXPB        ;EXPB減1

    GOTO        C_norm2        ;重新判斷規(guī)格化完畢否?

SHFTSL    BCF             STATUS ,C    ;ACCB左移子程序    

    RLF             ACCCLO        

    RLF             ACCCHI

    RLF             ACCBLO

    RLF             ACCBHI

    RETLW         0

【校驗舉例1】 0.0019531÷(-0.00016594)=-12.7699

化為十六進制數(shù):4000F8÷A900F4

結(jié)果:A1D704

【校驗舉例2】 0.26222÷3.5025=0.074867

化為十六進制數(shù): 4321FF÷701502

結(jié)果:4CA9FD

【例程】

MAIN        MOVLW        0X21            ;被除數(shù)的尾數(shù)4321H送ACCB

    MOVWF        ACCBLO

    MOVLW        0X43

    MOVWF        ACCBHI

        MOVLW        0XFF            ;被除數(shù)的階碼FFH送EXPB

        MOVWF        EXPB

    MOVLW        0X15            ;除數(shù)尾數(shù)7015H送ACCA

    MOVWF        ACCALO

    MOVLW        0X70

    MOVWF        ACCAHI

    MOVLW        0X02            ;除數(shù)階碼送EXPA

    MOVWF        EXPA

    CALL        F_div            ;調(diào)用浮點數(shù)除法子程序,求商

    END

 4  定點數(shù)與浮點數(shù)轉(zhuǎn)換程序

 4.1  定點數(shù)轉(zhuǎn)換成浮點數(shù)

本子程序的功能是將雙字節(jié)定點整數(shù)(十六進制)轉(zhuǎn)換為3字節(jié)浮點數(shù),其轉(zhuǎn)換數(shù)值范圍:-32768~32767,入口條件和出口條件如下:

入口條件:ACCBHI、ACCBLO

出口條件:ACCBHI、ACCBLO、EXPB

以下為定點整數(shù)轉(zhuǎn)換成浮點數(shù)的程序清單。

    LIST            p=16f877

    INCLUDE        p16f877.inc

    ACCBLO         EQU     23        ;存放定點整數(shù)和轉(zhuǎn)換后浮點數(shù)的尾數(shù)

    ACCBHI         EQU     24

    EXPB         EQU     25        ;存放轉(zhuǎn)換后浮點數(shù)的階碼

    ACCCLO         EQU     26        ;臨時寄存器

    ACCCHI         EQU     27        ;臨時寄存器

    ACCDLO         EQU     28        ;臨時寄存器

    ACCDHI         EQU     29        ;臨時寄存器

    SIGN         EQU     2B        ;存放被轉(zhuǎn)換數(shù)的符號


    ORG            0X0000

START    GOTO        MAIN

    ORG            0X0100

;*********雙字節(jié)定點整數(shù)到浮點數(shù)轉(zhuǎn)換子程序***********

DtoF    CLRF         SIGN            ;根據(jù)被轉(zhuǎn)換數(shù)確定結(jié)果的符號,對負數(shù)取補

    BTFSS         ACCBHI,7

    GOTO         INTF1

    BSF             SIGN,7

    CALL         NEG_B

INTF1    MOVLW         .15            ;初始化EXPB

    MOVWF         EXPB

    CLRF         ACCCHI

    CLRF         ACCCLO

    CALL         F_norm        ;對ACCB進行規(guī)格化

    BTFSS         SIGN,7        ;結(jié)果為負?

    GOTO         DtoF1

    CALL         NEG_B        ;是,求補

DtoF1    RETURN    

;**************浮點數(shù)規(guī)格化子程序**************

F_norm     MOVF         ACCBHI        ;ACCB=0?

    BTFSS         STATUS,Z

    GOTO         C_norm

    MOVF         ACCBLO

    BTFSC         STATUS,Z

    RETLW         0            ;是,不需規(guī)格化,返回

C_norm    BTFSC        ACCBHI,7    ;否。ACCB為負?

     GOTO        C_norm2    

C_norm1    BTFSC         ACCBHI,6    ;為正。規(guī)格化完畢?

    RETLW         0            ;ACCBHI.6=1,規(guī)格化結(jié)束

    CALL         SHFTSL        ;否。ACCB左移

    DECF         EXPB        ;EXPB減1

    GOTO         C_norm1        ;重新判斷規(guī)格化完畢否?

C_norm2    BTFSS        ACCBHI,6    ;ACCB為負。規(guī)格化完畢否?

    RETLW        0            ;ACCBHI.6=0,規(guī)格化結(jié)束

    BCF            STATUS,C    

    CALL        SHFTSL        ;否,ACCB左移

    BSF            ACCBHI,7    ;加符號

    DECF        EXPB        ;EXPB減1

    GOTO        C_norm2        ;重新判斷規(guī)格化完畢否?

SHFTSL      BCF             STATUS ,C    ;ACCB左移子程序    

    RLF             ACCCLO        

    RLF             ACCCHI

    RLF             ACCBLO

    RLF             ACCBHI

    RETLW         0

【校驗舉例1】 19531(十進制)

化為十六進制數(shù):4C4BH

結(jié)果:4C4B0FH

【校驗舉例2】 2622(十進制)

化為十六進制數(shù): 0A3EH

結(jié)果:51F00CH

【例程】

MAIN        MOVLW        0X4B        ;被轉(zhuǎn)換數(shù)4C4BH送ACCB

    MOVWF        ACCBLO

    MOVLW        0X4C

    MOVWF        ACCBHI

        CALL        DtoF            ;調(diào)用定點數(shù)至浮點數(shù)轉(zhuǎn)換子程序

    END


开平市| 苍南县| 东兴市| 台东县| 西乌| 永兴县| 无棣县| 和龙市| 靖边县| 乐业县| 东阳市| 陇南市| 博爱县| 南宫市| 水城县| 新平| 深圳市| 东港市| 雅安市| 肥乡县| 蒙自县| 伊金霍洛旗| 盈江县| 柏乡县| 太保市| 建昌县| 日照市| 黔江区| 奎屯市| 斗六市| 成安县| 山东| 仙游县| 江陵县| 东宁县| 汶川县| 丰原市| 吉木萨尔县| 来安县| 许昌县| 东乌珠穆沁旗|