1. gzyueqian
      18529173453
      首頁 > 新聞中心 > > 正文

      PIC16F877單片機運算子程序

      更新時間: 2007-05-25 16:51:03來源: 粵嵌教育瀏覽量:867


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

      以下是一個典型的程序結構:
      ;***************程序說明區*******************
      LIST p=16f877 ;指定微控制器型號和文件輸出格式
      INCLUDE p16f877.inc ;讀入MPLAB提供的定義文件P16F877.INC
      ;***片內RAM常用資源、變量定義和相應的說明*********
      ACCALO EQU 20 ;存放加數或減數低8位
      ACCAHI EQU 21 ;存放加數或減數高8位
      ACCBLO EQU 23 ;存放被加數或被減數低8位
      ACCBHI EQU 24 ;存放被加數或被減數高8位
      S_W EQU 25 ;棧存W寄存器值
      S_STATUS EQU 26 ;棧存STATUS寄存器值
      ;****************芯片復位矢量*******************
      ORG 0X0000 ;由于PIC16F877芯片復位矢量在0000h單
      ;元,所以常在0000h單元處放置一條跳轉
      ;指令,使單片機復位后能跳過中斷矢量,
      ;直接執行主程序
      START GOTO MAIN
      ;******************中斷矢量**********************
      ORG 0X0004 ;由于PIC16F877的中斷矢量為0004h,所以
      ;當中斷開放時, 需在此處加入中斷程序,
      ;使單片機能在中斷到來時及時進入相應的
      ;中斷服務程序。為了可靠起見,如果單片
      ;機不使用中斷,則常常在該中斷矢量處放
      ;置RETFIE指令,可以使單片機不會因
      ;干擾產生誤中斷而導致程序跑飛
      CALL PUSH ;調用保護現場子程序
      BTFSS PIR1,ADIF
      CALL AD ;若AD中斷到,則執行中斷服務程序
      …….. ;此處可放多個中斷子程序,并以軟件安排
      ;中斷優先級
      CALL POP ;恢復中斷現場
      RETFIE ;中斷返回
      ;****************主程序區*****************
      ORG 0X0100 ;將主程序、子程序和中斷服務程序等存放
      ;在0100h單元之后,在中斷矢量和主程序
      ;區之間預留一些存儲單元,以便寫入判
      ;跳指令和一些必要的現場保護程序。此外
      ;用戶也可以根據實際需要,使主程序從其
      ;它地址開始存放
      MAIN BSF STATUS,RP0 ;選擇存儲體1
      MOVLW 0XFF ;定義RA口為輸入端口
      MOVWF TRISA
      BCF STATUS,RP0 ;選擇存儲體0
      MOVLW 0X04 ;初值化ACCALO
      MOVWF ACCALO
      CALL DX ;調用DX子程序
      LOOP1 …… ;任務1
      …… ;任務2
      :
      :
      :
      GOTO LOOP1 ;反復執行任務一和任務二等
      ;***************子程序區*********************
      DX MOVF ACCALO,0 ;ACCB和ACCA低半字節相加
      ADDWF ACCBLO
      RETURN ;子程序返回
      ;****************************************
      PUSH MOVWF S_W ;保護W寄存器
      MOVF STATUS,0 ;保護STATUS寄存器
      MOVWF S_STATUS
      RETURN ;子程序返回
      ;****************************************
      POP MOVF S_STATUS,0 ;恢復STATUS寄存器
      MOVWF STATUS
      MOVF S_W,0 ;恢復W寄存器
      RETURN ;子程序返回
      ;****************中斷服務子程序區************************
      AD BCF PIR1,ADIF ;清AD中斷標志
      …… ;中斷服務主體程序
      RETURN ;子程序返回
      END

        2 四則運算子程序

        2.1 16×16位定點數加、減法子程序

        以下子程序實現2個16×16位有符號數加、減運算,其和或差用一個16位數表示。在子程序中,減法是通過對減數求補后再與被減數相加來實現的。因此,當程序從D_sub進入子程序時為減法,當從D_add進入子程序時為加法。
      子程序的入口條件和出口條件如下:
      入口條件:16位被加數/被減數存放在ACCBHI、ACCBLO中;
      16位加數/減數存放在ACCAHI、ACCALO中;
      出口條件:16位和/差存放在ACCBHI和ACCBLO中。
      以下為16×16位有符號數加、減法子程序。
      注意:在以下注釋程序中均以ACCA代替ACCAHI、ACCALO兩個字節,以ACCB代替ACCBHI、ACCBLO兩個字節。

      LIST p=16f877
      INCLUDE p16f877.inc
      ACCALO EQU 20 ;存放加數或減數低8位
      ACCAHI EQU 21 ;存放加數或減數高8位
      ACCBLO EQU 23 ;存放被加數或被減數低8位
      ACCBHI EQU 24 ;存放被加數或被減數高8位
      ORG 0X0000
      START GOTO MAIN
      ;***雙字節減法子程序,入口地址ACCB-ACCA,出口地址ACCB***
      D_sub CALL NEG_A ;求ACCA的補碼
      ;***雙字節加法子程序,入口地址ACCB+ACCA,出口地址ACCB***
      D_add MOVF ACCALO,0 ;ACCB和ACCA低半字節相加
      ADDWF ACCBLO
      BTFSC STATUS,C ;有進位否?
      INCF ACCBHI ;有,ACCB高字節加1,再加ACCAHI
      MOVF ACCAHI,0 ;ACCA、ACCB高半字節相加
      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(十進制)
      化為十六進制數:4C46H+BF2EH
      結果:0B79H(十六進制)
      【校驗舉例2】 26222+3000=29222(十進制)
      化為十六進制數: 666EH+0BB8H
      結果:7226H(十六進制)
      【例程】
      MAIN MOVLW 0X6E ;被加數666EH送ACCB
      MOVWF ACCBLO
      MOVLW 0X66
      MOVWF ACCBHI
      MOVLW 0XB8 ;加數BB8H送ACCA
      MOVWF ACCALO
      MOVLW 0X0B
      MOVWF ACCAHI
      CALL D_add ;調用雙字節加法子程序,求和
      END

        2.2 16×16位定點數乘法子程序

        子程序采用部分積右移加法實現乘法運算。乘數和被乘數分別為16位二進制有符號數(均采用補碼表示,第16位為符號位),積為32位二進制有符號數,第32位為符號位。子程序的入口條件和出口條件如下:
      入口條件:被乘數存放在ACCBHI和ACCBLO單元中,
      乘數存放在ACCAHI和ACCALO單元中。
      出口條件:積存放在ACCBHI、ACCBLO、ACCCHI和ACCCLO單元中,ACCB為高16位,ACCC為低16位。
      以下為本子程序的程序清單:

      LIST p=16f877
      INCLUDE p16f877.inc
      ACCALO EQU 20 ;存放乘數低8位
      ACCAHI EQU 21 ;存放乘數高8位
      ACCBLO EQU 23 ;存放被乘數低8位和乘積第16~23位
      ACCBHI EQU 24 ;存放被乘數高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 ;求取乘積的符號,并對負數取補
      CALL SETUP ;調用子程序,將ACCB的值送ACCD
      INCF TEMP
      CLRF ACCCHI ;清ACCC
      CLRF ACCCLO
      MLOOP BCF STATUS,C ;清進位位
      RRF ACCDHI ;ACCD右移
      RRF ACCDLO
      BTFSC STATUS,C ;判斷是否需要相加
      CALL D_add ;加乘數至ACCB,見加法程序
      BCF STATUS,C ;清進位位
      RRF ACCBHI ;右移部分乘積
      RRF ACCBLO
      RRF ACCCHI
      RRF ACCCLO
      DECFSZ TEMP ;乘法完成否?
      GOTO MLOOP ;否,繼續求乘積
      BTFSS SIGN,7 ;是,確定乘積的符號
      GOTO OVER ;為正,乘法結束
      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 ;子程序返回
      ;*******乘法運算確定結果符號判斷子程序******
      S_SIGN MOVF ACCAHI,0 ;ACCAHI異或ACCBHI,結果送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值,
      ;見雙字節加法程序
      RETURN ;ACCA和ACCB均為正,返回
      【校驗舉例1】:-24555×(-7391)=181486005(十進制)
      化為十六進制數:A015H×E321H
      結果:0AD141B5H(十六進制)
      【校驗舉例2】 16405×13089=214725045(十進制)
      化為十六進制數:4015H×3321H
      結果:0CCC71B5H(十六進制)
      【例程】
      MAIN MOVLW 0X15 ;被乘數4015H送ACCB
      MOVWF ACCBLO
      MOVLW 0X40
      MOVWF ACCBHI
      MOVLW 0X21 ;乘數3321H送ACCA
      MOVWF ACCALO
      MOVLW 0X33
      MOVWF ACCAHI
      CALL D_mpy ;調用雙字節乘法子程序,求積
      END

        2.3 16×16位定點數除法子程序

        子程序采用反復的減法算法,除數和被除數分別為16位二進制有符號數(均采用補碼表示,第16位為符號位),商為16位二進制有符號數,第16位為符號位。子程序的入口條件和出口條件如下:
      入口條件:被除數存放在ACCBHI、ACCBLO單元中;
      除數存放在ACCAHI、ACCALO單元中。
      出口條件:商存放在ACCBHI、ACCBLO單元中;
      余數存放在ACCCHI、ACCCLO單元中。

      LIST p=16f877
      INCLUDE p16f877.inc
      ACCALO EQU 20 ;存放除數低8位
      ACCAHI EQU 21 ;存放除數高8位
      ACCBLO EQU 22 ;存放被除數和商的低8位
      ACCBHI EQU 23 ;存放被除數和商的高8位
      ACCCLO EQU 24 ;存放余數低8位
      ACCCHI EQU 25 ;存放余數高8位
      ACCDLO EQU 26 ;臨時寄存器
      ACCDHI EQU 27 ;臨時寄存器
      TEMP EQU 28 ;臨時寄存器
      SIGN EQU 29 ;存放商的符號
      ORG 0X0000
      START GOTO MAIN
      ;***16×16位數除法子程序,入口地址ACCB /ACCA,出口地址ACCB ***
      ORG 0X0100
      D_div CALL S_SIGN ;確定商的符號,并將負數取補
      CALL SETUP ;初始化TEMP,將被除數移至ACCD,
      ;(SETUP子程序請參見16×16位定點數
      ;乘法子程序SETUP)
      INCF TEMP
      CLRF ACCCHI ;清余數寄存器
      CLRF ACCCLO
      DLOOP BCF STATUS,C ;清進位位
      RLF ACCDLO ;被除數、余數左移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 ;是,余數減除數
      SUBWF ACCCLO
      BTFSS STATUS,C
      DECF ACCCHI
      MOVF ACCAHI,0
      SUBWF ACCCHI
      BSF STATUS,C ;置進位位
      NOGO RLF ACCBLO ;商左移1位
      RLF ACCBHI
      DECFSZ TEMP ;循環完畢?
      GOTO DLOOP
      BTFSS SIGN,7 ;是,確定商的符號
      GOTO DIVOVER ;為正,除法結束,跳轉到結束行
      COMF ACCCLO ;為負,商和余數分別取補
      INCF ACCCLO
      BTFSC STATUS,Z
      DECF ACCCHI
      COMF ACCCHI
      CALL NEG_B ;見乘法程序中間NEG_B
      DIVOVER RETURN ;子程序返回
      ;************除法運算確定結果符號子程序*******************
      S_SIGN MOVF ACCAHI,0 ;ACCAHI異或ACCBHI,結果送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位定點數乘法子程序NEG_A)
      RETURN ;ACCA和ACCB均為負,返回
      【校驗舉例1】 -23775÷(-240)=99.0625(十進制)
      化為十六進制數:A321H÷FF10H;
      結果:(商)0063H,(余數)000FH(十六進制)。
      【校驗舉例2】 769÷3856=0.199429(十進制)
      化為十六進制數:0301H÷0F10H;
      結果:(商)0000H,(余數)0301H(十六進制)。
      【例程】
      MAIN MOVLW 0X01 ;被除數0301H送ACCB
      MOVWF ACCBLO
      MOVLW 0X03
      MOVWF ACCBHI
      MOVLW 0X10 ;除數0F10H送ACCA
      MOVWF ACCALO
      MOVLW 0X0F
      MOVWF ACCAHI
      CALL D_div ;調用雙字節除法子程序,求商
      END

        3 3字節浮點四則運算子程序

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

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

      LIST p=16f877
      INCLUDE p16f877.inc
      ACCALO EQU 20 ;存放加數或減數的尾數
      ACCAHI EQU 21
      EXPA EQU 22 ;存放加數或減數階碼
      ACCBLO EQU 23 ;存放被加數或被減數尾數以及和或差
      ACCBHI EQU 24
      EXPB EQU 25 ;存放被加數或被減數階碼
      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的補碼,將減法轉換為補碼加法
      ;***********浮點加法子程序**************
      F_add CALL SUBADJ ;調子程序判斷EXPB和EXPA的大小
      BTFSC STATUS,Z ;參與運算的兩個數階碼相等?
      GOTO PADD ;是,求尾數的和
      BTFSC STATUS,C ;EXPB>EXPA?
      CALL F_swap ;是,ACCB與ACCA互換
      MOVF EXPA,0 ;否,求取兩者的差值
      SUBWF EXPB
      SCLOOP CALL SHFTSR ;ACCB右移規格化
      INCFSZ EXPB ;EXPB=EXPA?
      GOTO SCLOOP ;否,繼續右移
      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 ;尾數相加
      BTFSS SIGN,7 ;ACCA和ACCB有負數?
      BTFSC ACCBHI,7 ;否,把和的位和次高位同時進位?
      GOTO ADD2 ;否,轉ADD2
      BTFSS ACCAHI,7 ;ACCA為負嗎?
      GOTO ADD3 ;ACCA和ACCB不同時為負,轉ADD3
      BTFSS EXPA,7 ;是,ACCB為負嗎?
      GOTO ADD3
      BSF STATUS,C ;ACCA和ACCB同為負,帶負號右移
      RRF ACCBHI
      RRF ACCBLO
      INCF EXPB
      ADD3 CLRF ACCCHI ;和(差)規格化
      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,結果送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
      ;***********浮點數規格化子程序****************
      F_norm MOVF ACCBHI ;ACCB=0?
      BTFSS STATUS,Z
      GOTO C_norm
      MOVF ACCBLO
      BTFSC STATUS,Z
      RETURN ;是,不需規格化,返回
      C_norm BTFSC ACCBHI,7 ;否。ACCB為負?
      GOTO C_norm2
      C_norm1 BTFSC ACCBHI,6 ;為正。規格化完畢?
      RETURN ;ACCBHI.6=1,規格化結束
      CALL SHFTSL ;否。ACCB左移
      DECF EXPB ;EXPB減1
      GOTO C_norm1 ;重新判斷規格化完畢否?
      C_norm2 BTFSS ACCBHI,6 ;ACCB為負。規格化完畢否?
      RETURN ;ACCBHI.6=0,規格化結束
      BCF STATUS,C
      CALL SHFTSL ;否,ACCB左移
      BSF ACCBHI,7 ;加符號
      DECF EXPB ;EXPB減1
      GOTO C_norm2 ;重新判斷規格化完畢否?
      SHFTSL BCF STATUS ,C ;ACCB左移子程序
      RLF ACCCLO
      RLF ACCCHI
      RLF ACCBLO
      RLF ACCBHI
      RETURN
      【校驗舉例1】 0.0019531+(-0.00016594)=0.00178716
      化為十六進制數:4000F8+A900F4
      結果:7520F7
      【校驗舉例2】 0.26222+3.5025=3.76478
      化為十六進制數: 4321FF+701502
      結果:787902
      【例程】
      MAIN MOVLW 0X21 ;被加數的尾數4321H送ACCB
      MOVWF ACCBLO
      MOVLW 0X43
      MOVWF ACCBHI
      MOVLW 0XFF ;被加數的階碼FFH送EXPB
      MOVWF EXPB
      MOVLW 0X15 ;加數尾數7015H送ACCA
      MOVWF ACCALO
      MOVLW 0X70
      MOVWF ACCAHI
      MOVLW 0X02 ;加數階碼送EXPA
      MOVWF EXPA
      CALL F_add ;調用浮點數加法子程序,求和
      END

        3.2 浮點數乘法子程序

      以下為浮點數乘法的程序清單。
      LIST p=16f877
      INCLUDE p16f877.inc
      ACCALO EQU 20 ;存放乘數尾數
      ACCAHI EQU 21
      EXPA EQU 22 ;存放乘數階碼
      ACCBLO EQU 23 ;存放被乘數尾數和乘積高16位
      ACCBHI EQU 24
      EXPB EQU 25 ;存放被乘數階碼
      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 ;求取乘積的符號,并對負數取補
      CALL SETUP ;調用子程序將ACCB的值送ACCD
      CLRF ACCCHI ;清ACCC
      CLRF ACCCLO
      MLOOP BCF STATUS,C ;清進位位
      RRF ACCDHI ;ACCD右移
      RRF ACCDLO
      BTFSC STATUS,C ;判斷是否需要相加
      CALL D_add ;加乘數至ACCB
      BCF STATUS,C ;清進位位
      RRF ACCBHI ;右移部分乘積
      RRF ACCBLO
      RRF ACCCHI
      RRF ACCCLO
      DECFSZ TEMP ;乘法完成否?
      GOTO MLOOP ;否,繼續循環
      MOVF EXPA,0 ;是,乘數與被乘數階碼相加,得積的階碼
      ADDWF EXPB
      MOVF ACCBHI ;ACCBHI=0?
      BTFSS STATUS,Z
      GOTO FINUP ;否,轉FINUP
      MOVF ACCBLO ;ACCB=0?
      BTFSS STATUS ,Z
      GOTO SHFT08 ;否,只有ACCBHI=0,轉SHFT08
      MOVF &nbs, p; ACCCHI,0 ;ACCB=0,將乘積左移15位
      MOVWF ACCBHI
      MOVF ACCCLO,0
      MOVWF ACCBLO
      BCF STATUS,C
      RRF ACCBHI
      RRF ACCBLO
      MOVLW .15 ;乘積階碼減15(十進制數)
      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 ;對乘積進行規格化
      BTFSS SIGN,7 ;確定乘積的符號
      GOTO OVER ;為正,乘法結束
      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 ;乘法結束,子程序返回
      ;********浮點乘除法運算確定結果符號子程序***********
      S_SIGN MOVF ACCAHI,0 ;ACCAHI異或ACCBHI,結果送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 ;返回
      ;*********浮點運算結果規格化子程序*************
      F_norm MOVF ACCBHI ;ACCB=0?
      BTFSS STATUS,Z
      GOTO C_norm
      MOVF ACCBLO
      BTFSC STATUS,Z
      RETURN ;是,不需規格化,返回
      C_norm BTFSC ACCBHI,7 ;否。ACCB為負?
      GOTO C_norm2
      C_norm1 BTFSC ACCBHI,6 ;為正。規格化完畢?
      RETURN ;ACCBHI.6=1,規格化結束
      CALL SHFTSL ;否。ACCB左移
      DECF EXPB ;EXPB減1
      GOTO C_norm1 ;重新判斷規格化完畢否?
      C_norm2 BTFSS ACCBHI,6 ;ACCB為負。規格化完畢否?
      RETURN ;ACCBHI.6=0,規格化結束
      BCF STATUS,C
      CALL SHFTSL ;否,ACCB左移
      BSF ACCBHI,7 ;加符號
      DECF EXPB ;EXPB減1
      GOTO C_norm2 ;重新判斷規格化完畢否?
      SHFTSL BCF STATUS ,C ;ACCB左移子程序
      RLF ACCCLO
      RLF ACCCHI
      RLF ACCBLO
      RLF ACCBHI
      RETURN
      【校驗舉例1】 0.0019531×(-0.00016594)=-0.000000324
      化為十六進制數:4000F8×A900F4
      結果:A900EB
      【校驗舉例2】 0.26222×3.5025=0.91842
      化為十六進制數: 4321FF×701502
      結果: 758F00
      【例程】
      MAIN MOVLW 0X21 ;被乘數的尾數4321H送ACCB
      MOVWF ACCBLO
      MOVLW 0X43
      MOVWF ACCBHI
      MOVLW 0XFF ;被乘數的階碼FFH送EXPB
      MOVWF EXPB
      MOVLW 0X15 ;乘數尾數7015H送ACCA
      MOVWF ACCALO
      MOVLW 0X70
      MOVWF ACCAHI
      MOVLW 0X02 ;乘數階碼送EXPA
      MOVWF EXPA
      CALL F_mpy ;調用浮點數乘法子程序,求積
      END

        3.3 浮點數除法子程序

      以下為浮點數除法子程序清單。
      LIST p=16f877
      INCLUDE p16f877.inc
      ACCALO EQU 20 ;存放除數的尾數

      ACCAHI EQU 21
      EXPA EQU 22 ;存放除數的階碼
      ACCBLO EQU 23 ;存放被除數的尾數和商的尾數
      ACCBHI EQU 24
      EXPB EQU 25 ;存放被除數和商的階碼
      ACCCLO EQU 26 ;存放余數
      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_div CALL S_SIGN ;確定商的符號,并將負數取補
      CLRF ACCCHI ;初始化ACCC寄存器
      CLRF ACCCLO
      CALL F_norm ;規格化ACCB
      CLRF ACCCLO
      CLRF ACCCHI
      CLRF TIMES
      MOVF ACCAHI ;除數為零?
      BTFSS STATUS,Z
      GOTO FD0 ;否,求商
      MOVF ACCALO
      BTFSC STATUS,Z
      RETLW 01 ;是,返回
      FD0 CALL NEG_A ;除數取補
      FD1 MOVF ACCBHI,0 ;ACCBHI送ACCDLO
      MOVWF ACCDLO
      CALL D_add1 ;被除數尾數大于除數尾數?
      BTFSS STATUS,C
      GOTO FD2
      RRF1 BCF STATUS,C ;是,被除數右移規格化,直到小于除數為止
      RRF ACCBHI
      RRF ACCBLO
      INCF TIMES
      RRF ACCCHI
      BCF STATUS,C
      GOTO FD1
      FD2 CALL DDIV ;否,調用雙字節除法子程序,求商的尾數
      MOVF TIMES,0 ;根據右移規格化次數調整ACCB階碼
      ADDWF EXPB
      MOVF EXPA,0 ;求商的階碼
      SUBWF EXPB
      CALL F_norm ;商規格化
      BTFSC SIGN,7 ;商為負?
      CALL NEG_B ;是,取補
      CALL NEG_A ;除數還原
      RETURN ;浮點數除法完成,返回
      ;***********雙字節純小數除法子程序***************
      DDIV MOVLW 0X0F ;初始化ACCDHI
      MOVWF ACCDHI
      DV1 BCF STATUS,C
      RLF ACCCLO ;左移商
      RLF ACCCHI
      RLF ACCBLO ;左移余數
      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 ;左移余數時移出來的數為1?
      GOTO DV2
      TESTC BTFSS STATUS,C ;是,再判斷ACCB尾數是否大于ACCA
      GOTO DV3
      DV2 MOVWF ACCBHI ;是,余數送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 ;加數、被加數低半字節相加
      ADDWF ACCBLO,0
      BTFSC STATUS,C ;有進位?
      INCF ACCDLO ;ACCD低半字節加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
      ;*********浮點乘除法運算確定結果符號子程序**********
      S_SIGN MOVF ACCAHI,0 ;ACCAHI異或ACCBHI,結果送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均為負,返回
      ;************浮點運算結果規格化子程序***************
      F_norm MOVF ACCBHI ;ACCB=0?
      BTFSS STATUS,Z
      GOTO C_norm
      MOVF ACCBLO
      BTFSC STATUS,Z
      RETLW 0 ;是,不需規格化,返回
      C_norm BTFSC ACCBHI,7 ;否。ACCB為負?
      GOTO C_norm2
      C_norm1 BTFSC ACCBHI,6 ;為正。規格化完畢?
      RETLW 0 ;ACCBHI.6=1,規格化結束
      CALL SHFTSL ;否。ACCB左移
      DECF EXPB ;EXPB減1
      GOTO C_norm1 ;重新判斷規格化完畢否?
      C_norm2 BTFSS ACCBHI,6 ;ACCB為負。規格化完畢否?
      RETLW 0 ;ACCBHI.6=0,規格化結束
      BCF STATUS,C
      CALL SHFTSL ;否,ACCB左移
      BSF ACCBHI,7 ;加符號
      DECF EXPB ;EXPB減1
      GOTO C_norm2 ;重新判斷規格化完畢否?
      SHFTSL BCF STATUS ,C ;ACCB左移子程序
      RLF ACCCLO
      RLF ACCCHI
      RLF ACCBLO
      RLF ACCBHI
      RETLW 0
      【校驗舉例1】 0.0019531÷(-0.00016594)=-12.7699
      化為十六進制數:4000F8÷A900F4
      結果:A1D704
      【校驗舉例2】 0.26222÷3.5025=0.074867
      化為十六進制數: 4321FF÷701502
      結果:4CA9FD
      【例程】
      MAIN MOVLW 0X21 ;被除數的尾數4321H送ACCB
      MOVWF ACCBLO
      MOVLW 0X43
      MOVWF ACCBHI
      MOVLW 0XFF ;被除數的階碼FFH送EXPB
      MOVWF EXPB
      MOVLW 0X15 ;除數尾數7015H送ACCA
      MOVWF ACCALO
      MOVLW 0X70
      MOVWF ACCAHI
      MOVLW 0X02 ;除數階碼送EXPA
      MOVWF EXPA
      CALL F_div ;調用浮點數除法子程序,求商
      END

        4 定點數與浮點數轉換程序

        4.1 定點數轉換成浮點數

        本子程序的功能是將雙字節定點整數(十六進制)轉換為3字節浮點數,其轉換數值范圍:-32768~32767,入口條件和出口條件如下:
      入口條件:ACCBHI、ACCBLO
      出口條件:ACCBHI、ACCBLO、EXPB
      以下為定點整數轉換成浮點數的程序清單。
      LIST p=16f877
      INCLUDE p16f877.inc
      ACCBLO EQU 23 ;存放定點整數和轉換后浮點數的尾數
      ACCBHI EQU 24
      EXPB EQU 25 ;存放轉換后浮點數的階碼
      ACCCLO EQU 26 ;臨時寄存器
      ACCCHI EQU 27 ;臨時寄存器
      ACCDLO EQU 28 ;臨時寄存器
      ACCDHI EQU 29 ;臨時寄存器
      SIGN EQU 2B ;存放被轉換數的符號

      ORG 0X0000
      START GOTO MAIN
      ORG 0X0100
      ;*********雙字節定點整數到浮點數轉換子程序***********
      DtoF CLRF SIGN ;根據被轉換數確定結果的符號,對負數取補
      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進行規格化
      BTFSS SIGN,7 ;結果為負?
      GOTO DtoF1
      CALL NEG_B ;是,求補
      DtoF1 RETURN
      ;**************浮點數規格化子程序**************
      F_norm MOVF ACCBHI ;ACCB=0?
      BTFSS STATUS,Z
      GOTO C_norm
      MOVF ACCBLO
      BTFSC STATUS,Z
      RETLW 0 ;是,不需規格化,返回
      C_norm BTFSC ACCBHI,7 ;否。ACCB為負?
      GOTO C_norm2
      C_norm1 BTFSC ACCBHI,6 ;為正。規格化完畢?
      RETLW 0 ;ACCBHI.6=1,規格化結束
      CALL SHFTSL ;否。ACCB左移
      DECF EXPB ;EXPB減1
      GOTO C_norm1 ;重新判斷規格化完畢否?
      C_norm2 BTFSS ACCBHI,6 ;ACCB為負。規格化完畢否?
      RETLW 0 ;ACCBHI.6=0,規格化結束
      BCF STATUS,C
      CALL SHFTSL ;否,ACCB左移
      BSF ACCBHI,7 ;加符號
      DECF EXPB ;EXPB減1
      GOTO C_norm2 ;重新判斷規格化完畢否?
      SHFTSL BCF STATUS ,C ;ACCB左移子程序
      RLF ACCCLO
      RLF ACCCHI
      RLF ACCBLO
      RLF ACCBHI
      RETLW 0
      【校驗舉例1】 19531(十進制)
      化為十六進制數:4C4BH
      結果:4C4B0FH
      【校驗舉例2】 2622(十進制)
      化為十六進制數: 0A3EH
      結果:51F00CH
      【例程】
      MAIN MOVLW 0X4B ;被轉換數4C4BH送ACCB
      MOVWF ACCBLO
      MOVLW 0X4C
      MOVWF ACCBHI
      CALL DtoF ;調用定點數至浮點數轉換子程序
      END

      免費預約試聽課

      亚洲另类欧美综合久久图片区_亚洲中文字幕日产无码2020_欧美日本一区二区三区桃色视频_亚洲AⅤ天堂一区二区三区

      
      

      1. 最新国产乱子伦真实在线观看 | 精品国产亚洲一区二区三区 | 亚洲国产精品盗摄 | 亚洲人成网站999久久久综合 | 色婷婷六月亚洲婷婷6月 | 在线看片免费人成视频福利 |