Sign in

username:

password:



Not a member?

Search hc11



Search tips

Subscribe to hc11



Ads

Discussion Groups

Discussion Groups | M68HC11 | Conversion

Technical discussions about Freescale Microcontrollers: M68HC11. (Freescale Semiconductor is a Subsidiary of Motorola).

Re: Conversion - Tony Papadimitriou - Oct 29 21:07:00 2004

----- Original Message -----
From: "bal_gill21" <>
To: < > Does anyone know how I can convert a hex number coming from the
> analog to digital convertor ($00-$ff) to a ASCII character from 0-100
> that I would like to display on a screen?
> One method i've thought of is generating a conversion table but it
> would have been easier if I only had data coming from $00-$64 as its
> a one to one conversion. Thanks in advance.

To scale to a new range, multiply by the new max and divide by the current
max (if both scales start from the same value).

So, to scale from $00-$FF to 0-100, multiply YOUR_VALUE by the fraction
100/255 (or 20/51 if you simplify things).

For example, $80 (or 128) in the original scale will become (128*100/255=)
50.20 in the new scale.

> Bal






(You need to be a member of hc11 -- send a blank email to hc11-subscribe@yahoogroups.com )


Re: Re: Conversion - Tony Papadimitriou - Oct 29 22:33:00 2004

----- Original Message -----
From: "bal_gill21" <>
To: < > Thanks for that Tony,
> from your example I would be left with 50.2 ($32) in the new scale,
> in my application I would like to display that as 50 Centigrade. In
> ASCII that would be $35 & $30. ie 0-$FF = 0-100 centigrade on the
> display. but I would need the ASCII code conversion. How would this
> be normally achieved.

To get the number in ASCII you just need to add '0' to each digit before you
display it.

So, binary 5 with an added '0' (48) becomes a '5' (53).

> Bal






(You need to be a member of hc11 -- send a blank email to hc11-subscribe@yahoogroups.com )

Re: Re: Conversion - Tony Papadimitriou - Oct 30 5:50:00 2004

----- Original Message -----
From: "bal_gill21" <>
To: < > If you had a binary A with an added '0' (48) it would become a ':'(58)

No such thing as binary A. Binary means 0 and 1. Don't confuse the
representation of numbers in various systems with the actual value.

10 decimal = 1010 binary = A hex = 12 octal

No matter how you write them, the above numbers always have a value of 10
(decimal).

> this would be the case for anything between and including A & F.
> Would something else need to be done here?

It seems I forgot to state the obvious, then.

Once you have scaled your $00..$FF number to 0..100 you'll then have to
convert it to decimal. You need a separate routine that will do that.
Then, to display that decimal in ASCII you need to add '0' to each digit.

So, you need three routines:

1. Scale from $00..$FF to 0..100
2. Convert the number to decimal
3. Print the decimal number as ASCII string.

[2] and [3] should be part of your standard libraries that you use in nearly
any program.

Hope it's clearer now.






(You need to be a member of hc11 -- send a blank email to hc11-subscribe@yahoogroups.com )

Conversion - bal_gill21 - Oct 30 8:12:00 2004


Hi All,
Does anyone know how I can convert a hex number coming from the
analog to digital convertor ($00-$ff) to a ASCII character from 0-100
that I would like to display on a screen?
One method i've thought of is generating a conversion table but it
would have been easier if I only had data coming from $00-$64 as its
a one to one conversion. Thanks in advance.

Bal






(You need to be a member of hc11 -- send a blank email to hc11-subscribe@yahoogroups.com )

Re: Conversion - Author Unknown - Oct 30 9:19:00 2004

To print it out in c is easy....
printf("the value is %d\n",value);

I guess you want assembler...... you need to write a subroutine called
'itoa' (int to ascii)... biggest int is 65536...the algorithm is: 1) subtract
10000 till number is < 10000. That's the 10,000s digit (+$30). 2) subtract 1000
till ans < 1000. That's the 1000s dig. Keep going like this for 100s, 10s, 1s.
[Non-text portions of this message have been removed]





(You need to be a member of hc11 -- send a blank email to hc11-subscribe@yahoogroups.com )

Re: Conversion - bal_gill21 - Oct 30 9:46:00 2004


Thanks for that Tony,
from your example I would be left with 50.2 ($32) in the new scale,
in my application I would like to display that as 50 Centigrade. In
ASCII that would be $35 & $30. ie 0-$FF = 0-100 centigrade on the
display. but I would need the ASCII code conversion. How would this
be normally achieved.

Thanks
Bal > > Does anyone know how I can convert a hex number coming from the
> > analog to digital convertor ($00-$ff) to a ASCII character from 0-
100
> > that I would like to display on a screen?
> > One method i've thought of is generating a conversion table but it
> > would have been easier if I only had data coming from $00-$64 as
its
> > a one to one conversion. Thanks in advance.
>
> To scale to a new range, multiply by the new max and divide by the
current
> max (if both scales start from the same value).
>
> So, to scale from $00-$FF to 0-100, multiply YOUR_VALUE by the
fraction
> 100/255 (or 20/51 if you simplify things).
>
> For example, $80 (or 128) in the original scale will become
(128*100/255=)
> 50.20 in the new scale.
>
> > Bal
>
> tonyp@a...





(You need to be a member of hc11 -- send a blank email to hc11-subscribe@yahoogroups.com )

Re: Conversion - bal_gill21 - Oct 30 13:14:00 2004


If you had a binary A with an added '0' (48) it would become a ':'(58)

this would be the case for anything between and including A & F.
Would something else need to be done here? >
> > Thanks for that Tony,
> > from your example I would be left with 50.2 ($32) in the new
scale,
> > in my application I would like to display that as 50 Centigrade.
In
> > ASCII that would be $35 & $30. ie 0-$FF = 0-100 centigrade on the
> > display. but I would need the ASCII code conversion. How would
this
> > be normally achieved.
>
> To get the number in ASCII you just need to add '0' to each digit
before you
> display it.
>
> So, binary 5 with an added '0' (48) becomes a '5' (53).
>
> > Bal
>
> tonyp@a...





(You need to be a member of hc11 -- send a blank email to hc11-subscribe@yahoogroups.com )

Re: Re: Conversion - Robert Mitchell - Oct 30 18:55:00 2004

As I understand the problem, it is to display temperatures from 0 to 100
with as much precision as is available from an 8 bit analog to digital
conversion.
If I were doing it, I would first scale the analog input so that it
covers the converted range 0 to 250. When this is multiplied by 4 and
divided by 10 you have the range 0 to 100 in steps of 0.4.
A conversion of the range 0 to 1000, produced by the initial
multiplication by 4, to decimal digits can then be carried out by first
dividing by 1000 to get the hundreds digit (rounded down) which can be
converted to ASCII numerals by adding $30 (48 in decimal). The result of
the division can now be multiplied by 1000 and subtracted from the
number to get a remainder which can be treated in the same way to get
the next digit, this time dividing by 100 instead of 1000. This process
is repeated using 10 as the divisor so that there is a remainder less
than 10 which represents the number to be displayed after the decimal
point. It is the placing of the decimal point which carries out the
division by 10.

I hope this helps. On Sat, 2004-10-30 at 20:50, Tony Papadimitriou wrote:
> ----- Original Message -----
> From: "bal_gill21" <>
> To: < > > If you had a binary A with an added '0' (48) it would become a ':'(58)
>
> No such thing as binary A. Binary means 0 and 1. Don't confuse the
> representation of numbers in various systems with the actual value.
>
> 10 decimal = 1010 binary = A hex = 12 octal
>
> No matter how you write them, the above numbers always have a value of 10
> (decimal).
>
> > this would be the case for anything between and including A & F.
> > Would something else need to be done here?
>
> It seems I forgot to state the obvious, then.
>
> Once you have scaled your $00..$FF number to 0..100 you'll then have to
> convert it to decimal. You need a separate routine that will do that.
> Then, to display that decimal in ASCII you need to add '0' to each digit.
>
> So, you need three routines:
>
> 1. Scale from $00..$FF to 0..100
> 2. Convert the number to decimal
> 3. Print the decimal number as ASCII string.
>
> [2] and [3] should be part of your standard libraries that you use in nearly
> any program.
>
> Hope it's clearer now. >
>
> Yahoo! Groups Links >
>
--
Bob Mitchell
PO Box 68 Phone (+61 2) 9449 4736
(21 Hudson Close) Fax (+61 2) 9449 1976
Turramurra, 2074 Mobile 0411554117
NSW, Australia Email




(You need to be a member of hc11 -- send a blank email to hc11-subscribe@yahoogroups.com )

Re: Conversion - Paul B. Webster - Oct 31 2:28:00 2004

On Sun, 2004-10-31 at 00:19, wrote:
> subtract 10000 till number is < 10000.

How about "while number is > 9999, subtract 10000"?

--
Cheers,
Paul B.




(You need to be a member of hc11 -- send a blank email to hc11-subscribe@yahoogroups.com )

Re: Conversion - bal_gill21 - Oct 31 4:55:00 2004


Thanks all, it makes sense now. I hope implementing it makes just as
much sense !

Bal > > If you had a binary A with an added '0' (48) it would become
a ':'(58)
>
> No such thing as binary A. Binary means 0 and 1. Don't confuse the
> representation of numbers in various systems with the actual value.
>
> 10 decimal = 1010 binary = A hex = 12 octal
>
> No matter how you write them, the above numbers always have a value
of 10
> (decimal).
>
> > this would be the case for anything between and including A & F.
> > Would something else need to be done here?
>
> It seems I forgot to state the obvious, then.
>
> Once you have scaled your $00..$FF number to 0..100 you'll then
have to
> convert it to decimal. You need a separate routine that will do
that.
> Then, to display that decimal in ASCII you need to add '0' to each
digit.
>
> So, you need three routines:
>
> 1. Scale from $00..$FF to 0..100
> 2. Convert the number to decimal
> 3. Print the decimal number as ASCII string.
>
> [2] and [3] should be part of your standard libraries that you use
in nearly
> any program.
>
> Hope it's clearer now.
>
> tonyp@a...





(You need to be a member of hc11 -- send a blank email to hc11-subscribe@yahoogroups.com )

Re: Conversion - Mark Schultz - Oct 31 6:28:00 2004


--- In , "bal_gill21" <bal_gill21@y...> wrote:
>
> Does anyone know how I can convert a hex number coming from the
> analog to digital convertor ($00-$ff) to a ASCII character from
> 0-100 that I would like to display on a screen?
> One method i've thought of is generating a conversion table but it
> would have been easier if I only had data coming from $00-$64 as
> its a one to one conversion. Thanks in advance.

Ok, I've read the various messages posted on this topic, and will
attempt to summarize all the info provided to make it easier for
you, along with adding my own suggestions/comments.

First, I recall someone suggesting that you scale your analog signal
such that you would get a reading of 250 decimal ($FA hex) from the
A/D converter (hereinafter abbreviated as 'ADC') when your
temperature reading is 100 C. This is good advice, and you should
consider modifying your hardware as suggested as it would improve
your resolution.

Another thing to consider is reducing your readable temperature
range. Do you really need to read temps up to 100 C ? Would 50 C
be sufficient? If you restrict your range (and increase your amp
gain accordingly) you could increase your resolution. For example,
if you want to measure temps from 0 - 50 C, with 50 C = 250 ($FA) on
the ADC, you would have an effective resolution of 0.2 C per ADC
step.

I am guessing (correct me if I'm wrong) that you are using a
LM35 "Precision Centigrade Temperature Sensor". This sensor, in the
most basic configuration, has an output that is at 0.0V at 0 C, and
increases 10 mV per degree C. Thus, at 50 C, the output would be
500 mV (0.5V). Assuming you are using a 5.0V reference for the ADC
(which is typical for the HC11 and most eval boards based on it),
and you want to achieve a ADC reading of 250 ($FA) at 50 C, then you
need to add an amplifier with a gain of:

Gain = ADC Vref * Max ADC value / 256 / (10 mV (0.01) * Max temp)

Where:

Gain = Amplifier gain
ADC Vref = Voltage applied to HC11 Vrh pin, typically 5.0 V
Max ADC value = Desired ADC count at (Max temp) - e.g. 250
Max temp = Highest temperature you wish to measure - e.g. 50

Plugging in appropriate values for the above, we get:

Gain = 5.0 * 250 / 256 / (0.01 * 50)
= 4.88 / 0.5
= 9.77

If you are using a op-amp in a non-inverting DC gain configuration,
you could get close to this gain by using a 10K resistor to ground
on the inverting input, with a 96K feedback resistor (output to
inverting input) with the temp sensor output connected to the
noninverting input.

For a 0-100 C range, you'd need a (ideal) gain of 4.88, which can be
approximated by using 10K and 47K resistors.

You could make the gain adjustable (for trimming/greater accuracy)
by adding a pot in series with your feedback resistor. There are
also some sofware based 'tricks' I could discuss that would let you
calibrate your measurement without having to resort to adjustment
pots, but the methods I have in mind would require 16-bit integer
math capability that I don't want to go into now.

As for the software techniques you'll need, if you wish to
express/output your temperature value in 'human readable' form (e.g.
ASCII decimal number output via SCI/serial port) then you'll need to
write a integer-to-ASCII decimal routine. You will also want to
take your ADC reading and scale it upward depending on the
resolution of your reading. I will address this last point first.

Let's say that you are interested in reading temps between 0-50 C,
and you have scaled your sensor reading such that you get a ADC
reading of 250 when the temp is at 50 C (as discussed above). Your
effective temperature resolution in this configuration is 0.2 C per
ADC unit. If you want to display your temperature with the maximum
resolution possible, and furthermore, avoid having to deal
with 'floating point' math, the best approach would be to scale the
ADC reading such that the value you would have for display/output is
expressed in 1/10 degree C units - that is, if the temperature were
28.6 C, the value you would get (after scaling) that you would
display would be 286. All you have to do to scale your value
(assuming you are using the configuration I discussed earlier) would
be to take the value from the ADC and multiply it by an appropriate
scaling factor, which is:

Scaling factor = Max temp * 10 / ADC value at max temp
= 50 * 10 / 250
= 2

As long as the scaling factor is a integer, you can perform the
multiplication using the HC11 MUL instruction. Since, in this case,
the scaling factor is a power of 2, you don't even have to use MUL -
you can do it with a shift-left operation. Since the value you will
get may exceed 8 bits (> 255), the shift operation has to be done as
a 16-bit operation, like this:

LDAB ADR1 ;Get value from ADC
CLRA ;Set MSB of result = 0
LSLD ;16-bit shift left (*2)
STD ScaledTemp ;(optional) save for later processing

Note that if you set your sensor gain such that you get a ADC
reading of 250 when the temperature is 100 C, you would need to use
a scaling factor of 4 to get a temperature in 0.1 C units. Since 4
is also a power of 2, all you would need to do is add another 'LSLD'
instruction to the code shown above.

For ADC=250 at 50 C, the value in D will be 500 if the temperature
is 50 C. For ADC=250 at 100 C, the value in D will be 1000 if the
temperature is 100 C.

As I mentioned earlier, you will need to create a integer-to-decimal
ASCII conversion routine if you wish to output/display the temp
reading in human readable form. There are two approaches that can
be used to do this. The first, most compact, approach converts the
number 'backwards' using successive divisions by 10, and works like
this (expressed in C-like pseudocode):

enter this routine with D = value to convert

Y = address of digit buffer
do
D = D / 10
digit = remainder of (D / 10)
digit += '0' (add ASCII '0', $30, to remainder)
*Y = digit (write <digit> to buffer pointed to by Y)
Y++ (increment buffer pointer Y)
until (D == 0)

The above algorithim is nice and relatively compact, but has the
disadvantage of converting the number 'backwards', with the least
significant decimal digit being converted first. Since normal
output order of numbers is most significant digit first, you have to
create a RAM buffer to hold the converted digits until the entire
number is converted, then output the contents of the
buffer 'backward' so the digits are displayed/output in the right
order.

For example, if you were to convert the number 12345 to ASCII
decimal using the above routine, and the address of the digit buffer
is $0080, the contents of your buffer would look like this after the
conversion is finished:

0080 : '5' ($35)
0081 : '4' ($34)
0082 : '3' ($33)
0083 : '2' ($32)
0084 : '1' ($31)

To output the value in this buffer, add this code to the end of the
conversion routine discussed above:

(on entry, Y points to the location following the last digit
converted)

do
Y-- (decrement buffer pointer)
A = *Y (get byte stored in buffer at address Y)
Output value in (A)
while (Y > start of buffer) The second approach to doing integer-to-decimal conversion involves
dividing the integer by powers of 10 to isolate each decimal digit.
It has the advantage of converting the number in most- to least-
significant digit order (thus allowing output directly, without a
buffer) but has the disadvantage of not supressing leading '0's, or
at least requiring extra code and complexity to perform the leading
zero supression. The pseudocode for this approach looks like this:

Power10[] = (10000,1000,100,10,1)
(asm: Power10 DW 10000,1000,100,10,1)

Y = @Power10 (address of Power10 table)
do
digit = D / *Y (divide D by value in Power10 table)
number = remainder (save remainder of division in RAM)
digit += '0' ($30)
Output <digit>
D = number (recover remainder for next iteration)
Y += 2 (increment Power10 table index)
while (Y <= @Power10 + 8) (continue until 1's digit is converted) My personal preference is to use the first method I discussed, even
though it converts the number backwards, because it tends to be
easier to code and is (in my opinion) simply a 'better' and cleaner
way to perform the task.

I have presented the integer-to-ASCII routines in pseudocode rather
than actual assembly code for two reasons: (1) It was easier than
trying to write a assembly code version 'on the fly' as I write
this, and (2) converting the pseudocode I've provided into actual
assembly code is a good excercise for the beginner.

Good luck...

-- Mark




(You need to be a member of hc11 -- send a blank email to hc11-subscribe@yahoogroups.com )