This program demonstrates the method described by Mike Keitz for converting a multi-byte binary number to binary coded decimal. While his version was 24-bits, I have extended this to 32-bits, a trivial modification. I have also included a subroutine that converts the 10 bcds to 10 ascii characters. While here it shows the ascii characters being written to a memory buffer, they could just as easily be sent off to some peripheral.
The rotate left instructions (rlf) that build the bcd result at the end of the b2bcd subroutine produce the result with the most significant digit at a lower memory address. If required you can reverse this order by reversing how the bits are shifted in, ie,
rlf bin+0 rlf bin+1 rlf bin+2 rlf bin+3 rlf bcd+0 rlf bcd+1 rlf bcd+2 rlf bcd+3 rlf bcd+4
The program is written in Microchip MPASM assembler and can be included in an MPLAB project. Check the special setup required. In its present form it assumes you are running it in the MPLAB debugger, observing results in the Special Function Registers and File Register windows.
| A zipped copy of this file is available: |
BCD2A.ZIP
|
Please refer all queries to Ron Kreymborg

;******************************************************************
;
; 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
load32 macro arg1,arg2
movlw arg1 24
movwf arg2
movlw arg1 16
movwf arg2+1
movlw arg1 8
movwf arg2+2
movlw arg1
movwf arg2+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
load32 123987,bin ; 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 ؕ 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