Assembly Language Routines

Hi!

I am looking for PIC asm routines for

Conversions

Long Integer to String (Long Integer - 4bytes)

Double to String (Double - 4bytes)

Floating Point Math

ADD

SUB

MUL

DIV

Square

Square root

power

I want to calculate numbers like 24.2874353903764903627393 * 5.527932455274853690390.

display

output string to lcd.

Re: Assembly Language Routines

Re: Assembly Language Routines

Can I use this for getting 4 byte variable routines?

http://avtanski.net/projects/math/

Re: Assembly Language Routines

You have to try to see the results.

Re: Assembly Language Routines

In assembly, there is no concept of conversions between Strings, integer, Long, short. In high level languages that concepts is there by restricting mathematical manipulating of variables.

In assembly it's only memory register that you store data and you are free to manipulate them as you wish (using assembly instructions). You may store 0x48, 0x45, 0x4c, 0x4c, 0x4f in 5 registers and you can add them together or consider them as ASCII values and get the word "HELLO" on a LCD.

However you may write functions in assembly for data manipulations (eg. convert ASCII values of small-letters to uppercase, add multi-register values, get decimal representation of a register value...) but conversion between variable types is not there.

Use a good book on assembly;I hope you can get the idea.

Re: Assembly Language Routines

The problem is, I am readind through adc. The byte value I get in ADRESH and ADRESL (12-bit) have to be converted to Decimal value and then converted to ascii for displaying in lcd. Give some names of assembly books.

Re: Assembly Language Routines

On the Piclist site referenced above, there is a whole section on radix conversion: http://www.piclist.com/techref/micro...adix/index.htm

There are routines to go from binary 12 or 16 bit to BCD as well as from binary directly to ASCII decimal.

John

Re: Assembly Language Routines

I need to do floating point multiplication and division on adc value. The resulting floating point value has to be converted to ascii for lcd display.

Re: Assembly Language Routines

That is not quite what you described needing in post#6.

It appears now that you want to do math and multiply a 24-digit decimal by 22-digit decimal in floating point based somehow on results from 12-bit ADC. The max resolution that can produce is 1 part in 4096. The rest of the digits in your 24-digit number are meaningless.

At this point, I think the best way for you to get meaningful help is to describe what it is you are trying to do in more detail. Are you sure you need floating point? Why? For example, if you need the remainder from a division, say to 4 decimal precision, you may be able to avoid floating point by simply left shifting the dividend to the left by two or more bytes. Then strip (concatenate) the insignificant bits from the result later on.

John

Re: Assembly Language Routines

12-bit gives 4095 digital count. I've to multiply 4095 by some no. like 0.5346. Then I get some result. Then there are some similar divisions and multiplications. The final result will be some hex value in the register. I need to convert that into decimal and display it on lcd.

Re: Assembly Language Routines

The precision of your result is still limited by the precision of your ADC. Try to visualize your result, if the ADC only gave 1-bit precision (i.e., 0 or 1), or to avoid zero, try 2-bit precision.

It is still not clear why you need floating point, as it appears the manipulations are known beforehand and the only data entry is the ADC value. Have you considered using tables? If you are certain you need floating point point, have you seen this?

http://www.codeproject.com/Articles/...ing-Point-Type

John

Re: Assembly Language Routines

There is a reason most people use C instead of assembler. Imagine having to write a whole load of floating point functions, and then someone changes

their mind, and wants to use AVR instead of PIC. And then changes mind again to ARM.

Better to use C if you want to do a lot of floating point, unless you can use lookup tables or scale up and do non-floating point as mentioned above.

Re: Assembly Language Routines

OK. Tell me how to do 32h * 5h / FFFh?

Re: Assembly Language Routines

You do know that equals zero, right? or 0.xxx... if you're not constrained to integers.

If that's a calculation you need to do often, then you can pre-calculate and store in a look-up table

to whatever accuracy you desire.

For example, if you need to multiply numbers in the range of 0 to 100 by 5 and then divide by FFF,

then do that for all 100 numbers, and store the results. Then you look them up.

If you don't have space for a look-up table for all your calculations, then you could use external

flash, you can get it in small packages with SPI interface for example.

Or, use C and use a math library.

Re: Assembly Language Routines

I get my adc values from 0000h to 0FFFh. I have to multiply it by 0005h and divide by 4095h. I get some value, which is the resistance of a device. Depending upon the resistance, I've to calculate its temperature using 2 polynomial equations. I've done that in mikroC, but I am implementing it in pic asm.

http://www.edaboard.com/thread252959.html

Re: Assembly Language Routines

Right.. you're just scaling by a factor (i.e. 5/FFFh), nothing non-linear, so this is easier.

Technically you don't even need a lookup table. But here's the concept if you used one.

Perform the calculation for values from 0 to FFF, and store them (i.e. 0.0012, 0.0024, etc)

but scaled up, e.g. 1, 2 if you want it to 3 decimal places, i.e. I've multiplied by 1000.

Make sure the table results are scaled up so that you're not dealing with decimal points.

If you want to continue doing further calculations, then you can use the scaled values.

If you want to display the results, then you know to scale back down by moving the decimal point.

The benefit of a look-up table is that it will save you compute time if you've got nonlinear

values. For the linear case, note that you could just multiply the single scaled value.

And a multiply is just 'add' instructions in a loop, if you're using an assembler.

Re: Assembly Language Routines

But when I use the polynomial with the resistance, I will be taking squares and square roots of some constant coefficients.

Re: Assembly Language Routines

So when you're using square roots, then this is absolutely a good use-case for a look-up table. Squares can be composed of multiple additions,

so you could use a loop and 'ADD' instruction in assembler. It will perform the square. Or to save time, use a look-up table for that too.

If you don't want to use a look-up table for square roots, then you need to find an algorithm (math book) and implement in assembler.

At some stage, you'll possibly decide that a math library is easier, and just move to C, or you'll dedicate memory for a lookup table.

Since your original problem is to use a temp probe and convert the value to a temperature, you'd save an awful lot of time just getting the

table of resistance values from the probe vendor and sticking it (or a conversion) in a lookup table. But it's your choice.

This thread is much like your other thread on this probe issue.

Re: Assembly Language Routines

My equation is (-a + (sqrt(a^2 - 4b(1-x/xo)))/2b and const1 * x + const2 * x^2 -const3 * x^3 - const4 * x^4 + const5 * x^5. I've to implement it in asm. In mikroC double data type is 4 bytes, but I don't know how to perform math operations in asm. Should I use variables of 4 bytes in mpasm and perform the math operations. I know that operations will be performed in hex. I have to convert the resulting hex value to decimal. But how do I get values like 8.4168. How to get the decimal part from the hex value. I'm using pic18. the registers are 1 byte. If I have 3 operands of 4 bytes size, how to move the value of 4 byte to i byte w reg for performing operations?

Re: Assembly Language Routines

Honestly, I think it won't be possible, unless you can find by luck some floating point math libraries for your device.

It is a lot of work to implement it from scratch, especially if you're not familiar with this.

I say give up, and store a lookup table of the ADC value and the corresponding temperature.

If you can't do that due to lack of space, then change to a different PIC with more space, or external memory, or

switch to C and use a math library. Simple!