Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 06:34 05 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Sub is auto-erasing results....

Author Message
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 03:57pm 01 Oct 2014
Copy link to clipboard 
Print this post

I have been playing with this most of the afternoon, and I can't get the results I want from the sub.

Here is the main code: (bear in mind, this is just for testing purposes, so is only supposed to return the expected result, not actually DO anything with those results)

[code]
FW:
FRAM (1,5000,"Hello.")
Print M,A,D$
End

FR:
FRAM (0,5000)
Print M,A,D$
End
[/code]

And the subroutine:

[code]
Sub FRAM (M,A,D$) 'Mode, Address and Data parimeters
If M<0 Or M>1 Then FRAM_FLAG=1
I2C open 400,100
FRAM_FLAG=0
If M=1 Then
A2=A+Len(D$):Y1=1:A3=A2+1
For Y=A To A2
I2C write &B1010000,0,3,Y\256,Y Mod 256,Asc(Mid$(D$,Y1,1))
Y1=Y1+1
Next Y
I2C write &B1010000,0,3,A3\256,A3 Mod 256,13 'CR marker
I2C Close
EndIf
If M=0 Then
D$=""
I2C write &B1010000,0,2,A\256,A Mod 256 'Set FRAM start address
Do
I2C read &B1010000,1,1,B 'Suck a byte from FRAM and hold onto bus
D$=D$+Chr$(B)
If B=13 Then Exit Do
Loop
I2C Close
EndIf
End Sub
[/code]

From the command prompt, if I enter GOTO FW or GOTO FR, BOTH return zeros as the results, which is not what is expected - it should be 1 5000 Hello. for the FW test, and 0 5000 Hello. for the other test.

Now, if I change the sub to print the parameters as it moves through the sub, they are there as expected, when expected, but they are auto-zeroed once the sub exits - I don't get what I am doing wrong.

For example, if I use this code here for the sub:

[code]
Sub FRAM (M,A,D$) 'Mode, Address and Data parimeters
If M<0 Or M>1 Then FRAM_FLAG=1
I2C open 400,100
FRAM_FLAG=0
If M=1 Then
A2=A+Len(D$):Y1=1:A3=A2+1
For Y=A To A2
I2C write &B1010000,0,3,Y\256,Y Mod 256,Asc(Mid$(D$,Y1,1))
Y1=Y1+1
Next Y
I2C write &B1010000,0,3,A3\256,A3 Mod 256,13 'CR marker
I2C Close
Print M,A,D$
EndIf
If M=0 Then
D$=""
I2C write &B1010000,0,2,A\256,A Mod 256 'Set FRAM start address
Do
I2C read &B1010000,1,1,B 'Suck a byte from FRAM and hold onto bus
D$=D$+Chr$(B)
If B=13 Then Exit Do
Loop
Print M,A,D$
I2C Close
EndIf
End Sub
[/code]

...then M=1 or 0 depending on FW or FR, and A=5000, and D$="Hello."

But the second the sub ends, and returns to the next line of either FW or FR, the values are all zero again.



Can anyone help me work out what I am doing wrong?

EDIT: FECK, FECK, FECK, FECK!!!!

From page 28 of the manual:

[quote]
The arguments act like ordinary variables but they exist only within the subroutine and will vanish when the subroutine ends.[/quote]

I was still thinking in MaxiMite mode, which does not forget variables, and they are available again OUTSIDE the sub, but the MicroMite obviously does not do this, for memory reasons.

So, the question now becomes, is there any way to change that behaviour?

...I guess on the full-size MaxiMite, this problem would not surface, and I would get the results I wanted.

Interestingly, I made a very simple test sub:

[code]
Sub XXX (A,B,C)
A=A*2:B=B*2:C=C*2
End Sub
[/code]

...and called it with:

[code]
ONE:
XXX (2,4,6)
Print A,B,C
End
[/code]

...and I get the results back from this one: 2,8,12......


Edited by Grogster 2014-10-03
Smoke makes things work. When the smoke gets out, it stops!
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 04:14pm 01 Oct 2014
Copy link to clipboard 
Print this post

OK - Problem fixed!

NEW caller test routines:

[code]
FW:
FRAM (1,5000,"Hello.")
Print M1,A1,D1$
End

FR:
FRAM (0,5000)
Print M1,A1,D1$
End
[/code]

...and NEW main sub:

[code]
Sub FRAM (M,A,D$) 'Mode, Address and Data parimeters
If M<0 Or M>1 Then FRAM_FLAG=1
I2C open 400,100
FRAM_FLAG=0
If M=1 Then
A2=A+Len(D$):Y1=1:A3=A2+1
For Y=A To A2
I2C write &B1010000,0,3,Y\256,Y Mod 256,Asc(Mid$(D$,Y1,1))
Y1=Y1+1
Next Y
I2C write &B1010000,0,3,A3\256,A3 Mod 256,13 'CR marker
M1=M:A1=A:D1$=D$
I2C Close
EndIf
If M=0 Then
D$=""
I2C write &B1010000,0,2,A\256,A Mod 256 'Set FRAM start address
Do
I2C read &B1010000,1,1,B 'Suck a byte from FRAM and hold onto bus
D$=D$+Chr$(B)
If B=13 Then Exit Do
Loop
M1=M:A1=A:D1$=D$
I2C Close
EndIf
End Sub
[/code]

Make a copy of the local argument variables, and check THESE after the sub ends.

You keep on learning new tricks in this game of programming......


Edited by Grogster 2014-10-03
Smoke makes things work. When the smoke gets out, it stops!
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 5913
Posted: 05:10pm 01 Oct 2014
Copy link to clipboard 
Print this post

In the subroutine:
If M<0 Or M>1 Then FRAM_FLAG=1
I2C open 400,100
FRAM_FLAG=0


FRAM_FLAG will always end up as zero so setting it to 1 in the first line is no use.

But you don't seem to use it anywhere anyway......

Jim

VK7JH
MMedit   MMBasic Help
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 06:33pm 01 Oct 2014
Copy link to clipboard 
Print this post

FRAM_FLAG is set to one, if the M parameter is less then zero, or greater then 1. I have tested that, and it seems to work. The idea being that if you try to select a mode that is not 0 or 1, the sub exits with this flag set. The same thing applies to FRAM addresses that are less then one, or more then 32767(address zero is not used). The code example Jim quotes was missing the :End Sub on the end of the line - my mistake there!

Updated callers:

[code]
FW:
FRAM (1,5000,"Hello.")
Print M,A,D$
If FRAM_BA=1 Then Print "Bad write address."
End

FR:
FRAM (0,5000)
Print M,A,D$
If FRAM_BA=1 Then Print "Bad read address."
If FRAM_BM=1 Then Print "Bad mode."
End
[/code]

Updated sub:

[code]
Sub FRAM (M1,A1,D1$) 'Mode, Address and Data parameters
If M1<0 Or M1>1 Then FRAM_BM=1:End Sub
If A1<1 Or A1>32767 Then FRAM_BA=1:End Sub
I2C open 400,100
FRAM_BM=0:FRAM_BA=0
If M1=1 Then
A2=A1+Len(D1$):Y1=1:A3=A2+1
For Y=A1 To A2
I2C write &B1010000,0,3,Y\256,Y Mod 256,Asc(Mid$(D1$,Y1,1))
Y1=Y1+1
Next Y
I2C write &B1010000,0,3,A3\256,A3 Mod 256,13 'CR marker
M=M1:A=A1:D$=D1$
I2C Close
EndIf
If M=0 Then
D$=""
I2C write &B1010000,0,2,A1\256,A1 Mod 256 'Set FRAM start address
Do
I2C read &B1010000,1,1,B 'Suck a byte from FRAM and hold onto bus
D$=D$+Chr$(B)
If B=13 Then Exit Do
Loop
M=M1:A=A1
I2C Close
EndIf
End Sub
[/code]

This version swaps around what parameter variables are passed to the sub, so that the more "Normal" variables can be shown at the end of the sub.
Edited by Grogster 2014-10-03
Smoke makes things work. When the smoke gets out, it stops!
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3165
Posted: 05:21am 02 Oct 2014
Copy link to clipboard 
Print this post

  Grogster said  I was still thinking in MaxiMite mode, which does not forget variables, and they are available again OUTSIDE the sub, but the MicroMite obviously does not do this, for memory reasons.

Sorry but the Maximite and Micromite are exactly the same in this regard. The variables in the parameter list of a subroutine are always local to the sub.

BUT, if you used variables when you called the subroutine then any changes to the local variables will be copied back to the variables used when you called the sub.

For example:

X = 1
Y = 5000
z$ = "Hello."
FRAM (X, Y, Z$)
Print X,Y,Z$

Would give you what you wanted as X, Y and Z$ would be updated to reflect any changes made to M, A and D$ in the sub. This is a handy way of getting data out of a sub but passing data by reference (which this is) can get confusing (I wish that I never implemented it). Perhaps global variables would be simpler and less confusing.

Geoff
Geoff Graham - http://geoffg.net
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 12:05pm 02 Oct 2014
Copy link to clipboard 
Print this post

I've just looked closer at my MaxiMite code, and the reason it "Appeared" to be working there, and not on the MicroMite, was that in my MaxiMite code, I don't reference the variables I want OUTSIDE the sub, in the parameter list - exactly as you say.

As I was using the likes of X,Y,Z as parameters, and then changing A,B,C kind of thing, all appeared to work as expected. I made a mistake here, in that I used A,B,C as parameters, then tried to change those same variables inside the sub, so they then vanished when the sub exited - just as the manual said would happen, I just did not pick up on my mistake before I posted this flippin' thread!

Human error!
Smoke makes things work. When the smoke gets out, it stops!
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024