Hex to BCD conversion routine

Discussion in 'Programmer's Corner' started by RG23, Apr 18, 2011.

  1. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    Does anyone have an idea about Hex to BCD conversion routine using pic?

    Please let me know

    Thanks
     
    #1
  2. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    Is there any subroutine available for converting hex to bcd?????
     
    #2
  3. DumboFixer

    DumboFixer Active Member

    Joined:
    Feb 10, 2009
    219
    34
    What language are you using ?

    Have you tried Google or Bing ?

    Have you had a go yourself ?
     
    #3
  4. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    i am using assembly language in pic

    I tried google but didn't get any satisfying results

    If you have any idea please let me know

    Thanks
     
    #4
  5. Markd77

    Markd77 Senior Member

    Joined:
    Sep 7, 2009
    2,803
    591
    #5
  6. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    #6
  7. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    At present when i divide 0x64 (decimal 100) by 0x21 (decimal 33)

    I get 3.07 on LCD which is hex but i want to see 3.03 (decimal)
     
    #7
  8. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    i have still not figured it out

    any help would be appreciated

    Thanks
     
    #8
  9. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    If you are not worried about memory, the unpacked BCD is easier to work with.


    Which unpacked bcd routine are you referring to?
     
    #9
  10. Markd77

    Markd77 Senior Member

    Joined:
    Sep 7, 2009
    2,803
    591
    I meant one of the binary to unpacked BCD links.
    Unpacked stores each BCD digit in a byte, but packed stores 2 BCD digits in each byte.
    eg. 93 is stored as b'10010011' in packed but as b'00001001' and b'00000011' in unpacked.

    I think we need to see your code to be more help.
     
    #10
  11. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    movlw h'22'
    movwf count209 //////divisor

    movlw h'00'
    movwf X_IntH /////MSB of dividend

    movlw h'64'
    movwf X_IntL /////LSB of dividend

    Div16by8to16_16:

    clrf X_FracL
    clrf X_FracH

    movlw 0x10
    movwf Counter

    movf count209, 0 ;keep value in accumulator
    clrf count209 ;and use count209 register as temporary

    ;Find integer part

    Div16by8to16_16a
    rlf X_IntL, 1 ;shift next msb into temporary
    rlf X_IntH, 1
    rlf count209, 1
    rlf Counter, 1 ;carry has 9th bit of temporary

    ;copy carry to counter
    subwf count209, 1 ;substract count209 (in w) from temporary
    skpnc ;if no borrow, set Counter.0

    bsf Counter, 0
    btfss Counter, 0 ;if Counter.0 clear (borrow) restore temporary
    addwf count209, 1
    bcf CARRY ;restore counter
    rrf Counter, 1
    ;at this point carry is the next bit of result

    decfsz Counter, f ;repeat 16 times to find integer part
    goto Div16by8to16_16a

    ;shift last integer bit
    rlf X_IntL, 1
    rlf X_IntH, 1

    ;Find fractional part
    bsf Counter, 4 ;Counter = 16

    Div16by8to16_16b
    ;Shift zero bit into temporary
    rlf X_FracL, 1
    rlf X_FracH, 1
    rlf count209, 1
    rlf Counter, 1 ;carry has 9th bit of temporary

    ;copy carry to counter
    subwf count209, 1 ;substract count209(in w) from temporary
    skpnc ;if no borrow, set Counter.0
    bsf Counter, 0
    btfss Counter, 0 ;if Counter.0 clear (borrow) restore temporary
    addwf count209, 1

    bcf CARRY ;restore counter
    rrf Counter, 1
    decfsz Counter, 1 ;repeat 16 times
    goto Div16by8to16_16b

    ;shift last fractional bit
    rlf X_FracL, 1
    rlf X_FracH, 1
    movwf count209 ;restore divisor
     
    Last edited: Apr 19, 2011
    #11
  12. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    I have used the following routine which works fine but gives me the result in hex


    16 bits by 8 with result as fraction rather than remainder by Nikolai Golovchenko

    For eg:

    I use count209 divisor as h'22' ie decimal 34

    and dividend as h'64' ie decimal 100

    It gives me the result of hex division as 2.f0f0 on LCD display which is correct as per hex format

    but I want to see 2.9411 on LCD ie the decimal answer

    I hope I made my question clear

    If you have any idea please let me know

    Thanks
     
    Last edited: Apr 19, 2011
    #12
  13. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    @Mark

    did you figure out anything I need to modify from the code above?????
     
    #13
  14. Markd77

    Markd77 Senior Member

    Joined:
    Sep 7, 2009
    2,803
    591
    It's an unusual method but if you want to continue with it, it is possible.

    You have X_FracH and X_FracL which has a range of 0-65535 for representing the fractional part of the answer, range 0-0.999
    If you divide X_Frac by 6.5535 (multiply by 0.152588) you get a result which is 0-9999 which you could then convert to BCD and display.

    You can use this:
    http://www.piclist.com/techref/piclist/codegen/constdivmul.htm
    to generate the code (multiplication by a constant is faster).
    It gives the result:

    Code ( (Unknown Language)):
    1. ; ACC = ACC * 0.152588
    2. ; Temp = TEMP
    3. ; ACC size = 16 bits
    4. ; Error = 0.1 %
    5. ; Bytes order = big endian
    6. ; Round = no
    7.  
    8. ; ALGORITHM:
    9. ; Clear accumulator
    10. ; Add input / 8 to accumulator
    11. ; Add input / 32 to accumulator
    12. ; Substract input / 256 from accumulator
    13. ; Add input / 4096 to accumulator
    14. ; Move accumulator to result
    15. ;
    16. ; Approximated constant: 0.152588, Error: 4.096e-007 %
    17.  
    18. ;     Input: ACC0 .. ACC1, 16 bits
    19. ;    Output: ACC0 .. ACC1, 14 bits
    20. ; Code size: 54 instructions
    21.  
    22.     cblock
    23.     ACC0
    24.     ACC1
    25.     TEMP0
    26.     TEMP1
    27.     endc
    28.  
    29. ;copy accumulator to temporary
    30.     movf    ACC0, w
    31.     movwf   TEMP0
    32.     movf    ACC1, w
    33.     movwf   TEMP1
    34.  
    35.  
    36. ;shift accumulator right 4 times
    37.     swapf   ACC1, w
    38.     andlw   0x0F
    39.     movwf   ACC1
    40.     swapf   ACC0, w
    41.     movwf   ACC0
    42.     andlw   0xF0
    43.     iorwf   ACC1, f
    44.     xorwf   ACC0, f
    45.  
    46. ;substract temporary from accumulator
    47.     movf    TEMP1, w
    48.     subwf   ACC1, f
    49.     movf    TEMP0, w
    50.     skpc
    51.     incfsz  TEMP0, w
    52.     subwf   ACC0, f
    53.  
    54. ;shift accumulator right 3 times
    55.     rrf ACC0, f
    56.     movlw   0x80
    57.     xorwf   ACC0, f ;invert bit shifted from carry
    58.     rrf ACC1, f
    59.     rlf ACC0, w
    60.     rrf ACC0, f
    61.     rrf ACC1, f
    62.     rlf ACC0, w
    63.     rrf ACC0, f
    64.     rrf ACC1, f
    65.  
    66. ;add temporary to accumulator
    67.     movf    TEMP1, w
    68.     addwf   ACC1, f
    69.     movf    TEMP0, w
    70.     skpnc
    71.     incfsz  TEMP0, w
    72.     addwf   ACC0, f
    73.  
    74. ;shift accumulator right 2 times
    75.     clrc
    76.     rrf ACC0, f
    77.     rrf ACC1, f
    78.     clrc
    79.     rrf ACC0, f
    80.     rrf ACC1, f
    81.  
    82. ;add temporary to accumulator
    83.     movf    TEMP1, w
    84.     addwf   ACC1, f
    85.     movf    TEMP0, w
    86.     skpnc
    87.     incfsz  TEMP0, w
    88.     addwf   ACC0, f
    89.  
    90. ;shift accumulator right 3 times
    91.     rrf ACC0, f
    92.     rrf ACC1, f
    93.     clrc
    94.     rrf ACC0, f
    95.     rrf ACC1, f
    96.     clrc
    97.     rrf ACC0, f
    98.     rrf ACC1, f
    99.  
    100. ; Generated by [URL="http://www.piclist.com/cgi-bin/constdivmul.exe"]www.piclist.com/cgi-bin/constdivmul.exe[/URL] (1-May-2002 version)
    101. ; Wed Apr 20 13:37:29 2011  GMT
     
    #14
  15. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    i think the above code is not hex to bcd
     
    #15
  16. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    #16
  17. Markd77

    Markd77 Senior Member

    Joined:
    Sep 7, 2009
    2,803
    591
    I think a lot of your questions are due to a confusion between hex, binary, decimal and binary coded decimal. The first 3 are just different ways of describing the same number, BCD is fundamentally different in that it can't easily be used by microcontrollers. It is only useful for displaying numbers for humans. All numbers in the microcontroller are binary but they have their hex and decimal equivalents.
    Something like the 16 bit binary to BCD on the page I linked to before is sufficient for your needs.
    Could you do a bit of reading about the number systems, reread this thread and see if it makes more sense.
     
    #17
  18. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    @mark

    Now the integer part of the previous hexadecimal result i get in decimal

    but the fractional part is still not accurate
     
    #18
  19. JDT

    JDT Well-Known Member

    Joined:
    Feb 12, 2009
    658
    83
    Here are some routines that I use. They are not written by me as you can see by the headers. Piclist is a good place to go. Google for it.

    Change the extension of the attachment from .txt to .asm could not attach .asm.
     
    #19
  20. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    298
    2
    Actually now I know how to convert the integer part of hex to integer bcd

    but the same approach didn't work for the fractional part.
     
    #20
Loading...