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
    Messages:
    290
    Does anyone have an idea about Hex to BCD conversion routine using pic?

    Please let me know

    Thanks
  2. RG23

    RG23 Thread Starter Member

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

    DumboFixer Active Member

    Joined:
    Feb 10, 2009
    Messages:
    205
    Location:
    South East UK
    What language are you using ?

    Have you tried Google or Bing ?

    Have you had a go yourself ?
  4. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    Messages:
    290
    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
  5. Markd77

    Markd77 Well-Known Member

    Joined:
    Sep 7, 2009
    Messages:
    2,794
    Location:
    Birmingham
  6. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    Messages:
    290
  7. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    Messages:
    290
    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)
  8. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    Messages:
    290
    i have still not figured it out

    any help would be appreciated

    Thanks
  9. RG23

    RG23 Thread Starter Member

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


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

    Markd77 Well-Known Member

    Joined:
    Sep 7, 2009
    Messages:
    2,794
    Location:
    Birmingham
    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.
  11. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    Messages:
    290
    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
  12. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    Messages:
    290
    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
  13. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    Messages:
    290
    @Mark

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

    Markd77 Well-Known Member

    Joined:
    Sep 7, 2009
    Messages:
    2,794
    Location:
    Birmingham
    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:
    ; ACC = ACC * 0.152588
    ; Temp = TEMP
    ; ACC size = 16 bits
    ; Error = 0.1 %
    ; Bytes order = big endian
    ; Round = no
    
    ; ALGORITHM:
    ; Clear accumulator
    ; Add input / 8 to accumulator
    ; Add input / 32 to accumulator
    ; Substract input / 256 from accumulator
    ; Add input / 4096 to accumulator
    ; Move accumulator to result
    ;
    ; Approximated constant: 0.152588, Error: 4.096e-007 %
    
    ;     Input: ACC0 .. ACC1, 16 bits
    ;    Output: ACC0 .. ACC1, 14 bits
    ; Code size: 54 instructions
    
    	cblock
    	ACC0
    	ACC1
    	TEMP0
    	TEMP1
    	endc
    
    ;copy accumulator to temporary
    	movf	ACC0, w
    	movwf	TEMP0
    	movf	ACC1, w
    	movwf	TEMP1
    
    
    ;shift accumulator right 4 times
    	swapf	ACC1, w
    	andlw	0x0F
    	movwf	ACC1
    	swapf	ACC0, w
    	movwf	ACC0
    	andlw	0xF0
    	iorwf	ACC1, f
    	xorwf	ACC0, f
    
    ;substract temporary from accumulator
    	movf	TEMP1, w
    	subwf	ACC1, f
    	movf	TEMP0, w
    	skpc
    	incfsz	TEMP0, w
    	subwf	ACC0, f
    
    ;shift accumulator right 3 times
    	rrf	ACC0, f
    	movlw	0x80
    	xorwf	ACC0, f	;invert bit shifted from carry
    	rrf	ACC1, f
    	rlf	ACC0, w
    	rrf	ACC0, f
    	rrf	ACC1, f
    	rlf	ACC0, w
    	rrf	ACC0, f
    	rrf	ACC1, f
    
    ;add temporary to accumulator
    	movf	TEMP1, w
    	addwf	ACC1, f
    	movf	TEMP0, w
    	skpnc
    	incfsz	TEMP0, w
    	addwf	ACC0, f
    
    ;shift accumulator right 2 times
    	clrc
    	rrf	ACC0, f
    	rrf	ACC1, f
    	clrc
    	rrf	ACC0, f
    	rrf	ACC1, f
    
    ;add temporary to accumulator
    	movf	TEMP1, w
    	addwf	ACC1, f
    	movf	TEMP0, w
    	skpnc
    	incfsz	TEMP0, w
    	addwf	ACC0, f
    
    ;shift accumulator right 3 times
    	rrf	ACC0, f
    	rrf	ACC1, f
    	clrc
    	rrf	ACC0, f
    	rrf	ACC1, f
    	clrc
    	rrf	ACC0, f
    	rrf	ACC1, f
    
    ; Generated by www.piclist.com/cgi-bin/constdivmul.exe (1-May-2002 version)
    ; Wed Apr 20 13:37:29 2011  GMT
  15. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    Messages:
    290
    i think the above code is not hex to bcd
  16. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    Messages:
    290
  17. Markd77

    Markd77 Well-Known Member

    Joined:
    Sep 7, 2009
    Messages:
    2,794
    Location:
    Birmingham
    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.
  18. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    Messages:
    290
    @mark

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

    but the fractional part is still not accurate
  19. JDT

    JDT Well-Known Member

    Joined:
    Feb 12, 2009
    Messages:
    577
    Location:
    UK
    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.

    Attached Files:

  20. RG23

    RG23 Thread Starter Member

    Joined:
    Dec 6, 2010
    Messages:
    290
    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.
Similar Threads: conversion routine
Forum Title Date
Programmer's Corner Unsigned int to signed int conversion Jul 22, 2013
Programmer's Corner Dynamic c lan to rs232 conversion Apr 5, 2013
Programmer's Corner A to D conversion 16f690 help.... Jul 8, 2012
Programmer's Corner data type conversion problem ? Oct 6, 2011
Programmer's Corner binary to decimal conversion program, having probs Dec 15, 2010

Share This Page