|
To download this file click here
/********************16 bit Binary to 5 decimal place
conversion in Basic*******************************
** Heavily based on Peter
Hemsley's High Speed Binary to Decimal For PICs article, published in
EPE magazine, September 2004. ** ** The original ASM code and
full explanations for this file can be downloaded from www.epemag.wimbourne.co.uk. ** ** From the download page look in Pic
Tools folder **Some similar ASM only code, and other maths
algorithms are available for viewing at ** http://www.dattalo.com/technical/software/pic
**Assembler
instructions such as rlf have been used
as XCSB optimises the Carry register by automatically
clearing it when code such as temp = temp << 1 or temp =
temp * 2 is used. **
**The code comments assume that you have the original code
and article available. ** ** This code uses 84 asm
instructions (including the ascii conversion) compared to the original
46 asm instructions (no ascii conversion) of the EPE article.
**
**Code space used 108 words **Code size 84 instructions **Ram
space 11 bytes
Compiler XCSB v1.8.1 Pro
This file may be used freely,
however all text in this green colour must
be included in any source code used for professional
purposes
Copyright C D Barnard DATE
9/01/2005 ********************************************************************************************************************/
Variable declarations
int number ubyte splitH ubyte splitL ubyte temp ubyte
tthou ubyte thou ubyte hund ubyte tens ubyte units
ubyte ASCII_flag
proc bin2dec_5(uint number, ubyte flag)
//Break 16 bit number into two byte size
chunks splitH = number >> 8 splitL = number
units = (splitH |
0xF0)
// Or'ing the byte with D'240 is the same as
deducting 16 from the lower nibble
tens = units tens
= tens + tens + tens // hund =
units
asm_start
// It is necessary to use assembler here to prevent
the compiler from clearing the carry
rlf hund,F
asm_end
splitH = splitH
>>4 // Swap the nibble around so as to work on what was the
top nibble splitH = splitH |
0xF0 // Again deduct D'16 from the
nibble hund = hund +
splitH thou = splitH
thou = thou +
splitH units = units +
(splitH + 52)
temp = (splitL
>>4) // In basic we cannot use the W register directly (16F
series) a temporary register has to be used temp = temp |
0xF0 //Now working on the low byte, high nibble and deducting
16 from the contents. tens = tens + temp units =
units + temp
asm_start
//asm has to be used here partly for the reason
stated above for rlf and because it seemed pointless to write the
comf // equivalent in basic. For those who are interested, 'comf'
in basic would be units^0xFF
rlf units,F comf units,F rlf
units,F
asm_end
units = units + (splitL & 0x0F) //mask off
the top nibble
asm_start
rlf Tens,F
asm_end
tthou = 7
asm_start
addlw
3 rlf thou,F
asm_end
/************************************************************************************************************************************** *************************************************************************************************************************************
** There are two choices of using the code
below.
** The assembler version
** Which takes 8 instructions less than the
basic version, can be uncommented if program space and speed is
of
** paramount importance.
** The basic version generates an extra two
"goto's" per test of the STATUS register.
*************************************************************************************************************************************/
//Basic version. This is a sort of do...while or
do.....until loop
while (1) do
asm_start
LSD
//Least Significant Digit
addwf units,F decf tens,F
asm_end
if (STATUS
& (1<<C)) != 0 then //If carry is set (=1) then we're
finished with UNITS and ready for the TENS
asm_start
LMD
addwf tens,F decf
hund,F
asm_end
if (STATUS &(1<<C)) != 0
then //Carry is
set onto the HUNDreds
asm_start
MMD
addwf
hund,F decf
thou,F
asm_end
if (STATUS &
(1<<C)) != 0 then //Done with
the HUNDreds onto the THOUsands
asm_start
NSD
addwf
thou,F decf
tthou,F
asm_end
if
(STATUS & (1<<C)) !=0 then //THOUsands done, TenThousands take care of
themselves, do..while loop finished
break //jump out of the loop to the
done directive
endif
goto
NSD
endif
goto MMD
endif
goto LMD
endif
done
//Assembler version
/* asm_start
LSD //Least Significant Digit
addwf Units,F decf Tens,F btfss
STATUS,C goto LSD
//Least Middle
Digit
LMD
addwf Tens,F decf Hund,F btfss
STATUS,C goto LMD
//Middle Middle Digit
MMD
addwf Hund,F decf Thou,F btfss
STATUS,C goto MMD
//Next Significant Digit
NSD
addwf Thou,F decf Tthou,F btfss
STATUS,C goto NSD
asm_end */
// Convert the hex digit into ASCII
format.
if ASCII_flag !=0 then
tthou = tthou + 0'0' //This is equivalent to tthou |
0x30 thou = thou +
0'0' hund = hund + 0'0'
units = units + 0'0'
endif
//return to calling program
endproc
endproc
|