Hex to BCD conversion routine

Thread Starter

RG23

Joined Dec 6, 2010
304
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
 

Thread Starter

RG23

Joined Dec 6, 2010
304
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)
 

Thread Starter

RG23

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


Which unpacked bcd routine are you referring to?
 

Markd77

Joined Sep 7, 2009
2,806
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.
 

Thread Starter

RG23

Joined Dec 6, 2010
304
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:

Thread Starter

RG23

Joined Dec 6, 2010
304
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:

Markd77

Joined Sep 7, 2009
2,806
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:

Rich (BB 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
 

Markd77

Joined Sep 7, 2009
2,806
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.
 

Thread Starter

RG23

Joined Dec 6, 2010
304
@mark

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

but the fractional part is still not accurate
 

JDT

Joined Feb 12, 2009
657
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.
 

Attachments

Thread Starter

RG23

Joined Dec 6, 2010
304
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.
 
Top