converting to bcd

Status
Not open for further replies.
hello,
I'm trying to convert an 8-bit number into to bcd, packed or unpacked it doesn't matter how it's done. I'm using this code, but i can't get it to work. Can anyone tell me where i'm going wrong, or direct to me to some code that works.


Code:
MOVLW	B'00000111'
MOVWF	BINARY
CALL 	BIN2BCD  
MOVF	TENS_AND_ONES 
ANDLW 	B'00001111'
CALL	LOOKUP_TABLE 
CALL 	DISPLAY
RRF	TENS_AND_ONES,4
MOVF	TENS_AND_ONES,W 
CALL	LOOKUP_TABLE
CALL 	DISPLAY
GOTO	$

BIN2BCD:  
 CLRF    HUNDREDS
 SWAPF   BINARY,W    ; swap the nibbles
 ADDWF   BINARY, W   ; so we can add the upper to the lower
 ANDLW   B'00001111' ; lose the upper nibble (W is in BCD from now on)
 BTFSC 	 STATUS,DC	 ; if we carried a one (upper + lower > 16)
 ADDLW   0x16        ; add 16 (the place value) (1s + 16 * 10s)
 BTFSC   STATUS,DC   ; did that cause a carry from the 1's place?
 ADDLW   0x06        ; if so, add the missing 6 (carry is only worth 10)
 ADDLW   0x06        ; fix max digit value by adding 6
 BTFSS 	 STATUS, DC  ; if was greater than 9, DC will be set
 ADDLW  -0x06        ; if if it wasn't, get rid of that extra 6
        
 BTFSC   BINARY,4       ; 16's place
 ADDLW   0x16 - 1 + 0x6  ; add 16 - 1 and check for digit carry
 BTFSC   STATUS, DC
 ADDLW  -0x06        ; if nothing carried, get rid of that 6
        
 BTFSC   BINARY, 5      ; 32nd's place
 ADDLW   0x30         ; add 32 - 2
        
 BTFSC   BINARY, 6      ; 64th's place
 ADDLW   0x60        ; add 64 - 4
        
 BTFSC   BINARY, 7  ; 128th's place
 ADDLW   0x20        ; add 128 - 8 % 100
        
 ADDLW   0x60        ; has the 10's place overflowed?
 RLF     HUNDREDS, F ; pop carry in hundreds' LSB
 BTFSS   HUNDREDS, 0 ; if it hasn't
 ADDLW  -0x60       ; get rid of that extra 60
        
 MOVWF   TENS_AND_ONES   ; save result
 
 BTFSC   BINARY,7       ; remeber adding 28 - 8 for 128?
 INCF    HUNDREDS, F ; add the missing 100 if bit 7 is set
        
 RETURN             ; all done!
 
this is super easy in C... but asm shouldnt be that hard... a 8 bit number is 0 to 255 which means it can be from 0 bits to 10 bits output in BCD

255 in BCD is 0x255 aka 0b1001010101

so there are approx 3 nibbles...

2-0010
5-0101
5-0101

Im no asm guru so ill show you in C and maybe it can help...

Hundreds = MyNum / 100;
Tens= (MyNum - Hundreds) / 10;
Ones = (MyNum - Hundreds) - tens;

somthing like that should produce 3 bytes in C with 0x02 , 0x05, 0x05

Now you simply shift them together into 1 int or 2 bytes...
UpperByte = (Hundreds << 4) + Tens;
LowerByte = Ones;

now you have 2 bytes 0x25, 0x5

If your number is from 0 to 99 then you end up with a 1 byte result... if the number is 99

then your upperbyte will be 0x99 and lower will be 0x00
 
This is something I have to do a fair bit. I've done the (as AtomSoft says) easy implementation in C - but I've found that for 16 bit values that takes precious milliseconds.
The code I keep coming back to **broken link removed**. It only uses 7 bytes of RAM, which can be used for other purposes when not needed for bnary - BCD calculations.
 
hi,,, edofbrighton


I have cut down a 16bit to ASCII subr for you, it works ok.
The program can be tested as posted


Code:
;Byte to BCD or ASCII into ascbfr, from Byte in binvall

    list    p=16f876a
    #include <p16f876A.inc>

    errorlevel -302, -207

    __config _CP_OFF & _XT_OSC & _PWRTE_ON  & _WDT_OFF & _LVP_OFF

temp1    equ     0x21
temp2    equ     0x22
binvall equ     0x23
binvalm equ    0x24

 
ascbfr2 equ     0x40
ascbfr1 equ     0x41
ascbfr0 equ     0x42



    org 0x0000
    goto test
    org 0x0004
    retfie
    
test:
    movlw     .123
    movwf    binvall
    call    bin2asc
    
trap:    goto trap

;convert 8 bit bin to 3 asci in ascbfr0
bin2asc:
    clrf    ascbfr2
    clrf      ascbfr1
    clrf    ascbfr0;lsd
          
        movlw   .8 
    movwf   temp1

bitloop:;shift msb into carry
        rlf     binvall,F 
        
        movlw   ascbfr0    ;0=lsd 1st
        movwf   FSR    ;fsr=pointer to digits
        movlw   0X03    ;digits to do
        movwf   temp2
adjloop:
        rlf     INDF,F    ;shift digit 1 bit left
        movlw   0X0A
        subwf   INDF,W    ;check and adjust for decimal overflow
        btfsc   STATUS,C
        movwf   INDF

        decf    FSR,F;incf=msd 1st next digit
        decfsz  temp2,F
        goto    adjloop
        decfsz  temp1,F;next bit
        goto    bitloop

    ;return from here if BCD only
    
        movlw    0X30;make asci
    iorwf   ascbfr2,F
    iorwf   ascbfr1,F
    iorwf   ascbfr0,F
    return 

    end
 
edofbrighton,

If it will help, here's a nice fast isochronous routine;

Regards, Mike

Code:
;******************************************************************
;
;  8-bit to 3 digit half-packed BCD (isochronous)
;
;   input: WREG, 0x00..0xFF, 0..255
;  output: tens, 0x00..0x25, packed bcd hundreds and tens
;          ones, 0x00..0x09
;
;  26 words/cycles (isochronous), not including call and return
;
    radix    dec

        clrf    tens            ;
        addlw   -200            ; W = W - 200
        rlf     tens,F          ; pick up Carry result
        btfss   tens,0          ; borrow? no, skip, else
        addlw   200             ; add 200 back
        addlw   -100            ; subtract 100
        rlf     tens,F          ; pick up Carry result
        btfss   tens,0          ; borrow? no, skip, else
        addlw   100             ; add 100 back
        addlw   -80             ;
        rlf     tens,F          ;
        btfss   tens,0          ;
        addlw   80              ;
        addlw   -40             ;
        rlf     tens,F          ;
        btfss   tens,0          ;
        addlw   40              ;
        addlw   -20             ;
        rlf     tens,F          ;
        btfss   tens,0          ;
        addlw   20              ;
        addlw   -10             ;
        rlf     tens,F          ;
        btfss   tens,0          ;
        addlw   10              ;
        movwf   ones            ;
        return                  ;
 
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…