ON 20050103@4:44:05 PM at page: http://www.piclist.com/techref/microchip/math/radix/b2a-16b4a-ng.htm#38355.0462384259 James Newton[JMN-EFP-786] Published and replied to post 38355.0462384259 by mrken88 |Insert 'If I remember correctly, high() takes the upper 8 bits of the value and low() takes only the lower 8 bits.

Yes, you can safely remove the TenK output.' at: '' mrken88@gmail.com asks:

I am new to PIC, so I apologise in advance for this question.

I am trying to get the ten-bit number from a 16F877a's A/D convertor to a computer using Hyperterminal, so this code converts the binary ADC value into an ASCII decimal, I assume?

I am using MPASM to programme the code, and understand the basics. What I do not understand is the numbers in brackets after movlw. Do I take out the "high"/"low" before it?

Also, since the ADC is only 10-bit, can the first section of the code "Output(temp) ;output temp = TenK" be discarded?

Thank you in advance!
|Delete 'P-' before: '' but after: 'mrken88@gmail.com
Thank you for the reply!

How about the Hi and Lo variables? I thought those two would be high and low bytes of the binary number...
I assembled the unedited code with MPASM and it seemed to have assembled fine.

My second question was not too clear; sorry! I meant whether I can take out the entire code from the beginning up to the TenK output. If I do that, would it affect the last four digits?

Thank you very much!
|Delete 'P-' before: '' but after: 'BIN2DEC clrf DEC0 ; Clear decimal output buffer clrf DEC1 clrf DEC2 clrf DEC3 clrf DEC4 clrf DEC5 clrf DEC6 clrf DEC7 ; NB. BINn and FSR are trashed after this routine movlw 24 ; Initiate bit loop movwf BIT_COUNTER BITLOOP rlf BIN0, F ; Every iteration of this loop will copy the next rlf BIN1, F ; bit of the bin value, starting with the MSB, rlf BIN2, F ; to the carry flag movlw DEC0 movwf FSR ; Initiate DECn pointer and counter movlw 8 movwf DEC_COUNTER ; The following is executed 8 times per bit DECLOOP rlf INDF, F ; Multiply DECn by two with carry, DECn * 2 + C movlw -10 ; See note above - test for DECn > 9 addwf INDF, W ; W = DECn -10, if W = positive or zero, C = 1 btfsc STATUS, C ; DECn has overflowed (>>9) if carry is set movwf INDF ; If carry is set DECn = DECn - 10 incf FSR, F ; Carry is CARRIED over to next multiply decfsz DEC-COUNTER, F goto DECLOOP ; Multiply next DECn decfsz BIT-COUNTER, F goto BITLOOP ; Do next bit retlw 0 ; Could be RETURN on most PICs ;............. ON 20050109@1:30:16 PM at page: http://techref.massmind.org/techref/microchip/math/radix/b2bu-24b9d-xx.htm#38361.5626851852 James Newton[JMN-EFP-786] Says BCD CHALLENGE ACCEPTED (Harry West - Dec '00)

I was very intrigued by the Binary to BCD conversion routine given in Sept '00, as I had always seen this done by some method involving division by ten.

After a lot of thought, I managed to come up with what I think is an improved version. The procedure used to do the conversion is: "Start with a Partial Result (PR) of zero. For each bit in the binary, starting at the left hand end, multiply the PR by two and add the bit."

By doing this arithmetic in decimal, the PR at the end has the converted value which holds the digits as binary coded decimal (BCD) in the lower four bits of each of a succession of bytes, bits 4 to 7 are zeroes (Unpacked BCD). You could also, with a different program, use Packed BCD with two digits in a byte, one in each nibble.

Throughout the process, decimal adjustment (DecAdj) of the PR is necessary to maintain its BCD nature, so that 0 to 9 are unchanged but a result in the range 10 to 15, which is stored as hex 0A to 0F, is converted to 0 to 5 with a 1 carry ready to go in the next BCD, i.e. 0A to 0F become 10 to 15 hex.

The actual process is to add six to the unadjusted result. If this causes a 1 in the fifth bit (bit 4) then the changed pattern is used, otherwise the original unadjusted pattern is retained. For Unpacked BCD the state of bit 4 can be used as the test.

The algorithm in Sept '00 uses "Add 3" before the "times 2" shift. This is best when Packed BCD is converted since for the "top" nibble there is no bit corresponding to bit 4. By "Adding 3" before the shift instead of "Add 6" after, the same effect is obtained using bit 7. However, in this case the carry into the decimal cannot be done until after the shift, hence the two passes through the digits for each bit.

The following is a version using one pass, for Unpacked BCD. I have used the locations BIN0 to BIN2 to hold the three bytes of binary, with the most significant (m.s.) byte in BIN2. The PR goes in the eight bytes DIGIT0 to DIGIT7, with the m.s. digit in DIGIT7. BINCNT and DECCNT hold counts for the two nested loops. ON 20050109@1:30:58 PM at page: http://techref.massmind.org/techref/microchip/math/radix/b2bu-24b9d-xx.htm#38361.5631712963 James Newton[JMN-EFP-786] Code:

BINDEC:
	CALL CLRDIG    ; Clear decimal digits
	MOVLW 24       ; Decimal count
	MOVWF BINCNT

BITLP:
	RLF BIN0,F     ; Shift binary left
	RLF BIN1,F     
	RLF BIN2,F
	MOVLW DIGIT0
	MOVWF FSR
	MOVLW 8        ; Count for the decimal digits
	MOVWF DECCNT
	MOVLW 6        ; The Working Register holds 6 throughout. For each bit the inner loop is repeated 8 times, with shift in of the next bit, "times 2" and DecAdj of each digit

ADJLP:
	RLF INDF,F     ; 2*digit, then shift in "next bit’’ for DIGIT0 or else the carry from the previous digit
	ADDWF INDF,F   ; Add 6, clears Cf and gives 1 in bit 4 if the
	BTFSS INDF,4   ; addition is needed; zero if not, when
	SUBWF INDF,F   ; we subtract it again. Sets Cf
	BSF STATUS,C   ; Cf could be 0 or 1, so make it 1 as default
	BTFSS INDF,4   ; Bit 4 is the carry to the next digit
	BCF STATUS,C   ; Reset Cf to zero if bit 4 is clear
	BCF INDF,4     ; For BCD clear bit 4 in case it’s one
	INCF FSR,F     ; Go to next digit, (Cf not affected)
	DECFSZ DECCNT,F ; End of inner loop. check digit count and
	GOTO ADJLP     ; round again if it’s not zero
	DECFSZ BINCNT,F ; End of outer loop, one pass through digits,
	GOTO BITLP     ; check bit count and repeat if necessary.
	RETURN


;..........
ON 20050109@1:31:33 PM at page: http://techref.massmind.org/techref/microchip/math/radix/b2bu-24b9d-xx.htm#38361.5635648148 James Newton[JMN-EFP-786] Says SHORTER BCD CONVERSION (Michael McLoughlin - April '01)

I have modified Steve Teal’s code, which required 1957 cycles, so that it completes in 1242 cycles!

Steve’s code doubles his Travelling Total (TT), but this only grows slowly and initially only one digit is needed to handle it. Yet the subroutine always doubles the whole of TT, so almost half the RLF multiplications do 2 × 0 + 0 = 0, and are superfluous. By studying the worst case (all 24 bits = 1) it soon appears that we only need to involve a new decimal digit for every three binary digits. The 08 in Steve’s listing could be called cycles, to start at 01 and increment after every three bits. Another counter (octcnt) ensures the repetition of that whole procedure just eight times.

In the following listing the commands to delete are shown "remmed out" with a semicolon, and the new lines are notated as such. ON 20050109@1:31:59 PM at page: http://techref.massmind.org/techref/microchip/math/radix/b2bu-24b9d-xx.htm#38361.5638773148 James Newton[JMN-EFP-786] Code:

bin2dec:
    clrf dec0
    clrf dec1
    cIrf dec2
    cIrf dec3
    cIrf dec4
    cIrf dec5
    cirf dec6
    cIrf dec7
;   movlw 18	 ; deleted
    clrf cycles	 ; new
    movlw 08	 ; new
    movwf octcnt ; new

ctloop:	 	 ; new
    incf cycles  ; new
    movlw 03   	 ; new
    movwf bitcnt

bitloop:
    rlf bin0
    rlf bin1
    rlf bin3
    movlw dec0
    movwf FSR
;   movlw 08	 ; deleted
    movfw cycles ; new
    movwf deccnt

decloop:
    rlf INDF
    movlw 0xF6
    addwf INDF,0
    btfsc STATUS,0
    movwf INDF
    incf FSR
    decfsz deccnt
    goto decloop
    decfsz bitcnt
    goto bitloop
    decfsz octcnt ; new
    goto octloop  ; new
    return

;............

;From Peter Hemsley 15July01

;Binary to decimal
;Convert 24 bit binary (count0,1,2) to decimal digits 1 to 8
;Revised version. My thanks to all who contributed to the bin to dec
;discussion in EPE.

	processor 16f84
	include p16f84.inc
	radix dec

;Ram equates
count0	equ	0x0C		;lsb
count1	equ	0x0D
count2	equ	0x0E		;msb
digit1	equ	0x11		;lsd
digit2	equ	0x12
digit3	equ	0x13
digit4	equ	0x14
digit5	equ	0x15
digit6	equ	0x16
digit7	equ	0x17
digit8	equ	0x18		;msd
bitcnt	equ	0x19
digcnt	equ	0x1A


	org	0		;test code for MPLAB simulator
	movlw	0xFF
	movwf	count2
	movlw	0xFF
	movwf	count1
	movlw	0xFF
	movwf	count0
	call	bin2dec
brk1	return


bin2dec	call	clrdig
	movlw	24		;24 bits to do
	movwf	bitcnt

bitlp	rlf	count0		;Shift msb into carry
	rlf	count1
	rlf	count2

	movlw	digit1
	movwf	fsr		;Pointer to digits
	movlw	8		;8 digits to do
	movwf	digcnt
adjlp	rlf	indf		;Shift digit 1 bit left
	movlw	-10
	addwf	indf,w		;Check and adjust for decimal overflow
	skpnc
	movwf	indf

	incf	fsr		;Next digit
	decfsz	digcnt
	goto	adjlp
	decfsz	bitcnt		;Next bit
	goto	bitlp
	return

clrdig:	clrf	digit1
	clrf	digit2
	clrf	digit3
	clrf	digit4
	clrf	digit5
	clrf	digit6
	clrf	digit7
	clrf	digit8
	return

	end
ON 20050109@1:35:19 PM at page: http://techref.massmind.org/techref/microchip/math/radix/b2bu-24b9d-xx.htm# James Newton[JMN-EFP-786] edited the page. Difference: http://techref.massmind.org/techref/diff.asp?url=H:\techref\microchip\math\radix\b2bu-24b9d-xx.htm&version=9 ON 20050109@1:36:54 PM at page: http://techref.massmind.org/techref/microchip/math/radix/b2bu-24b9d-xx.htm#38361.5672916667 James Newton[JMN-EFP-786] See also: /techref/microchip/math/radix/ftp://ftp.epemag.wimborne.co.uk/pub/PICS/PICtricks/pictricksv2.zip ON 20050109@1:37:13 PM at page: http://techref.massmind.org/techref/microchip/math/radix/b2bu-24b9d-xx.htm# James Newton[JMN-EFP-786] edited the page. Difference: http://techref.massmind.org/techref/diff.asp?url=H:\techref\microchip\math\radix\b2bu-24b9d-xx.htm&version=11 ON 20050109@2:02:01 PM at page: http://techref.massmind.org/techref/microchip/math/radix/index.htm#38361.5847222222 James Newton[JMN-EFP-786] Says in a new file at: http://techref.massmind.org/techref/microchip/math/radix/bu2b-5d16b-ph.htm 5 digit BCD unpacked to 16bit binary in 33 inst, 33 cycles by Peter Hemsley ON 20050109@2:03:07 PM at page: http://techref.massmind.org/techref/microchip/math/radix/bu2b-5d16b-ph.htm# James Newton[JMN-EFP-786] edited the page. Difference: http://techref.massmind.org/techref/diff.asp?url=H:\techref\microchip\math\radix\bu2b-5d16b-ph.htm&version=0 ON 20050109@2:09:01 PM at page: http://techref.massmind.org/techref/microchip/math/radix/bu2b-5d16b-ph.htm#38361.5895949074 James Newton[JMN-EFP-786] Says Published in EPE Dec '03 issue. By PETER HEMSLEY

Speed up your PIC's data conversion and compression.

MATHS is all about playing with numbers, so let's play and create a super-fast decimal to 16-bit binary routine for PIC microcontrollers. It is based on expressing powers of ten in terms of powers of two.

Here are the first five powers of ten:

1     = 1
10    = 8 + 2
100   = 64 + 32 + 4
1000  = 512 + 256 + 128 + 64 + 32 + 8
10000 = 8192 + 1024 + 512 + 256 + 16
If X represents any decimal digit between 0 and 9 then:
X     = (X * 1)
X0    = (X * 8) + (X * 2)
X00   = (X * 64) + (X * 32) + (X * 4)
X000  = (X * 512) + (X * 256) + (X * 128) + (X * 64) + (X * 32) + (X * 8)
X0000 = (X * 8192) + (X * 1024) + (X * 512) + (X * 256) + (X * 16)
These five expressions are the basis on which we can write a routine to convert a string of decimal digits into binary. The routine is to be written in assembler so any expression must be conducive to available processor instructions, namely NIBBLE SWAP, SHIFT LEFT and ADD.

Conducive numbers to work with are:

2   (SHIFT LEFT to multiply by 2)
16  (NIBBLE SWAP to multiply by 16)
256 (The result goes into the high byte of the binary)
If your mind is somewhat blank at this point let's try a simple example to get the grey matter working.

The number 300 can be written as:

(3 * 64) + (3 * 32) + (3 * 4)
Re-writing it in terms of conducive numbers we get:
3 * 16 * 2 * 2 + 3 * 16 * 2 + 3 * 2 * 2
Now reduce and re-arrange the expression to:
((3 * 16 + 3) * 2 + 3 * 16) * 2 = 300
Check it with your calculator.

This expression can be calculated easily using NIBBLE SWAP, SHIFT LEFT and ADD.

Ok that was easy enough, so now for the tricky part.

The 1000's and 10000's expressions contain six and five terms respectively. If we also use SUBTRACT, the number of terms can be reduced to three and four:

X     = (X * 1)
X0    = (X * 8) + (X * 2)
X00   = (X * 64) + (X * 32) + (X * 4)
X000  = (X * 1024) - (X * 32) + (X * 8)
X0000 = (X * 8192) + (X * 2048) - (X * 256) + (X * 16)
These five expressions can now be written in terms of conducive numbers and combined to give:
N = (((D1 + D3 + D4 * 256) * 2 + D2 * 16 + D2 + D3 * 256) * 2 - D3 * 16 +
D2 * 16 + D1 + D4 * 16 * 256) * 2 + D4 * 16 + D0 - D4 * 256
Where D0 = ones, D1 = tens, D2 = hundreds, D3 = thousands, D4 = ten thousands

To save a lot of typing, and you a big headache, the details of how this expression was arrived at have been omitted. It is simple enough though a little lengthy.

There is a problem however, it is the -D4 * 256 at the end of the expression. If the input is greater than 63231 the running total will exceed the allotted 16 bits. So, again, re-arrange the expression.

N = (((D1 + D3 + D4 * 256) * 2 + D2 * 16 + D2 + D3 * 256) * 2 - D3 * 16 +
D2 * 16 + D1) * 2 + D4 * 16 + D0 - D4 * 256 + D4 * 16 * 256 * 2
Now there is an addition of a large number at the end of the expression, therefore overflow will not occur.

The PIC routine in Listing 1 is an almost literal translation of this expression into assembler, with just a few tweaks to make the code more efficient. The variables may be allocated (equated) to any registers of your choice.

Incidentally, the routine will work with numbers up to 99999, the 17th bit (or bit 16) being returned in the carry.

Finally, if your numerical value is expressed in ASCII characters, each character may be converted to a BCD (binary-coded-decimal) format by subtracting 48, which makes it easy to then check if it is a valid decimal digit.

[xh]RESOURCE This software routine is available from the [i]EPE PCB Service[r] on 3.5in disk (Disk 6, [i]PIC Tricks[r] folder), for which a nominal handling charge applies. It is also available for free download from the [i]EPE[r] Downloads page, accessible via the home page at [bo]www.epemag.wimborne.co.uk[r]. It is in the [i]PIC Tricks[r] folder, as file [bo]Dec2Bin16.txt[r].

ON 20050109@2:11:20 PM at page: http://techref.massmind.org/techref/microchip/math/radix/bu2b-5d16b-ph.htm#38361.5912037037 James Newton[JMN-EFP-786] Code:

LISTING 1

; 5 digit decimal to 16 (17) bit binary. By Peter Hemsley, March 2003.
; Input decimal digits in D0 (LSD) to D4 (MSD)
; Output 16 bit binary in NUMHI and NUMLO
; No temporary variables required
; Code size: 33 instructions
; Execution time: 33 cycles (excluding Call and Return)
; Returns carry set if > 65535 (and NUMHI-LO MOD 65536)

dec2bin16
    movf  D1,W        ; (D1 + D3) * 2
    addwf D3,W
    movwf NUMLO
    rlf   NUMLO,F

    swapf D2,W        ; + D2 * 16 + D2
    addwf D2,W
    addwf NUMLO,F

    rlf   D4,W        ; + (D4 * 2 + D3) * 256
    addwf D3,W
    movwf NUMHI

    rlf   NUMLO,F     ; * 2
    rlf   NUMHI,F

    swapf D3,W        ; - D3 * 16
    subwf NUMLO,F
    skpc
    decf  NUMHI,F

    swapf D2,W        ; + D2 * 16 + D1
    addwf D1,W
    addwf NUMLO,F
    skpnc
    incf  NUMHI,F

    swapf D4,W        ; + D4 * 16 + D0
    addwf D0,W

    rlf   NUMLO,F     ; * 2
    rlf   NUMHI,F

    addwf NUMLO,F
    skpnc
    incf  NUMHI,F

    movf  D4,W        ; - D4 * 256
    subwf NUMHI,F

    swapf D4,W        ; + D4 * 16 * 256 * 2
    addwf NUMHI,F
    addwf NUMHI,F

    return            ; Q.E.D.
ON 20050109@2:13:19 PM at page: http://techref.massmind.org/techref/microchip/math/radix/index.htm# James Newton[JMN-EFP-786] edited the page. Difference: http://techref.massmind.org/techref/diff.asp?url=H:\techref\microchip\math\radix\index.htm&version=21 ON 20050109@2:14:13 PM at page: http://techref.massmind.org/techref/microchip/math/radix/index.htm# James Newton[JMN-EFP-786] edited the page. Difference: http://techref.massmind.org/techref/diff.asp?url=H:\techref\microchip\math\radix\index.htm&version=22