Searching \ for '[PIC] seperate num into tens+units' in subject line. ()
Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/devices.htm?key=pic
Search entire site for: 'seperate num into tens+units'.

Exact match. Not showing close matches.
'[PIC] seperate num into tens+units'
2007\03\06@130148 by

hi, i need a way to seperate a number, say 54. and put 5 in a register called
tens, and 4 in another called units.

is there some binary operation to do this, or will it have to be a custom
subroutine?

i need this kinda fast, can someone help?
--
View this message in context: www.nabble.com/seperate-num-into-tens%2Bunits-tf3356654.html#a9335697
Sent from the PIC - [PIC] mailing list archive at Nabble.com.

See binary to bcd at

Harold

{Quote hidden}

> -
noob,
I think your best bet is to write a loop that subtracts ten and
increments the "tens" register until the Carry flag is set, then
decrement the tens register, add 10 to your number, and move it to the
units register. Basically, you're doing division by hand.
- Marcel

On 3/6/07, picnoob <leeguy92googlemail.com> wrote:
{Quote hidden}

> -

Sir,

I would "AND" the number '54' with 0x0F.  This will give you '4'.  Store
it in it's destination register, whatever tht may be.  Then do a SWPAF
and "AND" it again with 0x0F. This will give you the '5'.  Store it
In it's destination register.  Now you're done.

Regards,

Jim

{Original Message removed}
On Tue, 2007-03-06 at 10:01 -0800, picnoob wrote:
> hi, i need a way to seperate a number, say 54. and put 5 in a register called
> tens, and 4 in another called units.
>
> is there some binary operation to do this, or will it have to be a custom
> subroutine?
>
> i need this kinda fast, can someone help?

Search for "hex to bcd", tons of options out there.

TTYL

I had this issue short time ago, I found that a separate routine to
handle units, tens, etc is more efficient and consumes less code, than
splitting, of course depends on the final application, I used this
routine for a timer

struct number
{
unsigned char u;
unsigned char d;
unsigned char c;
};

// Increase (like ++)
void inc(struct number *value)
{

value->u++;
if (value->u == 10)
{
value->u = 0;
value->d++;
}

if (value->d == 10)
{
value->d = 0;
value->c++;
}

if (value->c == 10)
{
value->c = 0;
}
}

// Decrease (like --)
void decr(struct number *value)
{

value->u--;

if (value->u == 255)
{
value->u = 9;
value->d--;
}

if (value->d == 255)
{
value->d = 9;
value->c--;
}

if (value->c == 255)
{
value->c = 9;
}
}

// Number = 0
void clr(struct number *value)
{
value->u = 0;
value->d = 0;
value->c = 0;
}

// Set value to struct
void set(struct number *value, unsigned char c, unsigned char d,
unsigned char u)
{
value->u = u;
value->d = d;
value->c = c;
}

// Test if zero
unsigned char zero(struct number value)
{
if ((value.u == 0) && (value.d == 0) && (value.c == 0))
return 1;
else
return 0;
}

// Equal two structures
void equal (struct number src, struct number *dst)
{
dst->u = src.u;
dst->d = src.d;
dst->c = src.c;
}

Cristo Alanis
Design Engineer
Tyco Electronics
2500 Courage Blvd St A
Brownsville Tx 78521

> {Original Message removed}
On 3/6/07, picnoob <leeguy92googlemail.com> wrote:
>
>
> hi, i need a way to seperate a number, say 54. and put 5 in a register
> called
> tens, and 4 in another called units.

How is it stored?

Single byte with a value of 54 decimal?
Packed BCD as 0x54?
Two Ascii bytes, 0x35, 0x34?

It makes a difference.
On Tue, 2007-03-06 at 12:18 -0600, PAUL James wrote:
> Sir,
>
> I would "AND" the number '54' with 0x0F.  This will give you '4'.  Store
> it in it's destination register, whatever tht may be.  Then do a SWPAF
> and "AND" it again with 0x0F. This will give you the '5'.  Store it
> In it's destination register.  Now you're done.

That's only if you want hex 0x54 printed as 5 and 4. There's nothing
wrong with that, but in my mind it's likely the op was speaking of
decimal 54, which in hex is 0x36.

TTYL

On Tue, Mar 06, 2007 at 12:18:39PM -0600, PAUL James wrote:
>
> Sir,
>
> I would "AND" the number '54' with 0x0F.  This will give you '4'.  Store
> it in it's destination register, whatever tht may be.

That's only if the number is 54 hex. 54 decimal is 36 hex. So anding with
0x0F would actually give you a 6.

You'd need to convert hex to BCD, then perform the operation in question.

>  Then do a SWPAF
> and "AND" it again with 0x0F. This will give you the '5'.  Store it
> In it's destination register.  Now you're done.

Same problem as before.

For my sunrise/sunset outdoor light controller I wrote a hex to BCD routine.
It's a bit involved. The basic idea was to convert the high nex nybble to
BCD via a table, then add the low BCD digit. For example your 54 decimal
(0x36) would take the 0x30 and convert it to 0x48, which is the BCD equivalent
to 0x30. It then adds the 6 back giving 0x4E. You then decimal adjust by adding
6 more giving 0x54, which is the BCD equivalent to the original 0x36.

Here are my comments from the routine which can be found here:

http://www.finitesite.com/d3jsys/clock.asm

; Add the low nybbles together. Compensate if the sum is greater than 9
; Then add the result to the high nybble of the BCD of the high nybble.
; The low digit add plus the compensation may have pushed the low digit back
; into the hex range. Need to check and recompensate. For example 1F maps to
; (16 + 0F). The low digit sum is 15 hex and with the compensation is bumped
; to 1B. It needs to be compensated again by adding 6 more to get to 21 BCD.
; ...
; This is where recompensate the low digit sum if necessary. Note that
; This one only checks the low digit of the sum since presumably there will
; be some high digit carry when adding 8+9+6 for example.

The simplest way is to do the repeated subtraction as suggested in another
post. My conversion does simplify tracking the high BCD digit, but the low
digit recompensation is a bit of a pain.

BAJ
picnoob wrote:

> hi, i need a way to seperate a number, say 54. and put 5 in a
> register called tens, and 4 in another called units.

Here.  This routine separates the number into three digits; if you
know your original number won't ever be larger than 99 decimal, you
can remove all the lines marked with a "*****" comment and it'll just
separate the number into two digits:

LIST    R=DEC

UNITS    EQU     ....    ;A FILE REGISTER.
TENS     EQU     ....    ;ANOTHER FILE REGISTER.
HUNDREDS EQU     ....    ;ANOTHER FILE REGISTER.  *****

; ENTER WITH ORIGINAL 8-BIT VALUE IN "UNITS".  EXITS WITH ONES'
; DIGIT IN "UNITS", TENS' DIGIT IN "TENS", AND HUNDREDS' DIGIT
; IN "HUNDREDS".

CONVERT CLRF    TENS
CLRF    HUNDREDS    ; *****

DO100S  MOVLW   100         ; *****
SUBWF   UNITS,W     ; *****
BNC     DO10S       ; *****

MOVWF   UNITS       ; *****
INCF    HUNDREDS    ; *****
GOTO    DO100S      ; *****

DO10S   MOVLW   10
SUBWF   UNITS,W

MOVWF   UNITS
INCF    TENS
GOTO    DO10S

DONE

-Andy

=== Andrew Warren - fastfwdix.netcom.com

I just wrote:

>   DO10S   MOVLW   10
>           SUBWF   UNITS,W
>
>           MOVWF   UNITS
>           INCF    TENS
>           GOTO    DO10S
>
>   DONE

I guess I should read this stuff before I hit the send button... "BNC
ADJUST" should be "BNC DONE".

-Andy

=== Andrew Warren - fastfwdix.netcom.com

;number 0-255 to extract is in temp
;result in d100:d010:d011, add 0x30 to each to make ASCII

bin2bcd  clrf    d100
swapf   temp,w
andlw   b'00001111'
skpndc
skpndc
skpdc

btfsc   temp,4
addlw   0x16 - 1 + 0x6
skpdc

btfsc   temp,5

btfsc   temp,6

btfsc   temp,7

rlf     d100,f
btfss   d100,w

movwf   d011
btfsc   temp,7
incf    d100,f

movf    d100,w
movwf   d100

swapf   d011,w       ;separate 10s
andlw   0x0f
movwf   d010

movlw   0x0f         ;separate 1s
andwf   d011,w
movwf   d011

You could also use a lookup table if you have plenty of free space.

John La Rooy
Jinx's post is a completion (separating the 10s from the 1s) of
Dattalo which is probably the fastest single byte binary to decimal
conversion for the PIC. It doesn't appear, at a glance, to be much larger
than the loop methods and it does it in one pass; no loops. BAM! Done!

Anyone who can understand how it works is smarter than I. Scotts notes:

---
James.

> {Original Message removed}
> Jinx's post is a completion (separating the 10s from the 1s) of
> by Scott Dattalo

I should have attributed that

The 16-bit convertor is pretty wizard too

Both the 8-bit and 16-bit are used extensively for LCD, no problems

(note gotos if porting to 18F)

;================================================
;        Convert 16-bit data to ASCII
;================================================

;Input  16-bit number in hi:lo
;Output 5-byte ASCII array

ascii16 nop

radix dec                    ;base 10

movf    fsr,w        ;save fsr
movwf   f_temp
clrf    known_zero
clrf    temp
movlw   dg1
movwf   fsr
goto    \$+2

sub10k   incf    temp
movlw   10000 & 255
subwf   lo

IFNDEF  known_zero

movlw   10000>>8
skpc
movlw   (10000>>8)+1
subwf   hi

ELSE
rlf     known_zero,w
sublw   (10000>>8)+1
subwf   hi

ENDIF
bc      sub10k
call    out_temp
movlw   10
movwf   temp

movlw   1000 & 255

IFNDEF  known_zero
movlw   1000 >> 8
skpnc
movlw   (1000>>8)+1

ELSE
rlf     known_zero,w

ENDIF
call    out_temp
clrf    temp
movlw   100
goto    \$+2

sub100
incf    temp
subwf   lo
skpnc
goto    sub100

decf    hi
btfss   hi,7
goto    sub100

call    out_temp

movlw   10
movwf   temp

call    out_temp     ;convert and store
call    out_lo       ;convert and store
movf    f_temp,w     ;restore fsr
movwf   fsr

return

;convert to ASCII and store

out_temp movf    temp,w
movwf   indf
incf    fsr
return

out_lo   movf    lo,w
movwf   indf
return

On Wed, Mar 07, 2007 at 09:05:25AM +1100, John La Rooy wrote:
> You could also use a lookup table if you have plenty of free space.

It's also real easy with a couple of compressed tables too. A table to
convert the upper hex nybble to its corresponding BCD and a decimal add
adjust table to compensate for hex digits with no corresponding BCD
digit should be enough. No more than 32 bytes.

BAJ
Jinx,

On Wed, 07 Mar 2007 10:07:12 +1300, Jinx wrote:

> ;number 0-255 to extract is in temp
> ;result in d100:d010:d011, add 0x30 to each to make ASCII

Is there a reason why you called the units field "d011" rather than "d001"?

Cheers,

Howard Winter
St.Albans, England

> Is there a reason why you called the units field "d011"
> rather than "d001"?

d100 holds 100s and d011 holds tens and units. m'kay ?

I wrote -

> ADCON1 is in Bank1 (address is between 0x7f and 0x90)

I beg your pardon, between 0x7f and 0x100

(really didn't do that on purpose, but it shows just how easy it is
to make a mistake)

More... (looser matching)
- Last day of these posts
- In 2007 , 2008 only
- Today
- New search...