PIC Microcontoller Radix Math Method

Binary to BCD half-packed 8 bit to 3 digit

From: Scott Dattalo, notes

Comments added by Alex Forencich


;******************************** 
;binary_to_bcd - 8-bits
;
;Input
;  bin  - 8-bit binary number
;   A1*16+A0
;Outputs
; hundreds - the hundreds digit of the BCD conversion
; tens_and_ones - the tens and ones digits of the BCD conversion
binary_to_bcd:

        CLRF    hundreds
        SWAPF   bin, W      ; swap the nibbles
        ADDWF   bin, W      ; so we can add the upper to the lower
        ANDLW   B'00001111' ; lose the upper nibble (W is in BCD from now on)
        SKPNDC              ; if we carried a one (upper + lower > 16)
         ADDLW  0x16        ; add 16 (the place value) (1s + 16 * 10s)
        SKPNDC              ; 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
        SKPDC               ; if was greater than 9, DC will be set
         ADDLW  -0x06       ; if if it wasn't, get rid of that extra 6
        
        BTFSC   bin,4       ; 16's place
         ADDLW  0x16 - 1 + 0x6  ; add 16 - 1 and check for digit carry
        SKPDC
         ADDLW  -0x06       ; if nothing carried, get rid of that 6
        
        BTFSC   bin, 5      ; 32nd's place
         ADDLW  0x30        ; add 32 - 2
        
        BTFSC   bin, 6      ; 64th's place
         ADDLW  0x60        ; add 64 - 4
        
        BTFSC   bin, 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   bin,7       ; remeber adding 28 - 8 for 128?
         INCF   hundreds, F ; add the missing 100 if bit 7 is set
        
        RETURN              ; all done!

Note: SKPDC is equivalent to BTFSS STATUS, DC and SKPNDC is equivalent to BTFSC STATUS, DC

Same code optimized for the PIC18F instruction set:


binary_to_bcd:
        clrf    hundreds
        swapf   bin, W, A   ; swap the nibbles
        addwf   bin, W, A   ; so we can add the upper to the lower
        andlw   B'00001111' ; and lose the upper nibble (W is in BCD from now on)
        btfsc   STATUS, DC, A   ; if we carried a one (upper + lower > 16)
         addlw  0x16        ; add 16 (the place value) (1s + 16 * 10s)
        daw                 ; check for digit overflows
        
        btfsc   bin, 4, A   ; 16's place
         addlw  0x16 - 1    ; add 16 - 1
        
        btfsc   bin, 5, A   ; 32nd's place
         addlw  0x30        ; add 32 - 2
        
        btfsc   bin, 6, A     ; 64th's place
         addlw  0x60        ; add 64 - 4
        
        btfsc   bin, 7, A   ; 128th's place
         addlw  0x20        ; add 128 - 8 % 100
        
        daw                 ; check for digit overflows
        rlcf    hundreds, F ; pop carry in hundreds' LSB
        
        movwf   tens_and_ones
        btfsc   bin,7, A    ; remember adding 28 - 8 for 128?
         incf   hundreds, F ; add the missing 100 if bit 7 is set
        
        return

Don't need the hundreds? Get rid of everything after the second daw up to the return. The result will end up in W in that case, just add a movwf if the result is needed elsewhere. Want to pass in the byte in W? Just add a movwf bin at the beginning.

Comments:

Says:

I am a Newbie and this is the exact information i was looking for, it works great. The only thing is i don't know how this code actually works, maybe i try to figure it out when i learn more about asm.

Questions:

Archive: