Searching \ for 'Two ASCII bytes to one Hex byte?' in subject line. ()
Help us get a faster server
FAQ page: techref.massmind.org/techref/index.htm?key=two+ascii+bytes
Search entire site for: 'Two ASCII bytes to one Hex byte?'.

Truncated match.
'Two ASCII bytes to one Hex byte?'
2000\04\01@073238 by

part 0 16 bytes
</x-html>

On Sat, 1 Apr 2000, David Thompson wrote:

> Hi all,
>
> I need something that would take two ASCII bytes and end up with a Hex value.
>
> For example...
>
> 33, 37 would become 25h (decimal 37)
>
> There are plenty of ASCII to Hex examples but they are a bit simplistic for this case. I thought maybe I could convert the first byte to hex (03h) and multiply that by 10 then add it to the second byte (converted to hex - 07h) to have reach the sum of 37, but there might be a more elegant way...
>
> Any ideas?

Why not just convert the two ascii values to bcd and call one of the bcd to hex
routines?

swapf  ascii1,w  ; ascii1 = 33, w=33 (coincidence)
andlw  0xf0      ; w = 30 (low nibble of ascii1)
xorwf  ascii2,f  ; ascii2 = 30^37 = 07
xorwf  ascii2,w  ; w = 30^07 = 37

or just brute force it:

movlw  0x0f
andwf  ascii2,f  ;Clear the upper nibble of the one's digit
rlf    ascii1,w  ;2*tens (note carry will always be cleared here)
andlw  0x1e      ;Clear upper nibble of tens digit
movwf  ascii1    ;W = ascii1 = 2*original ascii1
rlf    ascii1,f
rlf    ascii1,f  ;ascii1 = 8*original ascii1
addwf  ascii1,w  ;W = 2*original ascii1 + 8 *original ascii1
;  = 10*original ascii1

Of course, this snippet assumes that ascii1, and ascii2 are valid numerical
ASCII digits.

Scott

Scott,
Here is my brute force method for converting a two-byte
ascii decimal representation to the actual binary equivalent.
For example, ascii '3', '7' which is hex 0x33, 0x37
will become binary b'00100101' which is hex 0x25

;enter with ascii_msd and ascii_lsd loaded with ascii
;representation of decimal value to be converted to hex.
;Ascii must be in range 0x30 to 0x39. ( "0" to "9" )

;exit with hex byte in ascii_lsd (or w).
;Numerical value will be between 0 and 99 (decimal).

movlw   0x0f        ;set up mask. w has 0x0f
andwf   ascii_lsd,f ;ascii_lsd has hex/dec lsd. w has 0x0f
andwf   ascii_msd,f ;ascii_msd has hex/dec msd. w has 0x0f
bcf     status,c    ;carry=0 (so 0 gets rotated in next step)
rlf     ascii_msd,w ;w has hex/dec msd*2, and ascii_msd has hex/dec msd
movwf   ascii_msd   ;w has hex/dec msd*2, and ascii_msd has hex/dec msd*2
rlf     ascii_msd,f ;w has hex/dec msd*2, and ascii_msd has hex/dec msd*4
rlf     ascii_msd,f ;w has hex/dec msd*2, and ascii_msd has hex/dec msd*8
addwf   ascii_msd,w ;w has hex/dec msd*10, and ascii_msd has hex/dec msd*8
addwf   ascii_lsd,f ;ascii_lsd has msd*10 + lsd.
;ascii_lsd now contains the desired hex byte

; or use addwf  ascii_lsd,w  if you want the hex byte in w.

I have an explicit clearing of the carry flag
prior to the rlf instruction. I notice that your (Scott's)
ascii to hex byte solution does not explicity clear the
carry flag. I don't see how you can be *sure* that the carry
is clear prior to your first rlf instruction. Or am I
missing something here?

Fr. Tom McGahee

{Original Message removed}

On Sat, 1 Apr 2000, Thomas McGahee wrote:

{Quote hidden}

Yes you are (missing something). Immediately following the rlf is an ANDLW
instruction. If the carry is set (before the rlf), then the ANDLW 0x1e will
clear the lsb that got corrupted. At the same time, the RLF clears the carry
because David says the input consist of ASCII encode decimal digits.

;ascii1 and ascii2 are the tens and ones digit of a number we wish
;to convert to binary
;
; In C:
;
;  binary = (ascii1 & 0xf) * 10 + (ascii2 & 0xf);
;
; (I'd be interested to see how a compiler would generate the asm for this.)
;

movlw  0x0f
andwf  ascii2,f  ;Clear the upper nibble of the one's digit

; Multiply the ones digit by 10.
rlf    ascii1,w  ;2*tens
;Note that the carry is also cleared because
;ascii1 is an ASCII number between 0x30-0x39
andlw  0x1e      ;Clear upper nibble of tens digit
;In addition, we clear the shifted in carry
movwf  ascii1    ;W = ascii1 = 2*original ascii1
rlf    ascii1,f  ;ascii1 = 4*original ascii1
rlf    ascii1,f  ;ascii1 = 8*original ascii1
addwf  ascii1,w  ;W = 2*original ascii1 + 8 *original ascii1
;  = 10*original ascii1

Scott

2000\04\04@042214 by

movlw 15                ; de-ASCIIfy the chars
andwf char1,f
andwf char2,f
swapf char1,w           ; w = char1*10

On Sat, 1 Apr 2000, David Thompson wrote:

{Quote hidden}

Rich Leggitt <PICLISTMITVMA.MIT.EDU> wrote:

> > I need something that would take two ASCII bytes and end up with
> > a Hex value.
> >
> > For example...
> >
> > 33, 37 would become 25h (decimal 37)
>
>
>         movlw 15                ; de-ASCIIfy the chars
>         andwf char1,f
>         andwf char2,f
>         swapf char1,w           ; w = char1*10
>         addwf char2,w           ; + char2

Rich:

I assume that the "15" in "movlw 15" is decimal.

Your routine will work for 0-9 [ASCII 30-39], but it fails on A-F
[ASCII 41-46].  Here's a way that works for the whole range:

LIST R = DEC

MOVLW   '0'
BTFSC   CHAR1,6
MOVLW   'A'-10
SUBWF   CHAR1

MOVLW   '0'
BTFSC   CHAR2,6
MOVLW   'A'-10
SUBWF   CHAR2

;The rest of the routine is as you wrote it:

SWAPF   CHAR1,W

-Andy

=== Andrew Warren - fastfwdix.netcom.com
=== Fast Forward Engineering - San Diego, California
=== http://www.geocities.com/SiliconValley/2499

> Here's a way that works for the whole range:
>
>     LIST R = DEC
>
>     MOVLW   '0'
>     BTFSC   CHAR1,6
>     MOVLW   'A'-10
>     SUBWF   CHAR1
>
>     MOVLW   '0'
>     BTFSC   CHAR2,6
>     MOVLW   'A'-10
>     SUBWF   CHAR2

Aggh, hex!! But then what about lower case??

movf char1,w ; '0'-'9'    'A'-'F'/'a'-'f'
andlw 0x1f   ; 0x10-0x19  0x01-0x06
skpc
movwf char1

-- Rich

Andrew,

I don't quite understand this question. ASCII isn't ASCII  a  7bit code? meaning
each character is represented with 7 bits and to convert to hex simply interpret
those 7 bits as interpret them as hex correct? which for 2 ASCII bytes would
require 2 bytes.  How in your example did you say 33 and 37 becomes 25hex.
This is only one byte of hex to represent 2 bytes of ASCII, not possible.

Please Clarify what's you mean, I'm really curious what I'm missing here.

thanks,
-Dave

Andrew Warren <fastfwdIX.NETCOM.COM> on 04/04/2000 11:14:05 AM

Please respond to pic microcontroller discussion list <PICLISTMITVMA.MIT.EDU>

To:   PICLISTMITVMA.MIT.EDU
cc:    (bcc: David E Arnold/SYBASE)
Subject:  Re: Two ASCII bytes to one Hex byte?

Rich Leggitt <PICLISTMITVMA.MIT.EDU> wrote:

{Quote hidden}

Rich:

I assume that the "15" in "movlw 15" is decimal.

Your routine will work for 0-9 [ASCII 30-39], but it fails on A-F
[ASCII 41-46].  Here's a way that works for the whole range:

LIST R = DEC

MOVLW   '0'
BTFSC   CHAR1,6
MOVLW   'A'-10
SUBWF   CHAR1

MOVLW   '0'
BTFSC   CHAR2,6
MOVLW   'A'-10
SUBWF   CHAR2

;The rest of the routine is as you wrote it:

SWAPF   CHAR1,W

-Andy

=== Andrew Warren - fastfwdix.netcom.com
=== Fast Forward Engineering - San Diego, California
=== http://www.geocities.com/SiliconValley/2499

I don't see any reason WHY your PACKED BCD 37 (the 3 from 3"3" and the 7
from 3"7") should not be seem as binary 0011 0111 or hexa 37....  It is
really messy think that the PACKED BCD 37 is in true a decimal
representation and needs to be converted to hexa 25... really confused.

> > > I need something that would take two ASCII bytes and end up with
> > > a Hex value.
> > >
> > > For example...
> > >
> > > 33, 37 would become 25h (decimal 37)

Remember, any binary system is in true NOT DECIMAL, it can be octal,
hexadecimal, whatever you want, but it will be always binary represented
as 2^n.    The only place where you need Decimal representation is when
inputting or outputting numbers from/to human interface, there is no
other place in digital systems for decimal manipulations.

So, for example, if you have the numbers "5" and "7" it is ASCII
(digital, binary) 35h and 37h, or 0011 0101 and 0011 0111, that when
packed they will turn to be 57h (0101 0111). You can say that its
"decimal" representation is 53 and 55, but what for?

Of course if the result of a binary counter is 57h you should NOT send
35h and 37h to your LCD display, except if you want to see it in
hexadecimal format. This is one of the few moments you should convert it
first to decimal, will be 87, so ASCII 38h and 37h will be sent to the
LCD, then you will see decimal "87" at the display.

I am sorry if you already know that, but some other people don't, and it
is a great moment to explain it.

David E Arnold <PICLISTMITVMA.MIT.EDU> wrote:

> isn't ASCII  a  7bit code? meaning each character is represented
> with 7 bits and to convert to hex simply interpret those 7 bits as
> interpret them as hex correct? which for 2 ASCII bytes would
> require 2 bytes.  How in your example did you say 33 and 37 becomes
> 25hex. This is only one byte of hex to represent 2 bytes of ASCII,
> not possible.

Dave:

In the example (convert 33H 37H to 25H), 33 and 37 are the ASCII
codes for the characters "3" and "7".  For clarity, the question
might have been stated "I have a two-digit decimal number (37, for
example) represented as two ASCII characters (33H and 37H).  How can
I convert the number from THAT representation into a single value?"

Does that make more sense?  The way to do the conversion is to first
convert the two characters from ASCII "3" and "7" to the numbers 3
and 7, then multiply the 3 by 10 and add it to the 7.  The result, 37
decimal, is equivalent to hex 25.

And actually... Now that I've re-read te question, I take back what I
wrote in an earlier message.  I misread the question and oroiginally
thought that the pair of ASCII characters represented a HEX number;
now I see that it's a decimal number.  So to Rich Leggitt:  Sorry;

-Andy

=== Andrew Warren - fastfwdix.netcom.com
=== Fast Forward Engineering - San Diego, California
=== http://www.geocities.com/SiliconValley/2499

We say ASCII when we mean that the number is ready to be sent to an ASCII
terminal (window, screen, whatever) and displayed as the digits of the
number. A 33 in ASCII is a '3', 30 is '0' etc.. If you send a 7 to an ASCII
terminal, the bell rings (computer beeps, whatever) an 8 will cause the
terminal to backspace. You wanted to send a 37 or a 38. To send any single
digit from 0...9 you must add 30 to it before sending it to a terminal.

Conversely, when you receive a character from an ASCII terminal, if it is a
digit (in the range 30...39) you need to subtract 30 from it. If you want to
get multiple digits (e.g. allow the user to enter a number between 0...256)
you need to combine the digits into one binary value. So when the user types
234 you actually get 32 33 34 which you convert to 02 03 04 which you then
convert to 02*100 + 03*10 + 04.

Now, all of that was in decimal. PICs compute in binary. 02*100 in binary is
10 * 1100100. It's a bit hard to read so we usually use hexadecimal which is
easier to convert to and from binary since each hex digit is exactly a group
of 4 binary digits. In fact, most displays of the values in PIC registers
are in hexadecimal. When the original poster said he wanted to "end up with
a hex value", he was really saying he needed to convert from decimal to
binary. Our example problem expressed in hex would be 02 * 64h + 03 * 0Ah +
4 which is 0EAh (hex) or 11101010 (binary) or 234 (decimal) or '234' (ASCII
decimal)

Confused? Good, that's why I get paid the big bucks to design and not to
teach. I just wish I could tech. That's why I administrate.

---
James Newton jamesnewtongeocities.com 1-619-652-0593
http://techref.massmind.org NEW! FINALLY A REAL NAME!

{Original Message removed}
David,
the ascii CODE 30H happens to REPRESENT the character "0" which
in turn represents the NUMBER "zero" which in turn has a VALUE
of 00h.

So the ascii codes 33h and 37h represent "3" and "7" which
together makes "37", which has the same numerical value as 25h.

The original poster was asking for a routine that would take
the two ascii codes 33h and 37h and give 25h as the result.
25h means 2*16 + 5 which equals 37 in decimal notation.

When programming any microcontroller it is often necessary
to make these transformations so that you can, for example,
extract the numbers in ascii format that you receive over a serial
link from a PC or other device, and use them to perform
calculations.

We also often have the need to go in the opposite direction
and take a hex byte like 25h and convert it to "37" so we
can display it on an LCD screen. So a lot of us end up
"re-inventing the wheel" and spending inordinate amounts
of time coming up with methods that thousands of people
have already figured out before us.

Some of us enjoy finding different ways to do the same thing.
Make it easier to understand, or faster, or "elegant",
or do it in such a way that no normal person would have
thought of doing it. There is a challenge in trying to
do it in less steps. And sometimes we don't have all that
much extra space in our code, and we want to cram just
one more routine in there, but we need three extra bytes
to cram it in there, so we go through our code looking
for ways to save a byte here and there. It can be

Fr. Tom Mcgahee

{Original Message removed}
On Tue, 4 Apr 2000, Andrew Warren wrote:

> now I see that it's a decimal number.  So to Rich Leggitt:  Sorry;
> your example would've worked fine.

Which example? The first example he posted doesn't work. It computes 18*tens +
ones and not 10*tens + ones. The ones Tom and I posted a few days ago do work.

Scott

Um... dang. What I get for coding at 2AM. But hey, it LOOKED
good...
--Rich

On Tue, 4 Apr 2000, Scott Dattalo wrote:

{Quote hidden}

Hi,

there is another remark may be of interest.

If you inputs a number in character format, do some calculations or so,
then outputs in character format, there is also another way as to convert
it to hex/binary, calculate and re-convert. You can convert it into the
so-called packed decimal format. E. g. the number "47" = 34h 37h will be
47h in packed decimal. It is possible to do some calculations (e. g.
additions) directly with this, and the reverse the procedure. The trick
is very simple:

2. If the sum of the paricular digits is less, than 0Ah, do nothing.
3. If the sum of the digits exceeds 0Ah, add 6 to the result, and
mark the carry.

E. g.

+47h    BCD
+26h    BCD

would result really 73. How?

The result is 6Dh

3. D exceeds A, so add 6 to it. D+6 makes 13h

Write 3 into the result above in place of D and add that 1 of 13h as carry
to the 6. So you get 73. Then, it can be unpacked.

This procedure can be repeated for every digits.

Regards,
Imre

On Tue, 4 Apr 2000, Thomas McGahee wrote:

{Quote hidden}

> {Original Message removed}
Hi there,

You are right, and I'm sorry that you are confused but my application does
require exactly this conversion. If you really want to know, Caller-ID
information contains time and date info in this  "messy" format..

i.e.:
80  Message type
30  Message length
01 Date/Time parameter marker
30 "0"
34 "4"  04 = April
30 "0"
35 "5" 05 = 5th
32 "2"
32 "2" 22 = 10
30 "0"
34 "4" 04 = 04 pm
etc...

See... it may seem silly to you, but this is how Caller-ID was designed... I
have to run through this list and turn the quite definately "ASCII" numbers
into hex representation, in this case you would end up with 04,05,16,04.

Thank you to all those in the PIClist that replied with vastly better
routines than my own. All of your ideas have been carefully read and
evaluated and are much appreciated.

To those few that this problem seems to have confused... hmmm stupid as some
requests like mine may sound, as you can see by this example, there ARE some
stupid things we have to deal with.

Thanks again,

David
{Original Message removed}
Here's another solution that saves a cycle:

rlf   tens,w
andlw 0x1e      ;w=2*tens
movwf temp
rlf   temp,f    ;temp=4*tens
rlf   temp,f    ;temp=8*tens
addlw -'0'      ;convert from ASCII to decimal
;w=tens*2 + ones

Hi Scott.

Destructive way to save one more clock ;-)

movfw   tens    ;*1
rlf     tens,F  ;*4
rlf     tens,W  ;*10

Why so ? tens is '0' + x , ones is '0' + y , where x and y are in range
of 0..9 So finally '0'*(10+1)=48.*11.=528.=0x210 . it is constant so we
can subtract it back from result. Here we gone ;)

WBR Dmitry.

Scott Dattalo wrote:
{Quote hidden}

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