• AVR Freaks

Tip: Divide WREG by 10, PIC18

Page: 12 > Showing page 1 of 2
Author
ppater
Super Member
  • Total Posts : 1002
  • Reward points : 0
  • Joined: 2006/08/26 10:33:06
  • Location: Ivry, France
  • Status: offline
2009/12/18 09:15:25 (permalink)
5 (1)

Tip: Divide WREG by 10, PIC18

Here's a wonderful tip that I must share:

Given WREG = number to divide by 10,

MULLW .51
MOVLW .50
ADDWF PRODH, W
RRNCF WREG, W

It gives (number / 10) in WREG!!!

Any comment?

Best regards,
Philippe.

Pic Micro Pascal for All!
#1

37 Replies Related Threads

    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 10:59:51 (permalink)
    0
    Hmmm, it does not work with 69... or am I missing something? Smile

    69*51=3519
    PRODH=13
    +50=63
    /2=31



    GENOVA :D :D ! GODO
    #2
    ppater
    Super Member
    • Total Posts : 1002
    • Reward points : 0
    • Joined: 2006/08/26 10:33:06
    • Location: Ivry, France
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 11:09:59 (permalink)
    0
    ORIGINAL: DarioG

    Hmmm, it does not work with 69... or am I missing something? Smile

    69*51=3519
    PRODH=13
    +50=63
    /2=31

    [&:] My fault, I have not tested... 50 must be added to the 16 bits result:

    Given WREG = number to divide by 10,

    MULLW .51
    MOVLW .50
    ADDWF PRODL, F
    MOVLW .0
    ADDWFC PRODH, W
    RRNCF WREG, W
    post edited by ppater - 2009/12/18 11:12:42

    Best regards,
    Philippe.

    Pic Micro Pascal for All!
    #3
    BitWise
    Super Member
    • Total Posts : 1238
    • Reward points : 0
    • Joined: 2004/11/09 13:24:20
    • Location: UK
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 12:06:40 (permalink)
    0
    How about...

    addlw .1
    mullw .51
    bcf STATUS,C
    rrcf PRODH,W

    Provided WREG is not 255 on entry
    post edited by BitWise - 2009/12/18 12:07:52

    Throughout your life advance daily, becoming more skillful than yesterday, more skillful than today. This is never-ending.

    Yamamoto Tsunetomo (1659-1719)
    #4
    ppater
    Super Member
    • Total Posts : 1002
    • Reward points : 0
    • Joined: 2006/08/26 10:33:06
    • Location: Ivry, France
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 12:08:33 (permalink)
    0

    Given WREG = number to divide by 10,

    ; First "divide by 5"
    MULLW .51
    MOVLW .50
    ADDWF PRODL, F
    MOVLW .0
    ADDWFC PRODH, W
    ; Now divide by 2
    RRNCF WREG, W

    ...

    It's also easy to compute the remainder (modulo):

    ; save number
    MOVWF Temp
    ; First "divide by 5"
    MULLW .51
    MOVLW .50
    ADDWF PRODL, F
    MOVLW .0
    ADDWFC PRODH, W
    ; Now divide by 2
    RRNCF WREG, W
    ; Now multiply by 10
    MULLW .10
    ; Now get remainder
    MOVF PRODL, W
    SUBWF Temp, W


    Best regards,
    Philippe.

    Pic Micro Pascal for All!
    #5
    Stefan Uhlemayr
    Super Member
    • Total Posts : 4292
    • Reward points : 0
    • Joined: 2005/05/12 12:25:46
    • Location: Germany
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 14:28:02 (permalink)
    0
    ORIGINAL: BitWise

    How about...

    addlw .1
    mullw .51
    bcf STATUS,C
    rrcf PRODH,W

    Provided WREG is not 255 on entry
    Thanks for this neat DIV10-routine, done in 4 instructions! Smile And thanks for Philippe for having the initial-idea. wink Of course, this will be added to the neat asm-tricks in the software-gallery!

    Thanks,
    Stefan
    #6
    ppater
    Super Member
    • Total Posts : 1002
    • Reward points : 0
    • Joined: 2006/08/26 10:33:06
    • Location: Ivry, France
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 14:55:45 (permalink)
    +2 (1)

    ORIGINAL: BitWise

    How about...

    addlw .1
    mullw .51
    bcf STATUS,C
    rrcf PRODH,W

    Provided WREG is not 255 on entry


    How about...

    addlw .1
    mullw .51
    rrcf PRODH,W

    wink Provided WREG is not 255 on entry, there is no carry ...


    Best regards,
    Philippe.

    Pic Micro Pascal for All!
    #7
    Stefan Uhlemayr
    Super Member
    • Total Posts : 4292
    • Reward points : 0
    • Joined: 2005/05/12 12:25:46
    • Location: Germany
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 15:06:11 (permalink)
    0
    ORIGINAL: ppater

    How about...

    addlw .1
    mullw .51
    rrcf PRODH,W

    wink Provided WREG is not 255 on entry, there is no carry ...
    Very nice.wink And how about:

      addlw .1
      btfsc STATUS,C
      addlw .255
      mullw .51
      rrcf PRODH,W
    5 instructions then, but nothing provided...wink

    EDIT: Corrected mistake, thanks Philippe! Smile
    post edited by Stefan Uhlemayr - 2009/12/18 15:26:15
    #8
    ppater
    Super Member
    • Total Posts : 1002
    • Reward points : 0
    • Joined: 2006/08/26 10:33:06
    • Location: Ivry, France
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 15:18:50 (permalink)
    0

    ORIGINAL: Stefan Uhlemayr

    ORIGINAL: ppater

    How about...

    addlw .1
    mullw .51
    rrcf PRODH,W

    wink Provided WREG is not 255 on entry, there is no carry ...
    Very nice.wink And how about:

      addlw .1
      btfsc STATUS,C
      movlw .255
      mullw .51
      rrcf PRODH,W
    5 instructions then, but nothing provided...wink

    Does not work, movlw .255 does not reset carry...

    Best regards,
    Philippe.

    Pic Micro Pascal for All!
    #9
    ppater
    Super Member
    • Total Posts : 1002
    • Reward points : 0
    • Joined: 2006/08/26 10:33:06
    • Location: Ivry, France
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 15:22:12 (permalink)
    0

    ORIGINAL: ppater

    ORIGINAL: Stefan Uhlemayr

    ORIGINAL: ppater

    How about...

    addlw .1
    mullw .51
    rrcf PRODH,W

    wink Provided WREG is not 255 on entry, there is no carry ...
    Very nice.wink And how about:

      addlw .1
      btfsc STATUS,C
      movlw .255
      mullw .51
      rrcf PRODH,W
    5 instructions then, but nothing provided...wink

    Does not work, movlw .255 does not reset carry...

    So:

    addlw .1
    btfsc STATUS,C
    addlw .255
    mullw .51
    rrcf PRODH,W

    Best regards,
    Philippe.

    Pic Micro Pascal for All!
    #10
    Stefan Uhlemayr
    Super Member
    • Total Posts : 4292
    • Reward points : 0
    • Joined: 2005/05/12 12:25:46
    • Location: Germany
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 15:25:31 (permalink)
    0
    ORIGINAL: ppater

    So:

    addlw .1
    btfsc STATUS,C
    addlw .255
    mullw .51
    rrcf PRODH,W
    Yes, this way works. Thanks for correction (I shouldn't write code without simulator [8|]).

    Greetings,
    Stefan
    #11
    ppater
    Super Member
    • Total Posts : 1002
    • Reward points : 0
    • Joined: 2006/08/26 10:33:06
    • Location: Ivry, France
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 15:49:51 (permalink)
    0
    ORIGINAL: Stefan Uhlemayr
    Yes, this way works. Thanks for correction (I shouldn't write code without simulator [8|]).

    Me too grin ...
    Great piece of collaborative work!
    wink
    post edited by ppater - 2009/12/18 15:51:47

    Best regards,
    Philippe.

    Pic Micro Pascal for All!
    #12
    barbiani
    Super Member
    • Total Posts : 246
    • Reward points : 0
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 17:18:38 (permalink)
    0
    How about divide by 100 and modulo? In a new thread of course grin
    #13
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/18 17:37:16 (permalink)
    0
    ok Smile been away for a while and now we get it all working!!

    good job

    GENOVA :D :D ! GODO
    #14
    ppater
    Super Member
    • Total Posts : 1002
    • Reward points : 0
    • Joined: 2006/08/26 10:33:06
    • Location: Ivry, France
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/19 02:29:44 (permalink)
    0
    ORIGINAL: future56k

    How about divide by 100 and modulo? In a new thread of course grin


    It's straight forward:

    ; First "divide by 5"
    ADDLW .1
    BTFSC STATUS, C
    ADDLW .255
    MULLW .51
    ; Now "divide by 10"
    RRCF PRODH, W
    ; Now "divide by 50"
    MULLW .52
    ; Now "divide by 100"
    BCF STATUS, C Edited: here clearing status is mandatory...
    RRCF PRODH, W
    ...
    For remainder (modulo 100):
    If the divide was just made before, the same method as modulo 10 can be used,
    else I guess that a classic sub/add sequence is the most effective :

    MOVWF Temp
    MOVLW .200
    SUBWF Temp, F
    BTFSS STATUS, C
    ADDWF Temp, F
    MOVLW .100
    SUBWF Temp, F
    BTFSS STATUS, C
    ADDWF Temp, F
    MOVF Temp, W

    post edited by ppater - 2009/12/19 02:41:42

    Best regards,
    Philippe.

    Pic Micro Pascal for All!
    #15
    ppater
    Super Member
    • Total Posts : 1002
    • Reward points : 0
    • Joined: 2006/08/26 10:33:06
    • Location: Ivry, France
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/19 05:01:59 (permalink)
    0
    Smile And now...
    A full 8 bits binary to 3 digits routine based on previous code:
    (provided bank selection is good)

    ADDLW .1 ; adjust for 255?
    BTFSS STATUS, C
    ADDLW .255 ; yes, set to 255
    MULLW .51 ; "div by 5"
    RRCF PRODH, W ; div by 2
    MOVWF Tens ; save tens and ones
    MULLW .52 ; "div by 5"
    BCF STATUS, C
    RRCF PRODH, W ; div by 2
    MOVWF Hunds ; save hunds
    MOVF Tens, W ; get back tens and ones
    MOVWF Ones ; save it in ones
    MULLW .51 ; "div by 5"
    RRCF PRODH, W ; div by 2
    MOVWF Tens ; save tens
    MULLW .10 ; restore power of 10
    MOVF PRODL, W ; get result
    SUBWF Ones, F ; adjust ones
    post edited by ppater - 2009/12/19 07:32:51

    Best regards,
    Philippe.

    Pic Micro Pascal for All!
    #16
    DarioG
    Allmächtig.
    • Total Posts : 54081
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: Oesterreich
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/19 06:28:00 (permalink)
    0
    nice Smile

    GENOVA :D :D ! GODO
    #17
    K8LH
    Super Member
    • Total Posts : 1887
    • Reward points : 0
    • Joined: 2004/03/26 05:12:34
    • Location: Michigan, USA
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/19 06:36:08 (permalink)
    0
    Here's a 12 word "loop" version I came up with for a very resource limited 10F200 project which should work on 12/14/16 bit core devices (using lots more instruction cycles);

    Regards, Mike

    ;******************************************************************
    ;                                                                 *
    ;  8 bit to 3 digit half-packed BCD, Mike McLaren, K8LH (Jan-09)  *
    ;                                                                 *
    ;   input: WREG, 0x00..0xFF, 0..255                               *
    ;  output: tens, 0x00..0x25, packed bcd                           *
    ;          ones, 0x00..0x09                                       *
    ;                                                                 *
    ;  12 words, 2 variables, 12/14/16 bit core devices               *
    ;                                                                 *
    Bin2Bcd
             clrf    tens            ;
             decf    tens,F          ; preset 'tens' to -1
    div10   movwf   ones            ;
             incf    tens,F          ; bump 'tens', 0x00..0x25
             movlw   6               ; using "packed bcd" format
             addwf   tens,W          ; bcd "digit carry"?
             skpndc                  ; no, skip, else
             movwf   tens            ; fix 'tens'
             movlw   10              ; ones = ones - 10
             subwf   ones,W          ; borrow?
             bc      div10           ; no, branch, else

    And here's the companion routine for sending the 3-digit decimal number out your PutLCD or Put232 routine with leading zero suppression;

    ;
    ;  print number right justified and suppress leading zeros
    ;
    PutDec
             movlw   " "             ; seed leading zero 'mask'
             movwf   mask            ; mask = 0x20 = " " (space char)
             swapf   tens,W          ; get hundreds, 0..2
             call    PutDigit        ; print " " or "1".."2"
             movf    tens,W          ; get tens, 0..9
             call    PutDigit        ; print " " or "0".."9"
             movf    ones,W          ; get ones, 0..9
             goto    PutNumber       ; always print "0".."9"
    PutDigit
             andlw   0x0F            ;
             skpz                    ; zero? yes, skip, else
    PutNumber
             bsf     mask,4          ; mask = 0x30 = "0"
             iorwf   mask,W          ; wreg = " " or "0".."9"
             goto    Put232          ; Put232 or PutLCD


    #18
    1and0
    Access is Denied
    • Total Posts : 12108
    • Reward points : 0
    • Joined: 2007/05/06 12:03:20
    • Location: Harry's Gray Matter
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/19 07:39:42 (permalink)
    +4 (2)
    ORIGINAL: Stefan Uhlemayr

    ORIGINAL: ppater

    So:

    addlw .1
    btfsc STATUS,C
    addlw .255
    mullw .51
    rrcf PRODH,W
    Yes, this way works. Thanks for correction (I shouldn't write code without simulator [8|]).

    How about...

    mullw .205 ;W = W*205/2048
    rlncf PRODH,w
    swapf WREG
    andlw 0x1F
    Tested with WREG = 0 to 255 in the simulator.
    post edited by 1and0 - 2009/12/19 07:55:39
    #19
    Stefan Uhlemayr
    Super Member
    • Total Posts : 4292
    • Reward points : 0
    • Joined: 2005/05/12 12:25:46
    • Location: Germany
    • Status: offline
    RE: Tip: Divide WREG by 10, PIC18 2009/12/19 10:29:21 (permalink)
    0
    ORIGINAL: 1and0

    How about...

    mullw .205 ;W = W*205/2048
    rlncf PRODH,w
    swapf WREG
    andlw 0x1F
    Tested with WREG = 0 to 255 in the simulator.
    5 stars for this! Smile I think, now we've got the perfect implementation of W DIV 10.
    ORIGINAL: ppater

    Great piece of collaborative work!
    I can only second this! wink
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2021 APG vNext Commercial Version 4.5