PDA

View Full Version : N-Bit_MATH



Darrel Taylor
- 4th January 2010, 00:52
I recently came across these great routines from Alexander Avtanski, on the PicList (http://www.piclist.com/techref/microchip/math/index.htm) ...
http://avtanski.net/projects/math/
All credit goes to Alexander!

Everything was there, it just needed a few tweaks to be used with PicBasic Pro.

They're so cool ...

8, 16, 24, 32, 64, 128-bit Integer Math or more.
You want BIG numbers? .... you got 'em.
N-Bit means any number of bits.

16F, 18F ... doesn't matter (other than RAM space), and you must be using MPASM.
<hr>
The number of bytes used in the math depends on the PRECISION constant.
If PRECISION = 4, then all math is done as 32-bit operations.

So you need to have variables of the same size, which is easy to do with ...


PRECISION CON 4 SYSTEM ' 4 bytes = 32-bit

SetPoint VAR BYTE[PRECISION]
Position VAR BYTE[PRECISION]
Error VAR BYTE[PRECISION]
Current VAR BYTE[PRECISION]
MyVar VAR BYTE[PRECISION]


Then you can do the math on those variables with ...


@ MATH_SUB _SetPoint, _Position, _Error ; subtract Position from setpoint

Which subtracts Position from Setpoint and puts the result in Error.
<hr>

All I've done is put a "wrapper" around the original routines from Alexander (http://avtanski.net/projects/math/), so they can still be used exactly like the webpage says.
I've also added some macros to make things easier with PBP.



@ MATH_CLR _Pvar ; clear an N-Bit variable
@ MATH_INC _Pvar ; increment an N-Bit variable
@ MATH_DEC _Pvar ; decrement an N-Bit variable
@ MATH_ROL _Pvar ; rotate LEFT
@ MATH_ROR _Pvar ; rotate RIGHT
@ MATH_CMP _A, _B ; Compare Pvars - result in M_EQ and M_GTE bits
@ MATH_ADD _A, _B, _Res ; Res = A + B
@ MATH_SUB _A, _B, _Res ; Res = A - B
@ MATH_MUL _A, _B, _Res ; Res = A * B
@ MATH_DIV _A, _B, _Res ; Res = A / B - Remainder in REG_Z

At this point I'm calling them Pvar's because unlike a byte or word, they could be any length specified by the PRECISION constant.
ALL math done with these routines are done at the PRECISION level, and all variables used with the MATH functions must be (PRECISION) bytes in length.

Additional macros were created to allow movement of variables between bytes, words, longs and the Pvars.


@ MOVE?CP Cin, _Pout ; copy a CONSTANT to a Pvar
@ MOVE?BP _Bin, _Pout ; copy a BYTE to a Pvar
@ MOVE?WP _Win, _Pout ; copy a WORD to a Pvar
@ MOVE?LP _Lin, _Pout ; copy a LONG to a Pvar (PBPL only)
@ MOVE?PP _BeerIN, _Pout ; copy a Pvar to a Pvar

And the inverse of those puts them back into PBP variables again.


@ MOVE?PB _Pin, _Bout ; truncate a Pvar into a BYTE var
@ MOVE?PW _Pin, _Wout ; truncate a Pvar into a WORD var
@ MOVE?PL _Pin, _Lout ; truncate a Pvar into a LONG var (PBPL only)


http://www.pbpgroup.com/files/bargreen.gif

So let's say you were getting a 16-bit value from the QEI counter, and the upper 16-bits from a Rollover interrupt.
You could move them all into a Pvar with two lines ...


RollOvers VAR WORD ; QEI rollovers (from interrupt)

@ MOVE?WP POSCNTL, _Position ; copy QEI count to Position.Word0
@ MOVE?WW _RollOvers, _Position + 2 ; copy rollovers to Position.Word1

;-- Calculate the Error --
@ MATH_SUB _SetPoint, _Position, _Error ; Error = Setpoint - Position
@ MOVE?PW _Error, _pid_Error ; copy Pvar result to a WORD variable

This way you can do 32-bit math without PBPL. Or 64-bit if you needed.
It's not as easy as PBPL, but can be very useful.

Keep in mind that the math is all Software. Multiplication does not use the hardware multiplier.
So with 18F's, MATH_MUL at 32-bits will take longer than PBPL with 32-bits.

However, you can still use all of the math statements within PBP, and they will be faster without PBPL, or BIGGER with PBPL.

http://www.pbpgroup.com/files/bargreen.gif

Another recent request from someone in this forum was to have a counter that keeps track of the number of milliseconds since the power was turned on.
That can be a pretty big number ... if it's been powered-up for a decade or two.
No problem ...



'----[N-Bit Math]-----------------------------------------------------------
PRECISION CON 5 SYSTEM ; 5 bytes=40-bit
INCLUDE "N-Bit_MATH.pbp"

Powered_MS VAR BYTE[PRECISION]

MS_intHandler: ; this routine should be called every mS via a timer interrupt
@ FSRSAVE ; Save FSR value before interrupt code
@ MATH_INC _Powered_MS ; increment # of mS since PWR_ON
@ FSRREST ; Restore FSR
; return from interrupt, depends on the type of interrupt.
; interrupt code and context saving not shown.


That will happily count the number of milliseconds passed for over 34 years. 2<sup>^</sup>40/(1000*60*60*24*365)
If you need it to count longer ... go with 6 byte PRECISION (8,925 years).

<hr>
The routines are completely ASM, and do not use any of PBP's system variables. So it's OK to use them within ASM type Interrupts if desired.
But you'll need to save the FSR value before doing any MATH because it uses the FSR and would disrupt the flow of the Main program if not saved.

The @ FSRSAVE and @ FSRREST can be used to make it easy.

Note: DT_INTS already saves/restores the FSR's at the beginning/end of an interrupt, so you don't have to.
For ASM interrupts, you will need to save it. FSR's don't matter with ON INTERRUPT.

<hr>
Please understand that these are "Advanced Level" math routines.
I can not debug everyone's program that ends up not compiling because of syntax errors.

If you truely believe that something is wrong with the routines, I would love to hear it. And I will do my best to fix it.
If you can't get it to compile ... keep trying ... it will.

Here's the Include File.
Current Version = 1.4 Beta (8/4/2010); Workaround for MPASMs shift > 32-bits

History:
&nbsp; &nbsp; 1.3 Beta 1/7/2010 ; compatability with 16F1xxx chips (enhanced core)
&nbsp; &nbsp; 1.2 Alpha 1/4/2010 ; adds ability to turn Case Sensitivity off in MPASM
&nbsp; &nbsp; 1.1 Alpha 1/4/2010 ; fixes FSR conflict with DT_INTS-18
&nbsp; &nbsp; 1.0 Alpha 1/3/2010 ; initial release

Darrel Taylor
- 4th January 2010, 00:54
Hopefully, more info and examples forthcoming.
<br>

ScaleRobotics
- 4th January 2010, 02:28
Very cool! I've got to try these out. Thanks Alexander and Darrel!

Ioannis
- 4th January 2010, 10:32
As always, a great Darrel Taylor's project!

Thanks!

Ioannis

HenrikOlsson
- 4th January 2010, 16:21
Wow, this is going to be very cool Darrel!
I know you said to keep trying if it wouldn't compile but I can't seem to get it to "go thru" when using it in the same program as DT-Ints... Boiled down example, this compiles:

PRECISION CON 4 SYSTEM
INCLUDE "N-Bit_Math.pbp"

Setpoint VAR BYTE[PRECISION]
Position VAR BYTE[PRECISION]
Error VAR BYTE[PRECISION]

Start:
Pause 10
Goto Start


This does not compile (or assemble):

PRECISION CON 4 SYSTEM
INCLUDE "N-Bit_Math.pbp"
INCLUDE "DT_INTS-18.pbp" 'Include the interrupt system files.
INCLUDE "ReEnterPBP-18.pbp"

ASM
INT_LIST macro ;IntSource Label Type ResetFlag
INT_Handler INT2_INT, _DoStep, PBP, yes
endm
INT_CREATE
ENDASM

@ INT_ENABLE INT2_INT

Setpoint VAR BYTE[PRECISION]
Position VAR BYTE[PRECISION]
Error VAR BYTE[PRECISION]

Start:
Pause 10
Goto Start

DoStep:
Toggle PortB.7
@ INT_RETURN

I get a whole bunch of Symbol not previously defined FSR0L0L and so on.

Similarily, same code as above but simply removing the INCLUDE "N-Bit_Math.pbp"-line also compiles fine so there seems to be some incompatibillity there.I'm using 18F2431 but the device selected in MCS+ doesn't seem to matter.

Any ideas what might be the issue?
Thanks!
/Henrik.

Darrel Taylor
- 4th January 2010, 19:43
Hmmm, apparently it's laughing at my use of FSR's "FSR0L0L". :D

You are correct, there is a conflict when used with DT_INTS-18.
DT-INTS-14 is OK.

I must find a way around it.

Thanks Henrik.

Darrel Taylor
- 4th January 2010, 23:15
Thanks again Henrick.
The FSR problem should be fixed.

The file has been updated to version 1.1 Alpha.
And should now work with DT-INTS-18.

http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3854&d=1262930635

Cheers,

Bruce
- 5th January 2010, 00:01
Hey Darrel,

Only works for me with MPASM assembler case sensitive option enabled.

In DT_INTS-18;
SaveFSR macro F, Pr
RestFSR macro F, Pr

And in N-Bit_Math:
SAVEFSR macro
RESTFSR macro

Edit:


MOVE?PP macro BeerIN, Pout ; copy an N-bit variable to an N-bit variable
BeerCount = 0
while BeerCount < PRECISION
MOVE?BB BeerIN + BeerCount, Pout + BeerCount
BeerCount = BeerCount + 1
endw
endm

Too cool --- Classic Darrel...;o)

Darrel Taylor
- 5th January 2010, 00:50
Only works for me with MPASM assembler case sensitive option enabled.
Well, then keep case sensitivity enabled. :)

OK, since it's you bruce.
Update 1.2 Alpha ; adds ability to turn Case Sensitivity off in MPASM
Changes SAVEFSR and RESTFSR, to FSRSAVE and FSRREST.

http://www.picbasic.co.uk/forum/attachment.php?attachmentid=3854&d=1262930635

I think I'll go MOVE?PP now. :D
<br>

Bruce
- 5th January 2010, 01:14
Must have missed a version update somewhere in the mix. 1.2a works as expected.

Nice find on the math routines. Very handy. Nice work on the PBP wrappers too.

Thanks.

What I had tested was the 1.1 Alpha 1/4/2010 ; fixes FSR conflict with DT_INTS-18
in post #1, which changed to 1.2 alpha within just few minutes from posting.

Darrel Taylor
- 5th January 2010, 02:19
You didn't miss anything.
I fixed it within 50 minutes from your report, and reposted before you could say MOVE?PP. :)

Gets lost in the back and forth
I'm glad it's working better for you now.
<br>

WOZZY-2010
- 26th January 2010, 04:59
Greeting All.

This is my first post, but I've been lurkin' and learnin' from this site for quite a long time. Thanks to all the regulars for your great threads. I'm an aerodynamicist by training, but like to to tinker with just about everything geeky.

I can muddle my way through BASIC, but have quite a bit of difficulty with assembler, though by necessity, I am beginning to learn a little.

I was very excited by the N-Bit Math routines, since it should allow high precision to be carried through all the computations. I am especially interested in the MATH_DIV w/ Remainder routine. I've had a problem with some of my projects where I need to divide two large numbers, yet retain the precision.
I was hopeful that the N_BIT Math will allow that.

I've spent many hours now trying to implement this in my chip, but have been unable to get meaningful output.

I developed this simple test program to try to understand it (unsuccessfully):


' TROUBLESHOOTER for N-BIT MATH
' By WOZZY
' PIC18F4680
' Compile with -n -ampasmwin Build Options
' 32 BIT LONG


INCLUDE "N-Bit_Math.pbp" ' Include Alexander Avtanski's Multibyte Arithmetic
' Assembly Library Wrapped for PBP by Darryl Taylor
' Version:1.3 Beta (1/7/2010)

DEFINE OSC 20 ' 20 MHz Crystal Oscillator

DEFINE DEBUG_REG PORTC ' PORT C6
DEFINE DEBUG_BIT 6 ' PORT C6
DEFINE DEBUG_BAUD 57600 ' BAUD 57600
DEFINE DEBUG_MODE 0 ' 1 = inverted, 0 = true

PRECISION CON 8 SYSTEM ' 8 bytes = 64-bit

I VAR BYTE

AA_LONG VAR LONG
BB_LONG VAR LONG
CC_LONG VAR LONG
DD_LONG VAR LONG

AA64 VAR BYTE[PRECISION]
BB64 VAR BYTE[PRECISION]
CC64 VAR BYTE[PRECISION]
DD64 VAR BYTE[PRECISION]

XX64 VAR BYTE[PRECISION]
YY64 VAR BYTE[PRECISION]
ZZ64 VAR BYTE[PRECISION]

PAUSE 500 : DEBUG " ",10,13,10,13 : PAUSE 500

MAIN:

AA_LONG = 2134567891
BB_LONG = 1987654321
CC_LONG = 2176437299
DD_LONG = 12

@ MOVE?LP _AA_LONG, _AA64 ; @ MOVE?LP _Lin, _Pout ; copy a LONG to a Pvar (PBPL only)
@ MOVE?LP _BB_LONG, _BB64 ; @ MOVE?LP _Lin, _Pout ; copy a LONG to a Pvar (PBPL only)
@ MOVE?LP _CC_LONG, _CC64 ; @ MOVE?LP _Lin, _Pout ; copy a LONG to a Pvar (PBPL only)
@ MOVE?LP _DD_LONG, _DD64 ; @ MOVE?LP _Lin, _Pout ; copy a LONG to a Pvar (PBPL only)
@ MATH_MUL _AA64, _BB64, _XX64 ; @ MATH_MUL _A, _B, _Res ; Res = A / B - Remainder in REG_Z
@ MATH_DIV _CC64, _DD64, _YY64 ; @ MATH_DIV _A, _B, _Res ; Res = A / B - Remainder in REG_Z
@ MATH_DIV _DD64, _CC64, _ZZ64 ; @ MATH_DIV _A, _B, _Res ; Res = A / B - Remainder in REG_Z

DEBUG "BYTE ORDER BYTE[7],BYTE[6],BYTE[5],BYTE[4],BYTE[3],BYTE[2],BYTE[1],BYTE[0]",10,13,10,13
DEBUG "AA64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 AA64 : NEXT I : DEBUG 10,13
DEBUG "BB64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 BB64[I] : NEXT I : DEBUG 10,13
DEBUG "CC64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 CC64[I] : NEXT I : DEBUG 10,13
DEBUG "DD64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 DD64[I] : NEXT I : DEBUG 10,13
DEBUG "XX64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 XX64[I] : NEXT I : DEBUG 10,13
DEBUG "YY64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 YY64[I] : NEXT I : DEBUG 10,13
DEBUG "ZZ64 = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 ZZ64[I] : NEXT I : DEBUG 10,13
DEBUG "REG_Z = " : FOR I = 7 to 0 Step -1 : DEBUG BIN8 REG_Z[I] : NEXT I : DEBUG 10,13
DEBUG 10,13,10,13,10,13,10,13
PAUSE 10000
GOTO MAIN

END

Here is the commented output:


BYTE ORDER BYTE[7],BYTE[6],BYTE[5],BYTE[4],BYTE[3],BYTE[2],BYTE[1],BYTE[0]

AA64 = 00000000000000000000000000000000011111110011101011 10101111010011
= 12 OK, Should Be 2134567891: (MOVE?LP)

BB64 = 00000000000000000000000000000000011101100111100100 11001010110001
= 1987654321 OK, Should Be: 1987654321 (MOVE?LP)

CC64 = 00000000000000000000000000000000100000011011100111 00110000110011
= 2176437299 OK, Should Be: 2176437299 (MOVE?LP)

DD64 = 00000000000000000000000000000000000000000000000000 00000000001100
=12 OK, Should Be 12: (MOVE?LP)

XX64 = 01110101000000000000000001001100000000000000000000 00000000000000
= 8,430,738,828,855,080,000 Should Be: 4,242,783,092,014,010,000 (MATH-MUL)

YY64 = 00000000010000000000000000000000000000000000000000 00000000000000
= 18,014,398,509,482,000 Should Be: 181,369,774 (MATH_DIV)

ZZ64 = 00000000010011000000000000000000000000000000000000 00000000000000
= 21,392,098,230,009,900 Should Be: 0 (MATH_DIV)

REG_Z = 00000000000000000100110000000000000000000000000000 00000000000000
= 83,562,883,710,976 Should Be: 0.0000000055135978 (Remainder)

So I was wondering if anyone has successfully implemented the Multiplication and Division in N_BIT Math.

I would really appreciate it if someone could help me decode the output, point out the error in my ways, or at least point me in the right direction.

Thanks,
[I]Wozzy-2010

PS. Darryl, A huge thank you for all the routines you have developed.
Your Inst_Interrupts are better than sardines on toast.

Darrel Taylor
- 26th January 2010, 08:18
Ewwww, that's ugly.
And I agree, something's not right.

I will see what I can find.
Thanks Wozzy,

Darrel Taylor
- 26th January 2010, 09:12
Whew, had me worried there for a minute. :)

In order for the Include file to create the correct size working variables ...
The PRECISION constant needs to be BEFORE the include file.


PRECISION CON 8 SYSTEM ' 8 bytes = 64-bit
INCLUDE "N-Bit_Math.pbp" ' Include Alexander Avtanski's Multibyte Arithmetic
' Assembly Library Wrapped for PBP by Darryl Taylor
' Version:1.3 Beta (1/7/2010)

It was creating Working vars of only 1 byte, instead of 8 bytes.
After moving the constant, I got all the correct results with your program.

HTH,

Ioannis
- 26th January 2010, 09:32
Hmm, Darrel, don't you ever sleep?

Ioannis

Darrel Taylor
- 26th January 2010, 10:04
Hmm, Darrel, don't you ever sleep?

Yeah, but it's hard to get the drool out of the keyboard ...
Not to mention deleting several hours worth of J's where my nose pressed, so I try to avoid it. :D
<br>

WOZZY-2010
- 26th January 2010, 14:08
Thanks Darrel

Ouch....My head is sore from banging it on the workbench.

I'll try this out tonight and let you know.

I knew it must be something simple I was missing.

Wozzy

WOZZY-2010
- 27th January 2010, 05:20
Darrel,

Thanks again,

The N-Bit Troubleshooter program is working well now with the change you suggested.

It's seems pretty obvious now that I am aware of it.

So now I'll try to integrate it into my current program which is a two gate optical timer and speed calculator.

My next challenge is figuring out how to make use the 64-bit output

I'll post details when it's cleaned up and N-Bit math is integrated.

Wozzy-2010

Darrel Taylor
- 27th January 2010, 05:38
Great news!


So now I'll try to integrate it into my current program which is a two gate optical timer and speed calculator.
OOOOO, a math problem .... can I play?

How far apart?
Snail races? Or, rocket powered unicycle?
<br>

WOZZY-2010
- 27th January 2010, 17:46
Darrel,

Well, Me being Me I want it to do EVERYTHING, so the distance between the gates will be an input variable.
My light source is a beam-split 650nm (red) solid state laser that's way more powerful than it needs to be (but also a lot more fun!)
My Optical sensors are Osram SFH 5840 PhotoTransistors with built-in Schmitt Trigger.
The outputs are combined into a single pulse using an LS74F00 configured as an S-R Latch. (this allows me to use the same code and input pin with either one or two sensors)

The timer code is based on DT_INSTANT_INTERRUPTS running on a PIC18F4680 @ 20 MHz

This is all working very well as a high resolution timer, though I am still working on some corrections for software and hardware delays.

I may consider redoing the timer portion of the software using the N-Bit Variable Math, as I'm currently limited to about 1.5 Minutes.

I needed the N-Bit Math to get the resolution I want when converting from Time to Speed, as I end up dividing two large numbers.

My immediate goals are...
How fast are Pinewood Derby Cars?
How fast is my dog? (Very Fast!)
How fast am I? (Very Slow)
How fast can I back-slap someone? (approx. 29.97235 MPH)-DONE!
What is the muzzle velocity of my air rifle with different pellets?
How fast does that Jerk down the street drive past my house while kids are outside playing?
...

I only have time to work on this late at night.
I'll work on cleaning the code up a little before I lay it out for all to see.

So far this has been a really fun and educational project.
My youngest daughter (11yo) is learning with me, she seems very interested in what I'm doing. So I try and explain it to her as I go.

Again thanks to you and the others on the Forum that are so willing to share your knowledge to help others learn.

boroko
- 27th January 2010, 23:23
A story:

A young man was traveling from Georgia to Florida on a quick weekend trip to see someone. He drives Very fast on the way south. On the return trip, he decides to slow down a bit. While traveling across a bridge, he notices a officer of the law below on a perpendicular highway. He thinks "Ha!, someone is going to get a ticket on that other road!". Within a few minutes, he was visited by that same officer. When the traveler asked why the visit and personal attention, the officer explained that he was going 78 in a 55 and wanted it known just how wrong that was. When asked how he was able to measure the speed, he explained that the bridge was 1308 feet long and that it took 11.47 seconds to cross it. His LASCAR device helped him do the calculations.
-Input distance before hand
-trigger on entry
-trigger on exit
-run VISA card of foolish young man

Bo

WOZZY-2010
- 28th January 2010, 00:17
-run VISA card of foolish young man

Hmmmmm I hadn't thought about adding a credit card reader....

WOZZY-2010
- 7th February 2010, 06:45
Hi Darrel,

I finally got around top finishing up the Timer using the N-Bit MATH
I posted it in this thread:
http://www.picbasic.co.uk/forum/showthread.php?t=12634

I think it's really cool...It uses 64 Bit Math throughout and can run 99 minutes with 200 nS resolution.

Thanks for the help

--Bob

Darrel Taylor
- 8th February 2010, 00:01
Nice job Bob!
And nice work on the posts too.

I got lost in the math somewhere between ...

How fast am I? (Very Slow)
&nbsp; &nbsp; -- AND --
What is the muzzle velocity of my air rifle with different pellets?

Good thing you didn't need the help.

Thanks for the N-Bit Math workout too!
That really helps.

Cheers,

khufumen
- 14th March 2010, 00:05
Not being the brightest bulb in the math department, I was trying to figure out how to display the value of 100000 in decimal format on the debug screen.

So if I have the following loaded into a PVAR called SetPoint

SetPoint[0] = 160
SetPoint[1] = 134
SetPoint[2] = 1
SetPoint[3] = 0

How can I display is as 100000 as opposed to:

00000000000000011000011010100000

Hoping someone can point me in the right direction.

Eric




put 100000 into a PRECISION variable. Using a calculator I found the binary equivalent of 100000 and then took each byte and calculated the decimal value of it and plugged it in as shown below. Obviously this is quite laborious

PRECISION CON 4 SYSTEM
include "NBit_Math.bas"
SetPoint VAR BYTE[PRECISION]
SetPoint[0] = 160
SetPoint[1] = 134
SetPoint[2] = 1
SetPoint[3] = 0

Darrel Taylor
- 14th March 2010, 01:54
Much easier than using a calculator and separating the bytes.
You can load the number you want like this ...


@ MOVE?CP 100000, _SetPoint
Which puts up to a 32-bit Constant (4,294,967,295) into a PVAR.

Displaying the big numbers is just a matter of dividing them down to useable amounts.
For small numbers like 100,000 a single divide will do.

Divisor VAR BYTE[PRECISION]
Result VAR BYTE[PRECISION]
WordVar VAR WORD
Remainder VAR WORD

@ MOVE?CP 10000, _Divisor ; load 10,000 into Divisor
@ MATH_DIV _SetPoint, _Divisor, _Result ; isolate lowest 4 digits
@ MOVE?PW _Result, _WordVar ; copy Result to a PBP Word
@ MOVE?PW REG_Z, _Remainder ; copy remainder to a PBP Word

IF WordVar > 0 THEN
LCDOUT DEC Wordvar, DEC4 Remainder
ELSE
LCDOUT DEC Remainder
ENDIF


It should work up to 655,359,999. Larger numbers will require more divisions.
That's just off the top of my head, untested.
Let me know if you have problems.

khufumen
- 15th March 2010, 15:14
Darrel,
Thanks so much for your help. I've got it displaying the large values perfectly.
Eric

keymuu
- 13th December 2010, 14:28
Hi!

I have been away from PIC and PICbasic world over one and a half year now. However, I'm back again and run to a really strange thing. I have slightly over 28 k code where I need 36 bits for calculations, so I found that wonderful N-bit_Math (just beautiful). There is however, something strange going on.
the code for N-bits is as suggested by Darrel. And compiles without errors and warnings, as long as .... here is the code:


PRECISION CON 5 SYSTEM ' 5*8 = 40 bits, byte size for registers
include "N-Bit_Math.pbp"

define OSC 48 ' used clock frequenze

SetPoint VAR BYTE[PRECISION]
Position VAR BYTE[PRECISION]
Error VAR BYTE[PRECISION]
Current VAR BYTE[PRECISION]
MyVar VAR BYTE[PRECISION]
by var byte
wo var word
LHi var word
LMi var word
LLo var word

LHi = $7: LMi = $2174: LLo = $6FD9
for by = 0 to 4
select case by
case 0,1 : wo = LLo
case 2,3 : wo = LMi
case 4 : wo = LHi
end select
' SetPoint[2] = wo & $FF 'A
if (by & 1) = 0 _
then
by= by ' SetPoint[by] = wo & $FF ' B
else
by=by ' SetPoint[by] = wo >> 8 ' C
endif
next by
@ MATH_DIV _SetPoint, _Position, _Error

There are three comments (A,B and C). Depending on what combination you have will give different results for the compilation. As it is "now", SetPoint not involved, it compiles OK.

If I enable A then there are two warnings one saying both in the .mac file and ..pbppic18.lib file that "Address exceeds maximum range for this processor".

If I enable B and/or C without A then there is one Error (126) in pbppic18.lib saying "argument out of range (32816 not between 0-32767) and bunch of warnings, all saying "Address exceeds maximum range for this processor" in .lib and .mac files.

If I copy that to a new file and compile it then there are no problems to compile it.

I have been looking around the rest of the code to found something strange but can not image what it would be.

I'm using PicBasic pro 2.50b, MPASM and target is 18F4550.

The real question is:
What can in a code (the rest of it), what could make the compiler to act like that. Any ideas ?
Any suggestion what to look for? Please help....

Darrel Taylor
- 13th December 2010, 16:45
If you un-comment B or C, then you end up with invalid statements.

But in general, it looks like your program is larger than the chips memory.
No way to know with only a snippet of your code.

And, it would be easier to load the SetPoint this way ...
@ MOVE?CP 21746FD9h, _SetPoint
SetPoint(4) = 7

keymuu
- 13th December 2010, 20:06
If you un-comment B or C, then you end up with invalid statements.

But in general, it looks like your program is larger than the chips memory.
No way to know with only a snippet of your code.

And, it would be easier to load the SetPoint this way ...
@ MOVE?CP 21746FD9h, _SetPoint
SetPoint(4) = 7

Thanks Darrel,

chips memory should be 32k (18F4550) and within the IF statement only two times by = by and not any SetPoint "statements" then the compiled size is 28692 bytes. That is the strange thing here, how can one explain that?

I tested this:
@ MOVE?CP 21746FD9h, _SetPoint
SetPoint(4) = 7
no problems, once,
BUT
when there more than one then the problems are "familiar" :rolleyes: from those earlier mentioned. It seems that .... only guessing, that the compiler is allergic to SetPoint :p
of course not so, but again there is something here that I do not grasp...
OR
do I miss something from the hole picture here
Here is the code with more @ MOVE?CPs:

@ MOVE?CP 21746FD9h, _SetPoint
SetPoint(4) = 7
@ MATH_DIV _SetPoint, _Position, _Error
@ MOVE?CP 21756FD9h, _SetPoint
SetPoint(4) = 6
@ MATH_DIV _SetPoint, _Position, _Error
@ MOVE?CP 21766FD9h, _SetPoint
SetPoint(4) = 5
@ MATH_DIV _SetPoint, _Position, _Error
@ MOVE?CP 21776FD9h, _SetPoint
SetPoint(4) = 4
@ MATH_DIV _SetPoint, _Position, _Error

Darrel Taylor
- 13th December 2010, 20:49
There's no way for me to tell what's happening, since your snippets all compile.

If I had your whole program, maybe I could see what's going on.

keymuu
- 13th December 2010, 22:51
There's no way for me to tell what's happening, since your snippets all compile.

If I had your whole program, maybe I could see what's going on.


Thanks Darrel,

the hole program is big, but here it is attached:

Maybe you can see with one small glance what is the cause of the error, the origin (that is me, but...:rolleyes:). I sure wish to find the problem, what is causing this mysterious behavior.

Nevertheless, maybe you can see the problem with one glance...

Darrel Taylor
- 14th December 2010, 01:52
I don't think the file was accepted.
Try adding a .txt extension.

keymuu
- 14th December 2010, 09:35
I don't think the file was accepted.
Try adding a .txt extension.

Yep... :(

Did not check it until now. Let's hope it comes through this time.

Darrel Taylor
- 14th December 2010, 15:38
DEFINE RESET_ORG 1000h ' Room for Microchip USB Bootloader

That's 4K, +28K = 32K
The chip is FULL.

keymuu
- 15th December 2010, 00:56
DEFINE RESET_ORG 1000h ' Room for Microchip USB Bootloader

That's 4K, +28K = 32K
Oops :eek:
TRUE ! and thank you for pointing out that.

Didn't know/understand that when the number shown in the lower left corner (Success 28676 : bytes used) of MicroCode Studio did not include those 4k! That explains now really a lot.
Obviously the program is too big :mad:

There is not a big brother to 18F4550, that would be otherwise like but with 48 or 64 k of program memory? Or is there?

USB is the reason in the first place to choose 18F4550...

Then of course ...
when it is not possible to continue with a processor with only 32k of program mem then..
How about... PIC18F4620 with 64k of program memory and almost pin equivalent (with 4550) but unfortunately without USB :( but then again, I wonder how much code it would take if one would integrate USB/UART circuit FT232 unit along with 18F4620.

I suppose that it (FT232) has been used all around the world,
so I will try to look around and see what kind of experience people has...

Any experience with FT232? My only fear is that the "driver" for it in PIC is too big, or maybe the algorithm will for a working system consumes most time, I don't know.
What other troubles would one expect with such a plan?

Let's play with the idea that it already done and working (18F4620&FT232) so would it be possible to use that system with some kind of a bootloader?

Darrel Taylor
- 15th December 2010, 06:26
I don't know what the Microchip bootloader is compatible with.
But the MPS shows these USB parts with 64K or more.

http://www.pbpgroup.com/files/USB_64plus.GIF

The chips listed that are not supported in PBP 2.60A, will be added in PBP 2.60B.

Note: They are all 3V parts.

Otherwise, you can make your own FT232 equivalent with any USB PIC chip using CDC.
The 13K50 is probably the smallest @ 20 pins, and is 5V.

keymuu
- 16th December 2010, 01:52
I don't know what the Microchip bootloader is compatible with.
But the MPS shows these USB parts with 64K or more.

http://www.pbpgroup.com/files/USB_64plus.GIF

The chips listed that are not supported in PBP 2.60A, will be added in PBP 2.60B.

Note: They are all 3V parts.

Otherwise, you can make your own FT232 equivalent with any USB PIC chip using CDC.
The 13K50 is probably the smallest @ 20 pins, and is 5V.
Thank you Darrel,

thank you indeed, this looks really promising.
It is really nice from you to present such a table. :)
Where on earth did you find that? (rhetorical question)

I looked for something like that but did not find anything
besides what I already told (18F4620/FT232).

Do you have an Crystal ball?
Can you tell when PBP 2.60B will be released?
Within 3, 6 or 9 months?

There is of course some problems when changing from a 5V processor to a 3V processor when the environment is 5V. However, that is not a big problem when there are enough pins that are 5V tolerant that can work directly with other 5V circuits.

But on the other hand, I have not done that before,
could you please give some good advice how to do it?
Using two regulators one 3V and one 5V? The 3V reg could be small, something 500mA or even less, maybe just 100mA.
Using only 5V and a Zener diode (very old way of thinking)?
Or maybe some other approach?

Everyone in that list has enough program memory (64k or more) and a RTCC. Meaning that I can discard the I2C RTC and freeing such area of the board, nice. And changing the LCD to an I2C device (Melabs Serial LCD. Is it goog?) there is a possibility to choose 18F26J50 that is a only 28 pin device, so the board is not so populated any more as it is at the moment. Very promising indeed :p

Darrel Taylor
- 16th December 2010, 15:48
The list is straight out of the Microcontroller Product Selector (MPS).
http://www.microchip.com/productselector/MCUProductSelector.html

Select 8-bit Architecture, move the left Flash slider to 64, then click USB.

I believe 2.60B will be released in January.
Normally they wait till there have been several issues fixed, but there haven't been any in 2.60A.
So Charles has been talking about releasing it because there's so many new chips.

There are several things to think about regarding 3V/5V.
But that topic is beyond the scope of N-Bit_Math, so you should probably create a new thread for it.