赞助论坛
  • 3995阅读
  • 0回复

学习单片机之---PIC乘除运算子程序 [复制链接]

楼层直达
jswr  
发帖
339
精华
1
金币
264
威望
8
贡献
7
好评
15
注册
2008-06-30
楼主    jswr 发表于: 2008-08-07 15:00:44 
工作过程中写了这些小程序,供大家参考。虽然在客户的应用中经过测试,但还是希望大家验证一下。如果有优化请告知。任何PIC单片机都适用。




#define   STATUS   3

#define   skpb   skpnc   ;skip if borrowed
#define   skpnb   skpc   ;skip if no borrow

  cblock   0x10
PROD:2         ;2 bytes for production
QUOT:2         ;2 bytes for quotient
PAVRA         ;divider/multiplier
PAVRB         ;reminder / multiplier
PAVRC         ;additional byte space
mcount         ;loop counter
  endc

  org   000h

  ;movlw   0x20;
  ;movwf   PAVRA
  ;movlw   0x30
  ;movwf   PAVRB

  call   BBYTE_DIV

  goto   $-1

;====================================
;PROD:2 = PAVRA * PAVRB
;====================================
BYTE_MUL
  clrf   PROD
  clrf   PROD+1
  movlw   .8
  movwf   mcount
_mul1
  rlf   PROD,f     ;left shift 16-bit with LSB=0
  bcf   PROD,0
  rlf   PROD+1,f  
  rlf   PAVRA,w     ;make left-rotate shift
  rlf   PAVRA,f     ;and check MSB
  skpc         ;skip if MSB=1
  goto   _mul2     ;MSB=0
  ;do when MSB=1
  movf   PAVRB,w
  addwf   PROD,f
  skpnc
  incf   PROD+1,f
_mul2  
  decfsz   mcount,f
  goto   _mul1  
  retlw   0


;====================================
;WORD divided by BYTE           =
;PROD:2 / PAVRA               =
;QUOT:2 = Quotient             =
;PAVRB = Reminder             =
;====================================
WBYTE_DIV
  movf   PAVRA,f
  skpnz
  retlw   1     ;return if divider=0
  clrf   PAVRB
  clrf   PAVRC
  clrf   QUOT
  clrf   QUOT+1
  movlw   .16
  movwf   mcount
_wdiv1
  rlf   QUOT,f     ;adjust Quotient
  rlf   QUOT+1,f
  bcf   QUOT,0
  ;
  rlf   PROD+1,w
  rlf   PROD,f
  rlf   PROD+1,f
  ;
  rlf   PAVRB,f
  rlf   PAVRC,f
  ;
  movf   PAVRA,w
  subwf   PAVRB,f
  skpb         ;skip if borrow
  goto   _wdiv2
  ;if borrow
  btfsc   PAVRC,0
  goto   _wdiv2
  addwf   PAVRB,f
  bcf   PAVRC,0
  goto   _wdiv3
_wdiv2   ;if no borrow
  bcf   PAVRC,0
  bsf   QUOT,0  
_wdiv3
  decfsz   mcount,f
  goto   _wdiv1  
  retlw   0

;====================================
;BYTE divided by BYTE           =
;PROD[0] / PAVRA             =
;QUOT[0] = Quotient           =
;PAVRB   = Reminder           =
;====================================
BBYTE_DIV
  movf   PAVRA,f
  skpnz
  retlw   1     ;return if divider=0
  clrf   PAVRB     ;clear reminder
  clrf   QUOT     ;clear quotient
  movlw   .8
  movwf   mcount     ;for 8 times shift
_bdiv1
  rlf   QUOT,f     ;adjust Quotient
  bcf   QUOT,0     ;left shift i bit
  ;
  rlf   PROD,w     ;get 1 bit, MSB first
  rlf   PROD,f     ;do rotate shift
  ;
  rlf   PAVRB,f     ;set to LSB of reminder
  ;
  movf   PAVRA,w     ;reminder - divider
  subwf   PAVRB,f
  skpb         ;skip if borrow
  goto   _bdiv2
  ;do if borrowed
  addwf   PAVRB,f     ;cancel subtraction
  goto   _bdiv3     ;go for next
_bdiv2   ;do if no borrow
  bsf   QUOT,0     ;reminder > divider
          ;update quotient
_bdiv3
  decfsz   mcount,f   ;loop test
  goto   _bdiv1     ;do 8 times
  retlw   0     ;completed

  END