關鍵字:
商品分類:

聯系人:王先生 
電   話:(025)84412473 
            (025)86642420  86642429
手   機:(0)13905184409
            (0)13382799382 
QQ:717279726     
QQ:264354310      
傳  真: (025)86642420
郵  箱: 
郵  編:210000 
地  址:江蘇省南京市中山東路110號4樓403室(華龍電子城) 

技術文章
您當前所在的位置:首頁>技術文章>詳細信息
PIC-PIC16F877單片機算法子程序
發表時間:2011-6-21  文字 〖 〗  閱讀次數:3992   [關閉窗口]

PIC-PIC16F877單片機算法子程序

PIC16F877單片機運算子程序2

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


文章分頁:重庆快乐十分开奖规律 
上一條:AVR單片機SPI通訊實例程序

版權所有:南京愛思電子有限公司   
ICP備:蘇ICP備05023762號-1        聯系我們:0)13905184409        (0)13382799382 
 QQ交談:1)QQ717279726       2)QQ264354310