PIC Microcontroller Radix Math Method

Binary to BCD packed and ASCII, 32 bit to 10 digits

from Ron Kreymborg and Mike Keitz

[ed: rough guess is that about 2200 instructions will be executed]

see also:

;******************************************************************
;
; Test program for 32-bit unsigned binary to BCD and BCD to ASCII.
;
;******************************************************************
        title   "32-bit binary to ascii"
        list p=pic16f84,r=dec,n=80,x=off,st=off
        include <p16f84.inc>
        errorlevel -302         ; no bank warnings
	errorlevel -305		; no default dest warnings

#define	number	123456789

loadd	macro
	local	m,n,p
p = number / 16777216
	movlw	p
	movwf	bin
m = (number - p * 16777216) / 65536
	movlw	m
	movwf	bin+1
n = (number - p * 16777216 - m * 65536) / 256
	movlw	n
	movwf	bin+2
	movlw	number - p * 16777216 - m * 65536 - n * 256
	movwf	bin+3
	endm

	CBLOCK	0x0c
	bin:4		; 32-bit binary number (unsigned)
	bcd:10		; 10 BC digits or 10 ascii chars
	pti,pto		; pointers
	ii
	temp
	cnt
	ENDC
	
	loadd			; load test value <number>
	call	b2bcd		; convert to 32-bit binary to 10 bcd
	call	bcd2a		; convert 10 bcd to 10 ascii
	goto	$

;******************************************************************
; Convert the 10 binary coded digits (5 bytes) starting at 
; <bcd> into an ascii string also starting at <bcd>. Original
; bcd digits are lost.

bcd2a	movlw	bcd+9
	movwf	pto		; destination pointer
	movlw	bcd+4
	movwf	pti		; source pointer
	movlw	5		; 5 bytes to process
	movwf	cnt

bcd2a1	movf	pti,w		; get current input pointer
	movwf	fsr
	decf	pti,f		; prepare for next
	movf	indf,w		; get 2 bcds
	movwf	temp		; save for later
	movf	pto,w		; get current output pointer
	movwf	fsr
	decf	pto,f		; prepare for next
	decf	pto,f
	movf	temp,w		; get digits back
	andlw	0x0f		; process lsd
	addlw	"0"
	movwf	indf		; to output
	decf	fsr,f
	swapf	temp,w		; process msd
	andlw	0x0f
	addlw	"0"
	movwf	indf		; to output
	decfsz	cnt		; all digits?
	goto	bcd2a1
	return			; yes


;******************************************************************
; Convert 32-bit binary number at <bin> into a bcd number
; at <bcd>. Uses Mike Keitz's procedure for handling bcd 
; adjust; Modified Microchip AN526 for 32-bits.

b2bcd	movlw	32		; 32-bits
	movwf	ii		; make cycle counter
	clrf	bcd		; clear result area
	clrf	bcd+1
	clrf	bcd+2
	clrf	bcd+3
	clrf	bcd+4
	
b2bcd2	movlw	bcd		; make pointer
	movwf	fsr
	movlw	5
	movwf	cnt

; Mike's routine:

b2bcd3	movlw	0x33		
	addwf	indf,f		; add to both nybbles
	btfsc	indf,3		; test if low result > 7
	andlw	0xf0		; low result >7 so take the 3 out
	btfsc	indf,7		; test if high result > 7
	andlw	0x0f		; high result > 7 so ok
	subwf	indf,f		; any results <= 7, subtract back
	incf	fsr,f		; point to next
	decfsz	cnt
	goto	b2bcd3
	
	rlf	bin+3,f		; get another bit
	rlf	bin+2,f
	rlf	bin+1,f
	rlf	bin+0,f
	rlf	bcd+4,f		; put it into bcd
	rlf	bcd+3,f
	rlf	bcd+2,f
	rlf	bcd+1,f
	rlf	bcd+0,f
	decfsz	ii,f		; all done?
	goto	b2bcd2		; no, loop
	return			; yes

	end
        

Questions: