Home     Contact     Projects     Experiments     Circuits     Theory     BLOG     PIC Tutorials     Time for Science     RSS     Terms of services     Privacy policy  
   
 Home      Projects     Experiments     Circuits     Theory     BLOG     PIC Tutorials     Time for Science   



All about PIC microcontrollers

Within these pages, you can find many useful pieces of code mostly in assembly for the Microchip PIC micro controller family. A lot of people have spend many hours trying to put the bits and bytes together. If the code is NOT written by a member of the PCB Heaven community, then a link will be added above the code with the original website that this code was found.
Because the code is copied to our servers, you should know that:

  • The responsible web master of the website that the code is taken, has been informed and he has agreed to copy the code
  • All emails from the above contact have been kept as records but due to personal privacy cannot be shown in public.
  • The author of the code is always clearly indicated above the code. In some cases the author is unknown. If you happen to be the author of the code or you know the person who wrote it, please inform us by email and it will be added ASAP.

We would personally like to send the credits to all the people that managed to write some very interesting code and publish it, and special thanx to the people that originally hosted those code snippets and gave us the permission to copy them.


View code
Binary to ASCII, 16 bit to 3digits (0..999) FAST
Author: Nikolai Golovchenko
This code was originally located @ http://www.piclist.com


Follow this link to go back

;-------------------------------------------
;Fast binary to decimal conversion (0..999)
;
;Input: NumH:NumL
;Output Hund:Tens_Ones (packed BCD)
;
;
;
;Size: 56 instructions
;Execution time (with return): 57
;
;8-July-2000 by Nikolai Golovchenko
;23-Aug-2001
;Based on 8bit BIN2BCD of Scott Dattalo
;-------------------------------------------
bin2dec999fast
swapf NumL, w ;Add the upper and lower nibbles
addwf NumL, w ;to get the one's digit
andlw 0x0F
skpndc ;Go through a binary to bcd
addlw 0x16 ;conversion for just the one's
skpndc ;digit
addlw 0x06
addlw 0x06
skpdc
addlw -0x06

btfsc NumL, 4 ;bit 4 is a special case
addlw 0x16 - 1 + 0x6
skpdc
addlw -0x06

;now adjust the ten's digit
btfsc NumL, 5 ;2^5 = 32, so add 3 to the ten's
addlw 0x30 ;digit if bit 5 is set

btfsc NumL, 6 ;2^6 = 64, so add 6
addlw 0x60 ;if bit 6 is set

btfsc NumL, 7 ;2^7 = 128, so add 2 (the ten's
addlw 0x20 ;digit) if bit 7 is set


addlw 0x60 ;convert the ten's digit to bcd
clrf Hund
rlf Hund, f ;if there's a carry, then the input
btfss Hund, 0 ;was greater than 99.
addlw -0x60
movwf Tens_Ones

movlw 0x66 ;2^8 = 256, so add 0x56 to Tens_Ones
btfsc NumH, 0
movlw 0x56 + 0x66 ;add 0x66 for decimal adjust
addwf Tens_Ones, f
skpnc
incf Hund, f
clrw
skpc
iorlw 0x60
skpdc
iorlw 0x06
subwf Tens_Ones, f

movlw 0x66 ;2^9 = 512, so add 0x12 to Tens_Ones
btfsc NumH, 1
movlw 0x12 + 0x66
addwf Tens_Ones, f
skpnc
incf Hund, f
clrw
skpc
iorlw 0x60
skpdc
iorlw 0x06
subwf Tens_Ones, f

; btfsc NumL, 7 ;finish with hundreds
; incf Hund, f
; movlw 2
; btfsc NumH, 0
; addwf Hund, f
; movlw 5
; btfsc NumH, 1
; addwf Hund, f

; Aug 23, 2001 optimization:

rlf NumL, w ; copy bit 7 to carry
rlf NumH, w ; load w with bits 9 to 7
btfsc NumH, 1 ; add b[9]
addlw 1 ;
addwf Hund, f ; add it to hundreds


return

---------------------------------------------------------------------

The algorithm is based on the idea of adding up decimal weights of each
bit. Each bit has a weight (equal to 2^b, b - bit number, 0 to 15), which can
be represented and added in decimal:

bit weight hundreds tens ones
------- ------- ------- ------ -------
0 1 0 0 1
1 2 0 0 2
2 4 0 0 4
3 8 0 0 8
4 16 0 1 6
5 32 0 3 2
6 64 0 6 4
7 128 1 2 8
8 256 2 5 6
9 512 5 1 2

So, if a bit is set, we add the appropriate decimal digits to our
result. But testing each bit would be very inefficient. There are
however ways to optimize this. You can notice a regularity, for
example, in the ones column. Values almost repeat the binary weights
(1,2,4,8,6,2,4,8,6,2). That means that we can separate the binary word
in repeatable strings and add these strings together, which would be
the same if we tested each bit.

First, we need to modify the table to see how to separate the bits in
strings:

bit weight hundreds tens ones
------- ------- ------- ------ -------
0 1 0 0 1
1 2 0 0 2
2 4 0 0 4
3 8 0 0 8
4 16 0 1 1+5
5 32 0 2+1 2
6 64 0 4+2 4
7 128 1 2 8
8 256 2 5 1+5
9 512 4+1 1 2


So, the calculations would be:

ones = b[3:0] + b[7:4] + b[9:8] + 5*(b[4] + b[8])
tens = b[6:4] + b[6:5] + 2*b[7] + 5*b[8] + b[9]
hund = b[9:7] + b[9]

However, first two sums may exceed the 0 to 9 range, so we would have
to check for that and propagate the overflow to tens and hundreds.

Let's see what the code does...


; add b[3:0] + b[7:4] for ones
swapf NumL, w ;Add the upper and lower nibbles
addwf NumL, w ;to get the one's digit
andlw 0x0F
; if sum is bigger than 15 (DC is set), add 16 to BCD result
skpndc ;Go through a binary to bcd
addlw 0x16 ;conversion for just the one's
; if lower digit overflowed again, add 16 again
skpndc ;digit
addlw 0x06
; make sure the lower digit is in 0..9 range. If not, do BCD
; correction (add 6)
addlw 0x06
skpdc
addlw -0x06


; add now 5*b[4] to ones accumulator and b[4] to tens, doing the
; BCD correction at the same time
btfsc NumL, 4 ;bit 4 is a special case
addlw 0x16 - 1 + 0x6
skpdc
addlw -0x06

; here we have converted already bits 0 to 4:
; ones = b[3:0] + b[7:4] + b[9:8] + 5*b[4] + 5*b[8]
; --------------- -------
; tens = 2*b[6:5] + b[4] + b[6:5] + 2*b[7] + 5*b[8] + b[9]
; ----
; hund = b[9:7] + b[9]


; now just test bits 5 to 7 and add their decimal weights to
; tens only (bit 7 also affects hundreds). We can add maximum
; 11 to tens digit here, so it will be less than 16 and not overflow.
;now adjust the ten's digit
btfsc NumL, 5 ;2^5 = 32, so add 3 to the ten's
addlw 0x30 ;digit if bit 5 is set

btfsc NumL, 6 ;2^6 = 64, so add 6
addlw 0x60 ;if bit 6 is set

btfsc NumL, 7 ;2^7 = 128, so add 2 (the ten's
addlw 0x20 ;digit) if bit 7 is set

; do decimal correction for tens and propagate carry to hundreds
addlw 0x60 ;convert the ten's digit to bcd
clrf Hund
rlf Hund, f ;if there's a carry, then the input
btfss Hund, 0 ;was greater than 99.
addlw -0x60
movwf Tens_Ones

; Here we are done with bits 5 to 7 (except bit 7 for hundreds):
; ones = b[3:0] + b[7:4] + b[9:8] + 5*b[4] + 5*b[8]
; --------------- -------
; tens = 2*b[6:5] + b[4] + b[6:5] + 2*b[7] + 5*b[8] + b[9]
; -------- ---- ------ ------
; hund = b[9:7] + b[9]


; test bit 8, and add what it contributes to ones and tens
movlw 0x66 ;2^8 = 256, so add 0x56 to Tens_Ones
btfsc NumH, 0
movlw 0x56 + 0x66 ;add 0x66 for decimal adjust
addwf Tens_Ones, f
; do decimal correction
skpnc
incf Hund, f
clrw
skpc
iorlw 0x60
skpdc
iorlw 0x06
subwf Tens_Ones, f

; Here we are done with bit 8:
; ones = b[3:0] + b[7:4] + 2*b[9] + b[8] + 5*b[4] + 5*b[8]
; --------------- ----- ------- ------
; tens = 2*b[6:5] + b[4] + b[6:5] + 2*b[7] + 5*b[8] + b[9]
; -------- ---- ------ ------ ------
; hund = b[9:7] + b[9]


; test bit 9 (it adds 2 to ones, 1 to tens, and 5 to hundreds),
; but ignore hundreds yet
movlw 0x66 ;2^9 = 512, so add 0x12 to Tens_Ones
btfsc NumH, 1
movlw 0x12 + 0x66
addwf Tens_Ones, f
skpnc
incf Hund, f
clrw
skpc
iorlw 0x60
skpdc
iorlw 0x06
subwf Tens_Ones, f

; Now we have a ready result for ones and tens:
; ones = b[3:0] + b[7:4] + 2*b[9] + b[8] + 5*b[4] + 5*b[8]
; --------------- ------ ----- ------- ------
; tens = 2*b[6:5] + b[4] + b[6:5] + 2*b[7] + 5*b[8] + b[9]
; -------- ---- ------ ------ ------ -----
; hund = b[9:7] + b[9]

; now just test bits 7, 8, and 9 and add their share to hundreds
; (without any BCD correction, because we assume input value is
; between 0 and 999, so hundreds can't be more than 9)

btfsc NumL, 7 ;finish with hundreds
incf Hund, f
movlw 2
btfsc NumH, 0
addwf Hund, f
movlw 5
btfsc NumH, 1
addwf Hund, f

That's it!

Wait, let's optimize the last few lines...

; hund = b[9:7] + b[9]

rlf NumL, w ; copy bit 7 to carry
rlf NumH, w ; load w with bits 9 to 7
btfsc NumH, 1 ; add b[9]
addlw 1 ;
addwf Hund, f ; add it to hundreds

Follow this link to go back






delicious
digg
reddit this Reddit this
Faves



 HOT in heaven!