PDA

View Full Version : '*/' operator



jblackann
- 17th January 2007, 20:57
Hello I was wondering if someone can better explain what is happening when using the '*/' command. I had posted some months ago asking for help in converting a 10 bit analog to digital number into a value of 0 to 5 to display it on an LCD. Here is the code that someone posted and it works perfectly fine.
I am performing A to D on analog channel 11 on a PIC16F690

READ_A_D_AN11: 'used for adjusting set pts
ADCON0 = %11101101 'right justified, using Vref, AD on Channel 11
PAUSEUS 50 ' wait 50 microsec
ADCIN 11, AD_AN11_VALUE ' read channel 11 to AD_AN11_VALUE
AD_AN11_VOLT = (AD_AN11_VALUE */ 5000) >> 2
RETURN

Code for displaying it on an LCD.

DISPLAY_SENSOR_VALUE:
GOSUB CLEAR_LCD
GOSUB READ_A_D_AN11
LCDOUT "Rotary Voltage"
LCDOUT $FE, $C0, "Sensor ", DEC (AD_AN11_volt/1000) ,".", DEC3 AD_AN11_VOLT ," VDC"
This works perfectly fine and displays a value of with 3 decimal places.

What I am attempting to do is use a potentiometer to act as a trigger for another part of a circuit. I can set the voltage points in software to act as trip points. What I would like to do is create a window in which the trigger will occur. I was simply going to have another routine that would be adjustable from 10 to 250, which I would like to represent 0.010V t0 0.250V. The problem is that I was going to just take the number 10 to 250 and subract that from my A to D conversion value but that does not give me the true representation of what I need to adjust my window by.

I would like to some how convert backwards from what I did to get my range from 0 to 5 V from the A to D value of 0 to 1023. I would like to take 0.01 to 0.250V and convert this to a proportional value to subtract from my A to D value.

If I have not confused everyone and someone has any ideas I would love to hear them. Thanks for your help.

Darrel Taylor
- 17th January 2007, 21:49
*/ is the MidWord multiplier.

When you multiply 2 16-bit values together, you'll get up to a 32-bit result (4 bytes). The Midword, is the 2 bytes in the middle.

For instance, let's say you have an A/D value of 600, and you multiply it times 5000, that gives you 3,000,000. And if you express that in Hexadecimal, it looks like ...
002D:C6C0

The MidWord is 2DC6, or 11,718.

That's the same as (600 * 5000) / 256. The /256 is implied, and happens without the extra time required to do a division. So, it can be allot faster than using DIV32.

The rest of the formula is, >> 2, or shiftright 2 places. Which is the same as /4. Since the result has already been divided by 256, /4 makes the total divisor equal to 1024 (256*4). And, the result will be 2,929, which represents 2.929 Volts input to the ADC.

So, the whole formula is really just (600 * 5000) / 1024. But in a way that PBP can handle it with 16-bit numbers.<hr>
OK, so how to go the other direction...

I would like to take 0.01 to 0.250V

You'll need the integer numbers (10 to 250) I'll call it Offset. Then just do the reverse formula.

AD_Cal = (Offset * 1024) / 5000

This one doesn't fit in with the */ operator, so you'll need to use DIV32.
Offset = 250 ; 0.250V - Must be a WORD Var
AD_Cal = Offset * 1024
AD_Cal = DIV32 5000

This gives a result of 51, which can then be added or subtracted from the AD result as necessary.

HTH,

rhino
- 18th January 2007, 20:00
To supplement Darrel's example/description, I'd suggest looking HERE (http://www.emesystems.com/BS2index.htm#math) for some good examples.