Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

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.

Latest threads

Back
Top