• AVR Freaks

16 bit Binary to 5 digit BCD

Author
HOODEY
Super Member
  • Total Posts : 580
  • Reward points : 0
  • Joined: 2005/02/08 06:06:31
  • Status: offline
2009/08/07 21:12:31 (permalink)
0

16 bit Binary to 5 digit BCD

Am looking for a compact clealy documented routine to do this conversion.

I have searched without success..
#1

9 Replies Related Threads

    Ken_Pergola
    Super Member
    • Total Posts : 2252
    • Reward points : 0
    • Joined: 2003/11/07 12:48:48
    • Status: offline
    RE: 16 bit Binary to 5 digit BCD 2009/08/07 22:05:48 (permalink)
    0

    Hello Fernando,

    I pretty much typed your subject line into Google and found this from the PICList:

    http://techref.massmind.org/techref/microchip/math/radix/b2bu-16b5d.htm

    I hope this is what you are looking for.

    Best regards,

    Ken Pergola

    #2
    dan1138
    Super Member
    • Total Posts : 4246
    • Reward points : 0
    • Joined: 2007/02/21 23:04:16
    • Location: 0
    • Status: offline
    RE: 16 bit Binary to 5 digit BCD 2009/08/07 22:20:15 (permalink)
    0
    ORIGINAL: HOODEY

    Am looking for a compact clearly documented routine to do this conversion.

    I have searched without success..
    Ken has pointed out a routine that does the conversion you have asked for though the documenation is far from clear.

    It is likely that what you are looking for does not currently exist for the PIC 14-bit core processor.

    There may be several reasons why this is so but mainly there are two mutually exclusive goals at work here.

    The first is what you are asking for, a compact routine. 

    The second is for a routine that executes quickly.

    In general the most compact routine will use the remainder of a divide by ten to produce a stream of BCD digits from least to most significant. This routine is inefficient because division of a 16-bit value is inefficient with the PIC 14-bit core processor.

    One of the faster methods uses binary weighted decimal constants to decompose the 16-bit integer into 5 BCD digits from most to least significant digit.

    For the MSD the constants are 40000 and 20000, for the next they are 8000, 4000, 2000, 1000 then 800, 400, 200, 100, then 80, 40, 20, 10. This method uses 14 comparisons, and  up to 14 subtractions and bit sets to create 5 BCD digits. This will execute faster than even one call to a generic 16-bit division function.

    Hopefully this will give you an idea or two of how this problem may be solved.
    #3
    BitWise
    Super Member
    • Total Posts : 1238
    • Reward points : 0
    • Joined: 2004/11/09 13:24:20
    • Location: UK
    • Status: offline
    RE: 16 bit Binary to 5 digit BCD 2009/08/08 03:56:00 (permalink)
    0
    Try this. Relatively compact and whilst there are a number of adds/subs they only operate on 8-bits.

    include P12F683.inc

    errorlevel -312

    udata

    BINL res .1 ; Binary value to convert
    BINH res .1
    BCDL res .1 ; Resulting BCD value
    BCDH res .1
    BCDU res .1

    COUNT res .1 ; Counter


    .ResetVector code h'000'

    lgoto PowerOnReset


    code

    PowerOnReset:
    banksel BINL ; Set a test value
    movlw h'ff'
    movwf BINL
    movwf BINH
    call Bin2BCD ; Convert it

    goto $ ; Stop

    ;-------------------------------------------------------------------------------

    Bin2BCD:
    clrf BCDL ; Clear result
    clrf BCDH
    clrf BCDU
    movlw .16 ; Set bit counter
    movwf COUNT
    ConvertBit:
    movlw h'33' ; Correct BCD value so that
    addwf BCDL,F ; subsequent shift yields
    btfsc BCDL,.3 ; correct value.
    andlw h'f0'
    btfsc BCDL,.7
    andlw h'0f'
    subwf BCDL,F

    movlw h'33'
    addwf BCDH,F
    btfsc BCDH,.3
    andlw h'f0'
    btfsc BCDH,.7
    andlw h'0f'
    subwf BCDH,F

    rlf BINL,F ; Shift out a binary bit
    rlf BINH,F

    rlf BCDL,F ; .. and into BCD value
    rlf BCDH,F
    rlf BCDU,F

    decfsz COUNT,F ; Repeat for all bits
    goto ConvertBit
    return

    end

    Its a 'double dabble' algorithm the idea being that you can convert a binary number to decimal by doubling a running total using BCD arithmetic and adding the binary bits one at a time.

    The blocks at the start of the loop adjust the BCD value so that the subsequent doubling by the shift will yield a valid BCD digit. If you double 0, 1, 2, 3 or 4 then the result will always valid but if the digit was 5, 6, 7, 8 or 9 then doubling will yield an incorrect (hexadecimal) value a, b, c, d, e, 10 or 11. Adding an additional 6 to these values gives the correct result e.g. a + 6 = 10).

    The code tests which BCD nybbles can't be doubled by adding 3 to each digit. If the result is less than 8 (e.g. bit 3 or 7 clear) then it subtracts the 3 away again leaving be digit unchanged. If the 3 was not subtracted then when the value is shifted it becomes equivalent to adding 6 and corrects the result.

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

    Yamamoto Tsunetomo (1659-1719)
    #4
    HOODEY
    Super Member
    • Total Posts : 580
    • Reward points : 0
    • Joined: 2005/02/08 06:06:31
    • Status: offline
    RE: 16 bit Binary to 5 digit BCD 2009/08/08 07:39:20 (permalink)
    0
    Okay used the one form PIC list as I wanted 5 digits . I am trying to display RPM. E.g 7000rpm

    Thank you.
    #5
    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: 16 bit Binary to 5 digit BCD 2009/08/08 08:16:14 (permalink)
    0

    ORIGINAL: BitWise

    Its a 'double dabble' algorithm the idea being that you can convert a binary number to decimal by doubling a running total using BCD arithmetic and adding the binary bits one at a time.

    Very Nice ! Smile This is better than the one in Microchip AN526 which has some BCD routines.

    @HOODEY: BitWise's routine returns 5 digits in packed BCD format (BCDU:BCDH:BCDL).
    #6
    DougRice
    Super Member
    • Total Posts : 534
    • Reward points : 0
    • Joined: 2008/10/08 23:44:59
    • Location: 0
    • Status: offline
    RE: 16 bit Binary to 5 digit BCD 2009/08/08 12:51:56 (permalink)
    0
    Hoodey,

    I found this and used it.

    http://www.dattalo.com/technical/software/pic/bcd.txt

    This routine is fast and documented. Not sure I follow how it works.

    I tried one doing BCD additions, but it was very slow in comparission.



    Doug
    #7
    BitWise
    Super Member
    • Total Posts : 1238
    • Reward points : 0
    • Joined: 2004/11/09 13:24:20
    • Location: UK
    • Status: offline
    RE: 16 bit Binary to 5 digit BCD 2009/08/08 13:20:28 (permalink)
    0

    ORIGINAL: DougRice

    This routine is fast and documented. Not sure I follow how it works.

    Doesn't really count as documented then ;-)

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

    Yamamoto Tsunetomo (1659-1719)
    #8
    ppater
    Super Member
    • Total Posts : 1002
    • Reward points : 0
    • Joined: 2006/08/26 10:33:06
    • Location: Ivry, France
    • Status: offline
    RE: 16 bit Binary to 5 digit BCD 2009/08/08 22:33:38 (permalink)
    0
    Hi,
    It was in pic list mine of code as somebody said before...
    (Here: http://www.piclist.com/techref/microchip/math/radix/b2bu-16b5d.htm)
    Read the warning at end of page for PIC18 translation.

    Scott has added its own comments because original doesn't have any documentation.
    By the way Scott's PIC pages (http://www.dattalo.com/technical/software/software.php) are also a great mine of PIC code.
    post edited by ppater - 2009/08/08 22:47:41

    Best regards,
    Philippe.

    Pic Micro Pascal for All!
    #9
    DougRice
    Super Member
    • Total Posts : 534
    • Reward points : 0
    • Joined: 2008/10/08 23:44:59
    • Location: 0
    • Status: offline
    RE: 16 bit Binary to 5 digit BCD 2009/08/15 00:00:43 (permalink)
    0
    BitWise,

    At this point I say "If you are trying to be clever with me, you are wasting your time." - The kipper family

    Like most people, I believe somebody else understood it, and it seems to work, so I will use it without further thought.

    Seriously, It is documented. I have tried to follow it and would like to understand it one day!

    I coded this, and my code took ages.

    BCD=1
    BCDacc=0
    binary= value

    for 16 bits do
    If lsb of binary is 1 add BCD to BCDacc then
    BCDacc = BCDacc + BCD
    BCDacc BCDadjust(BCDacc)
    end

    BCD = BCD + BCD
    BCD= BCDadjust(BCD)
    shiftright( binary )

    BCDacc now contains the decimal digits.


    I used this code. It was fast.

    ;
    ;********************************************************************
    ; Binary To BCD Conversion Routine
    ; This routine converts a 16 Bit binary Number to a 5 Digit
    ; This routine converts a 24 Bit binary Number to an 8 Digit
    ; BCD Number. This routine is useful since PIC16C55 & PIC16C57
    ; have two 8 bit ports and one 4 bit port ( total of 5 BCD digits)
    ;
    ; The 16 bit binary number is input in locations H_byte and
    ; L_byte with the high byte in H_byte.
    ; The 5 digit BCD number is returned in R0, R1 and R2 with R0
    ; containing the MSD in its right most nibble.
    ;
    ; Performance : 16 bit 24 bit
    ; Program Memory : 35
    ; Clock Cycles : 885 2100 approx
    ;
    ; This file is based on the file BCD.ASM found on www.crownhill.co.uk
    ;
    ;*******************************************************************;
    ;
    ;

    B2_BCD bcf STATUS,0 ; clear the carry bit
    movlw .32 ; number of bits to convert.
    movwf BCDcount
    clrf BCDop0
    clrf BCDop1
    clrf BCDop2
    clrf BCDop3
    clrf BCDop4

    BCDloop16
    bcf STATUS,C
    btfsc BCDip3,7
    bsf STATUS,C
    rlf BCDip0
    rlf BCDip1
    rlf BCDip2
    rlf BCDip3

    rlf BCDop0
    rlf BCDop1
    rlf BCDop2
    rlf BCDop3
    rlf BCDop4
    ;
    decfsz BCDcount
    goto BCDadjDEC
    RETLW 0
    ;
    BCDadjDEC
    ; movlw BCDop4
    ; movwf FSR
    ; call BCDadjBCD

    movlw BCDop0
    movwf FSR
    call BCDadjBCD

    movlw BCDop1
    movwf FSR
    call BCDadjBCD
    ;
    movlw BCDop2
    movwf FSR
    call BCDadjBCD
    ;
    movlw BCDop3
    movwf FSR
    call BCDadjBCD
    ;
    goto BCDloop16
    ;
    BCDadjBCD
    movlw 0x03
    addwf 0,W
    movwf BCDtemp
    btfsc BCDtemp,3 ; test if result > 7
    movwf 0
    movlw 0x30
    addwf 0,W
    movwf BCDtemp
    btfsc BCDtemp,7 ; test if result > 7
    movwf 0 ; save as MSD
    RETLW 0
    post edited by DougRice - 2009/08/15 00:15:49
    #10
    Jump to:
    © 2021 APG vNext Commercial Version 4.5