PDA

View Full Version : Mathematics and remainder for PLL MC145158



RFsolution
- 16th August 2005, 20:03
Hi All

I need some help with some mathematics and remainders, which might not be that difficult if you know how to handle it

Here is what I want to do and calculate in pbp:

I want to determine the A and N counters from a dual modulus PLL MC145158 for who might be familiar with it, if not:
I receive with serin a value which is 6 digits with 1 decimal point a frequency in Khz with 1 decimal
ex: 433687,5 which is Freq as variable or if easyer 433 (in one variable) , and 6875 in another

So:

Freq = var ??? (because it is bigger than 16bit

I have 3 variable, one is fixed which needs to be calculated as followed:

R = var word (14bit)
R = 800 '(fix value untill now)
N = var word (10bit) 'to be calculated
A = var word (7bit) 'to be calculated
temp var word


here is what I need to do in PBP comming from a original C source:

unsigned long temp,nlong,along
Temp = (501800 - 433687,5) * 800
Nlong = temp/64000
Along = (temp-(Nlong*64000))/1000
N = (unsigned int) Nlong
A= (unsigned int)Along




example: freq is 433,6875 Mhz
temp = (501800 - 433687,5) * 800 = 54490000
Nlong = temp/64000 = 54490000/64000 = 851,40625000 (64000 is a fixed divider ratio)
Along = ((Nlong*64000))/1000 = (0,406250*64000))/1000 = 26 '0,406250 is remainder from 851,406250

result should be:
N = 851 without remainder
A = 26

Anyone who can help me

Darrel Taylor
- 17th August 2005, 20:25
HI RFsolution,

I was trying to work thru this calculation, but I have a question. There's seems to be 2 different ways of calculating "Along".

In the "here is what I need to do " section, it's...
Along = (temp-(Nlong*64000))/1000

Then in the example, it's
Along = ((Nlong*64000))/1000

For now, I'm assuming the second one is correct, but just wanted to verify it with you.<br><br>

Darrel Taylor
- 18th August 2005, 06:56
Well, nevermind, I got it figured out anyway.

Give this a try.
<font color="#000000"><b>Freq1 </b><font color="#008000"><b>VAR WORD
</b></font><b>Freq2 </b><font color="#008000"><b>VAR WORD

</b></font><b>N </b><font color="#008000"><b>VAR WORD
</b></font><b>A </b><font color="#008000"><b>VAR WORD
</b></font><b>Remainder </b><font color="#008000"><b>VAR WORD


</b></font><font color="#0000FF"><b><i>; --- Frequency must be split into 2 variables ---
</i></b></font><b>Freq1 </b>= <b>4336 </b><font color="#0000FF"><b><i>; 433687.5
</i></b></font><b>Freq2 </b>= <b>875
</b><font color="#008000"><b>GOSUB </b></font><b>PLL_Calc

</b><font color="#008000"><b>STOP

</b></font><b>PLL_Calc</b>:
<b>N </b>= (<b>5018 </b>- <b>Freq1</b>)
<font color="#008000"><b>IF </b></font><b>Freq2 </b>&gt; <b>0 </b><font

color="#008000"><b>THEN
</b></font><b>A </b>= <b>1000 </b>- <b>Freq2
N </b>= <b>N </b>- <b>1
</b><font color="#008000"><b>ELSE
</b></font><b>A </b>= <b>0
</b><font color="#008000"><b>ENDIF
</b></font><b>N </b>= <b>N </b>* <b>8
A </b>= <b>A </b>* <b>8

N </b>= <b>N </b>+ (<b>A</b>/<b>1000</b>)
<b>A </b>= <b>A </b>- (<b>A</b>/<b>1000</b>*<b>1000</b>)

<b>N </b>= <b>N</b>*<b>10
N </b>= <font color="#008000"><b>DIV32 </b></font><b>64
Remainder </b>= <b>R2
Remainder </b>= <b>Remainder </b>* <b>10000
Remainder </b>= <font color="#008000"><b>DIV32 </b></font><b>64

A </b>= <b>A </b>* <b>10000
A </b>= <font color="#008000"><b>DIV32 </b></font><b>64

A </b>= <b>A </b>+ <b>Remainder
A </b>= <b>A </b>* <b>64
A </b>= <font color="#008000"><b>DIV32 </b></font><b>10000
Remainder </b>= <b>R2
</b><font color="#008000"><b>IF </b></font><b>Remainder </b>&gt;= <b>5000 </b><font

color="#008000"><b>THEN </b></font><b>A </b>= <b>A </b>+ <b>1
</b><font color="#008000"><b>RETURN</b></font>

RFsolution
- 21st August 2005, 16:24
Hi darrel

I gave it a try but I think there is still a problem

As I told you it is a part of the C routine, but if i take the remainder from
:
Nlong = temp/64000 = 54490000/64000 = 851,40625000
so the remainder is 0,40625000 and multiply by 64000 divide by 1000
is giving me the correct A value

Tis is not the case with your example

Can you have a look ?, you can try any example of freq (in the range 430000.0 til 440000.0 following my example

Thanks again

Darrel Taylor
- 21st August 2005, 19:33
OOPS, you're right.

Somehow, in the process of posting it, I lost two 0's in the third DIV32.

This works better.
<font color="#000000"><b>Freq1 </b><font color="#008000"><b>VAR WORD
</b></font><b>Freq2 </b><font color="#008000"><b>VAR WORD

</b></font><b>N </b><font color="#008000"><b>VAR WORD
</b></font><b>A </b><font color="#008000"><b>VAR WORD
</b></font><b>Remainder </b><font color="#008000"><b>VAR WORD


</b></font><font color="#0000FF"><b><i>; --- Frequency must be split into 2 variables ---
</i></b></font><b>Freq1 </b>= <b>4336 </b><font color="#0000FF"><b><i>; 433687.5
</i></b></font><b>Freq2 </b>= <b>875
</b><font color="#008000"><b>GOSUB </b></font><b>PLL_Calc

</b><font color="#008000"><b>STOP

</b></font><b>PLL_Calc</b>:
<b>N </b>= (<b>5018 </b>- <b>Freq1</b>)
<font color="#008000"><b>IF </b></font><b>Freq2 </b>&gt; <b>0 </b><font

color="#008000"><b>THEN
</b></font><b>A </b>= <b>1000 </b>- <b>Freq2
N </b>= <b>N </b>- <b>1
</b><font color="#008000"><b>ELSE
</b></font><b>A </b>= <b>0
</b><font color="#008000"><b>ENDIF
</b></font><b>N </b>= <b>N </b>* <b>8
A </b>= <b>A </b>* <b>8

N </b>= <b>N </b>+ (<b>A</b>/<b>1000</b>)
<b>A </b>= <b>A </b>- (<b>A</b>/<b>1000</b>*<b>1000</b>)

<b>N </b>= <b>N</b>*<b>10
N </b>= <font color="#008000"><b>DIV32 </b></font><b>64
Remainder </b>= <b>R2
Remainder </b>= <b>Remainder </b>* <b>10000
Remainder </b>= <font color="#008000"><b>DIV32 </b></font><b>64

A </b>= <b>A </b>* <b>10000
A </b>= <font color="#008000"><b>DIV32 </b></font><b>6400 <font color="#0000FF">; <-- Changed, was 64</font>

A </b>= <b>A </b>+ <b>Remainder
A </b>= <b>A </b>* <b>64
A </b>= <font color="#008000"><b>DIV32 </b></font><b>10000
Remainder </b>= <b>R2
</b><font color="#008000"><b>IF </b></font><b>Remainder </b>&gt;= <b>5000 </b><font

color="#008000"><b>THEN </b></font><b>A </b>= <b>A </b>+ <b>1
</b><font color="#008000"><b>RETURN</b></font>

RFsolution
- 22nd August 2005, 10:09
Sorry Darrel, can you have a look again ?
In the code A = (A/1000*1000) does not do anything
So the A counter value is not calculated correctly


Is it possible to use for freq1 only the 3 first digits
for freq2 4 digits, it makes more sense and easyer for the serin2 command
to enter the completer frequency

433.6875 Mhz so we can split 433 and 6875 into 2 variables

What you think ?

Darrel Taylor
- 22nd August 2005, 18:13
In the code A = (A/1000*1000) does not do anything
Yes it does! Since PBP only works with integers, dividing by 1000 then multiplying by 1000 will isolate any digits over 1000. With Freq2 only being 3 digits, anything over 1000 gets added to the N value.



Is it possible to use for freq1 only the 3 first digits for freq2 4 digits
No. Due to overflow and accuracy problems, Freq2 must only be 3 digits. Since, the numbers are being parsed from ascii text, it shouldn't matter how many digits are in each parameter.

Here are some sample results of actually running the routine on a PIC16F877.
Scroll to the right for the PIC results.
<table BORDER="1" CELLSPACING="0" BORDERCOLOR="#000000" CELLPADDING="2" WIDTH="789" height="279">
<tr>
<td WIDTH="11%" HEIGHT="23">
<p></p>
</td>
<td WIDTH="9%" HEIGHT="23">
<p></p>
</td>
<td WIDTH="9%" HEIGHT="23">
<p></p>
</td>
<td WIDTH="3%" HEIGHT="213" rowspan="11">
<p></p>
</td>
<td WIDTH="48%" HEIGHT="23" colspan="5">
<p ALIGN="CENTER">Calculated</td>
<td WIDTH="2%" HEIGHT="213" rowspan="11">
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
</td>
<td WIDTH="19%" COLSPAN="2" HEIGHT="23">
<p ALIGN="CENTER">Results from PIC</td>
</tr>
<tr>
<td WIDTH="11%" align="center" ><b>
<p >Freq</b></td>
<td WIDTH="9%" align="center" ><b>
<p >Freq1</b></td>
<td WIDTH="9%" align="center" ><b>
<p >Freq2</b></td>
<td WIDTH="11%" ><b>
<p >C Result N</b></td>
<td WIDTH="8%" ><b>
<p >INT N</font></b></td>
<td WIDTH="11%" ><b>
<p >Remainder</font></b></td>
<td WIDTH="11%" ><b>
<p >C Result A</font></b></td>
<td WIDTH="7%" ><b>
<p >INT A</font></b></td>
<td WIDTH="10%" align="center" ><b>
<p >N</font></b></td>
<td WIDTH="9%" align="center" ><b>
<p >&nbsp;A</font></b></td>
</tr>
<tr>
<td WIDTH="11%" >
<p ALIGN="RIGHT">430000.0</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">4300</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">0</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">897.5</font></td>
<td WIDTH="8%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">897</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">0.5</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">32</font></td>
<td WIDTH="7%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">32</font></td>
<td WIDTH="10%" >
<p ALIGN="RIGHT">897</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">32</font></td>
</tr>
<tr>
<td WIDTH="11%" >
<p ALIGN="RIGHT">430816.5</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">4308</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">165</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">887.29375</font></td>
<td WIDTH="8%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">887</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">0.29375</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">18.8</font></td>
<td WIDTH="7%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">19</font></td>
<td WIDTH="10%" >
<p ALIGN="RIGHT">887</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">19</font></td>
</tr>
<tr>
<td WIDTH="11%" >
<p ALIGN="RIGHT">431123.3</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">4311</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">233</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">883.45875</font></td>
<td WIDTH="8%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">883</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">0.45875</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">29.36</font></td>
<td WIDTH="7%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">29</font></td>
<td WIDTH="10%" >
<p ALIGN="RIGHT">883</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">29</font></td>
</tr>
<tr>
<td WIDTH="11%" >
<p ALIGN="RIGHT">432000.0</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">4320</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">0</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">872.5</font></td>
<td WIDTH="8%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">872</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">0.5</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">32</font></td>
<td WIDTH="7%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">32</font></td>
<td WIDTH="10%" >
<p ALIGN="RIGHT">872</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">32</font></td>
</tr>
<tr>
<td WIDTH="11%" >
<p ALIGN="RIGHT">432086.1</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">4320</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">861</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">871.42375</font></td>
<td WIDTH="8%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">871</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">0.42375</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">27.12</font></td>
<td WIDTH="7%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">27</font></td>
<td WIDTH="10%" >
<p ALIGN="RIGHT">871</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">27</font></td>
</tr>
<tr>
<td WIDTH="11%" >
<p ALIGN="RIGHT">433010.7</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">4330</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">107</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">859.86625</font></td>
<td WIDTH="8%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">859</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">0.86625</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">55.44</font></td>
<td WIDTH="7%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">55</font></td>
<td WIDTH="10%" >
<p ALIGN="RIGHT">859</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">55</font></td>
</tr>
<tr>
<td WIDTH="11%" ><b>
<p ALIGN="RIGHT">433687.5</font></b></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">4336</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">875</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">851.40625</font></td>
<td WIDTH="8%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">851</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">0.40625</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">26</font></td>
<td WIDTH="7%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">26</font></td>
<td WIDTH="10%" >
<p ALIGN="RIGHT">851</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">26</font></td>
</tr>
<tr>
<td WIDTH="11%" >
<p ALIGN="RIGHT">438214.0</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">4382</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">140</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">794.825</font></td>
<td WIDTH="8%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">794</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">0.825</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">52.8</font></td>
<td WIDTH="7%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">53</font></td>
<td WIDTH="10%" >
<p ALIGN="RIGHT">794</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">53</font></td>
</tr>
<tr>
<td WIDTH="11%" >
<p ALIGN="RIGHT">440000.0</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">4400</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">0</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">772.5</font></td>
<td WIDTH="8%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">772</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">0.5</font></td>
<td WIDTH="11%" >
<p ALIGN="RIGHT">32</font></td>
<td WIDTH="7%" BGCOLOR="#ffff00" >
<p ALIGN="RIGHT">32</font></td>
<td WIDTH="10%" >
<p ALIGN="RIGHT">772</font></td>
<td WIDTH="9%" >
<p ALIGN="RIGHT">32</font></td>
</tr>
</table>
The only possibility I can see for getting the wrong answer, is that I am rounding the A value in the last line of the routine. You had only requested the integer. If you don't want it to be rounded, simply comment out the ...

IF Remainder >= 5000 THEN A = A + 1

If you still get the wrong numbers, let me know.

<br>

RFsolution
- 23rd August 2005, 21:00
Hi Darrel

Oeps, I changed A var word to A var byte to save some place
But as A is only 127, but you use the word space to calculate

Thanks again, it looks that it works

CocaColaKid
- 23rd August 2005, 22:30
Just curious where the "R2" comes from?

Darrel Taylor
- 23rd August 2005, 22:53
R2 is one of PBP's system variables. They are defined in the PBPPICxx.RAM files, located in the PBP folder.

In this case R2 holds the modulas (remainder) of the DIV32 command.

For more info ... http://www.picbasic.co.uk/forum/showthread.php?t=48

<br>

CocaColaKid
- 23rd August 2005, 22:59
So this is basically the same as the // but only for DIV32?

Darrel Taylor
- 23rd August 2005, 23:16
Correct!<br><br>

CocaColaKid
- 23rd August 2005, 23:32
On that note though would you not think that it would be listed as a reserved word?

rhino
- 24th August 2005, 01:02
R2 is one of PBP's system variables. They are defined in the PBPPICxx.RAM files, located in the PBP folder.

In this case R2 holds the modulas (remainder) of the DIV32 command.

<br>
I was looking through this file, hoping to learn some of that voodoo that Darrel pops on us time to time... but all the definition said was "System Register". Does anyone know just what exactly these other variables mean or do? Is it documented somewhere that I have missed?

Darrel Taylor
- 24th August 2005, 02:20
I've been found out. I guess I can take those pins out of my Rhinoceros doll now. :)

While the PBPPICxx.RAM declares the system variables, the PBPPICxx.LIB and PBPPICxx.MAC files are where you'll find out how they are used.

For instance, with the DIV32 command on an 18F part... Open up the PBPPIC18.LIB file and search for DIV32. You'll find this header in front of the code for the DIV32 command.
;************************************************
;* DIV32 : 31 x 15 divide
;*
;* Input : R0, R2 = 32 bits
;* : R1 + 1, W = divisor
;* Output : R0 = quotient
;* : R2 = remainder
;*
;* Notes : Uses result from MUL.
;************************************************
From that you can see that R2 is the remainder of a DIV32, even though it's not mentioned anywhere in the manual.

Most of the PBP macros have a header showing the input and output variables, but not necessarily all the system variables that are used by that routine. For that you have to digest the code and follow subroutine calls.

As far as I know, there is no list of macro's or the system variables that they use. My guess is that it would create a tech support nightmare for them if they put that kind of stuff in the manual. Can't blame them.

<br>

rhino
- 24th August 2005, 04:32
aaaahhh..... it's a dark mysterious art. I shall take your teachings and proceed with caution. As for the pins.... I'll consider it some kind of hazing/right of passage ritual. Seriously... thanks for the info.