10 bit Binary to BCD Conversion

Posted on the Chat Zone by Ed Grens on September 22, 2004 at 03 08 38 

On 18 September Peter Hemsley posted a 12b binary to BCD conversion subroutine 
in a response to a post by me. His algorithm is excellent for 12b conversion, 
but not efficient for the 10b often encountered with A/D inputs. Over the 10b 
data range, 0x000 to 0x3FF, this routine requires on the average of 131 
processor cycles. Actually this is more than it requires on the average over the 
entire 12b range (118 cycles).

A simple divide by power of ten algorithm, listed below, requires on the average 
88 cycles over the 10b range. This is possible because, for 10b, one can use 
single byte subtractions for divides. At 12b (probably) and certainly at 16b 
this approach cannot compete with the procedure Peter has presented. But, if 10b 
is what you need, it can be advantageous.

Ed 


  ;======= Bin2Dec10G.asm ============= Sep 04 =========
  ;       Test of 10b binary to 4 digit conversion as 
  ;       based on division by powers of 10. 
  ;
  ;       E. A., Grens
  ;
  ;       For most PICs - here for 16F628 with 4 MHz
  ;       internal oscillator.
  ;
  ;       Average processor cycles for execution of
  ;       subroutine over the input range 0x000 to 0x3FF
  ;       is 88.  No variables required except the
  ;       input blh, blo and the out BCD digits.
  ;       Subroutine length 38.
  ;======================================================

        list p=16f628
        radix   dec
        #include 
        __config 0x3D30

  
  ;-------Set Up RAM Variables---------------------------
  blo   equ     0x20            ;lsbyte of 10b binary
  bhi   equ     0x21            ;msb
  d4    equ     0x23            ;msdigit
  d3    equ     0x24
  d2    equ     0x25
  d1    equ     0x26            ;lsd
  ;-------Program Code--------------------------------
                                         
        org     0x00            ;Effective Reset Vector
  ;
        nop
        goto    Start           ;Jump by interrupt
  ;
  Start
        movlw   0x07
        movwf   CMCON           ;Digital I/O
        movlw   0x03            ;Test input
        movwf   bhi
        movlw   0xFF
        movwf   blo
        movlw   0x04
        call    Bin2decg
  Hold
        goto    Hold            ;Finished

  Bin2decg                      ;10b binaey to BCD
        clrf    d1
        clrf    d2
        clrf    d3
        clrf    d4
        clrc
        rrf     bhi,f           ;N = 4*Q + R
        rrf     blo,f           ;blo = Q
        rrf     d1,f            ;d1 = R as temp, R25 
        goto    B2d2            ;repeat
  B2d3
        addwf   blo,f           ;get remainder
                                  ;    after /100, C = 0
        rlf     d1,f            ;*4 and add R back in
        rlf     blo,f
        rlf     d1,f
        rlf     blo,f           ;4*blo + R = N - 
                                  ;    1000*d4 - 100*d3
                movlw   10
  B2d4
        subwf   blo,f           ;blo = N - 1000*d4 -
                                  ;     100*d3 - 10*d2
        skpc
        goto    B2d5            ;blo10
        goto    B2d4
  B2d5
        addwf   blo,f           ;put last 10 back, C=0
        movf    blo,w            
        movwf   d1
        return
   
        end

      
**********************

12-bit code

Posted by Peter Hemsley on September 18, 2004 at 17 40 56 
Message   ; Bonus 12-Bit version

  ; Leaner and Meaner, 36 instructions
  ; Ideal for displaying A/D values
  Bin2DecFast
        movf    NUMHI,w
        iorlw   0xF0            ;w=H2-16
        movwf   D1              ;D1=H2-16
        addwf   D1,f            ;D1=H2*2-32
        addwf   D1,f            ;D1=H2*3-48
        movwf   D2              ;D2=H2-16
        addlw   -D'5'           ;w=H2-21
        addwf   D2,f            ;D2=H2*2-37 Done!
        addlw   D'41'           ;w=H2+20
        movwf   D0              ;D0=H2+20

        swapf   NUMLO,w
        iorlw   0xF0            ;w=H1-16
        addwf   D1,f            ;D1=H2*3+H1-64
        addwf   D0,f            ;D0=H2+H1+4, C=1
        rlf     D0,f            ;D0=(H2+H1)*2+9, C=0
        comf    D0,f            ;D0=-(H2+H1)*2-10
        rlf     D0,f            ;D0=-(H2+H1)*4-20

        movf    NUMLO,w
        andlw   0x0F            ;w=H0
        addwf   D0,f            ;D0=H0-(H2+H1)*4-20 Done!
        rlf     D1,f            ;C=0, D1=H2*6+H1*2-128 Done! 

        movlw   D'5'
        movwf   D3

        movlw   D'10'
  mod0
        addwf   D0,f            ;D(X)=D(X)mod10
        decf    D1,f            ;D(X+1)=D(X+1)+D(X)div10
        skpc
        goto    mod0
  mod1
        addwf   D1,f
        decf    D2,f
        skpc
        goto    mod1
  mod2
        addwf   D2,f
        decf    D3,f
        skpc
        goto    mod2

        return