PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Übergabe von Long und Single Variablen klappt nicht



Onkelono
11.02.2005, 12:26
Hallo Zusammen,
ich versuche gerade Long und Single Variablen an eine Subprozedur zu übergeben.
Das funktioniert aber nicht ich bekomme falsche Werte.
Hier das Testprog:


$regfile = "M32DEF.DAT"
$crystal = 8000000


Declare Sub Testlong(byval Wert1 As Long , Byval Wert2 As Long)
Declare Sub Testsingle(byval Wert1 As Single , Byval Wert2 As Single)


'LCD
Config Lcdpin = Pin , Db4 = Portc.4 , Db5 = Portc.5 , Db6 = Portc.6 , Db7 = Portc.7 , E = Portc.2 , Rs = Portc.3
Config Lcd = 16 * 4


Dim Clong1 As Long
Dim Clong2 As Long

Dim Csingle1 As Single
Dim Csingle2 As Single

Dim Tlong As Long
Dim Tsingle As Single



Do


Cls
Locate 1 , 1
Clong1 = 12545
Clong2 = 55555
Call Testlong(clong1 , Clong2)
Locate 2 , 1
Call Testlong(33333 , 2)


Locate 3 , 1

Csingle1 = 12545
Csingle2 = 55555
Call Testsingle(csingle1 , Csingle2)


Locate 4 , 1
Call Testsingle(33.45 , 1223.4)

Wait 10
Loop



Sub Testlong(byval Wert1 As Long , Byval Wert2 As Long)

Tlong = Wert1
Lcd Tlong

Tlong = Wert2
Lcd " " ; Tlong

End Sub

Sub Testsingle(byval Wert1 As Single , Byval Wert2 As Single)

Tsingle = Wert1
Lcd Tsingle

Tsingle = Wert2
Lcd " " ; Tsingle

End Sub



Als Werte bekomme ich
0 -1
0 138412032
-0.0 0.0
-0.0 -0.0

zurück.

Ist die Übergabe von Long und Singles in Bascom nicht möglich?

Gruß Ingo

PicNick
11.02.2005, 12:51
Hi, Ingo
lcd funktioniert wie print, d.h sowas wie long u. single mußt du mit
STR(single) od. STR(long) übergeben.
Versuch das mal

oe9vfj
11.02.2005, 13:44
Hallo Ingo,

Du musst die Stacks entsprechend einrichten. Die Variablen werden bei der byval Option in einem eigenen Speicherbereich kopiert und dort übergeben, dem sogenannten Frame. Die Adressen zu den übergebenen Variablen werden in den Softstack gespeichert. Die Rücksprungadressen aus den Sub-Routinen und Funktionen sind auf dem HW-Stack. Diese Speicherbereiche befinden sich am Ende des SRAM.

Gehe in die Optionen / Compiler / Chip und setze die
Framesize auf 48
Softstack auf 16
HW-Stack auf 32

dann funktioniert Dein Programm, wie Du es geschrieben hast. Weiters hast Du noch jeweils einige Bytes an Reserve.

16 Byte aus dem Frame werden ausserdem noch für Umwandlung von nummerischen Variablen in Strings für Ausgabe bei Print und LCD verwendet.

Schau mal in der Hilfe unter $DBG nach.
Mit diesem Feature kannst Du die Belegung in diesen Speicherbereichen abschätzen.

Füge das Statement $DBG am Programmanfang ein. Lass das Programm im Simulator laufen. Dann kannst in der SRAM Ansicht nachsehen, wieviel Bytes vom jeweiligen Bereich verwendet wurden. Das sind alle Bytes, welche in der ASCII-Darstellung nicht mehr den Initialiserungswert (durch $DBG) F für Frame, S für SoftStack und H für HW-Stack haben.

Viele Grüße Josef

Onkelono
11.02.2005, 22:21
Hallo Josef,
Hallo Zusammen,
der Hinweis auf den Softstack hat funktioniert.
Jetzt klappts!

Vielen Dank für die Tipps

12.02.2005, 08:34
wie kommst du auf die werte für framesize softstack und hwstack? mein programm läuft nicht im simulator, der macht nur undefinierte sachen.

oe9vfj
14.02.2005, 13:00
Hallo,

in diesem Falle habe ich das in BASCOM-AVR eingebaute Hilfsmittel $DBG verwendet.
Dieses initialisiert an der Stelle, wo es im Programm vorkommt, die 3 Speicherbereiche Frame, SoftStack und HW-Stack mit den ASCII-Zeichen F (für Frame), S (für Softstack) und H (für HW-Stack). Daher muss dieses Statement ziemlich am Anfang des Programmes eingefügt werden vor der eigentlichen Benutzung dieser Bereiche durch das Programm selbst.

Nach dem Testen des Programms im Simulator ist in der SRAM-Darstellung (End des SRAM-Bereiches des Chips) anhand der überschriebenen Bytes der Bedarf im jeweiligen Stack-Bereich ersichtlich.


Grundsätzlich werden die Bereiche verwendet für:

Frame:
Konvertierung Nummerische Variable in ASCII-Ausgabe bei Print und LCD
In Sub und Function übergebene Variable mit byVal
In Sub und Functions dimensionierte LOCALe Variable

Softstack:

Addressen zu den im Frame abgelegten Variablen ( 2 Bytes pro Addresse)

HW-Stack:

Rücksprungaddressen aus Unterprogrammen ( 2 Bytes pro Rücksprungadresse)
Retten von CPU-Registern in Assembler-Routinen
Retten von CPU-Registern bei Aufruf von Interrupt-Service-Routinen


Für die oben erwähnte Konvertierung von Num. Variablen in Strings werden fix die ersten 16 Bytes des Frame verwendet (bei DOUBLE sind es 24 Byte). Der andere Bedarf sich nach der Größe der abgelegten Variablen.

Manche Assembler-Routinen legen auch interne Byte oder Word-Werte im Softstack ab, da dies gegenüber der Standardmethode (im Frame) Speicherplatz und Ausführungszeit spart.

Der HW-Stack wird besonders bei ISR-Routinen, falls nicht mit der Option NOSAVE gearbeitet wird, stark beansprucht (30 Bytes).

Der Bedarf richtet sich nach der Sub oder Function mit den höchsten Werten, bei verschachtelten Aufrufen von Sub oder Function sind die jeweiligen Werte zu addieren. Bei ISR-Routinen ist auch noch dieser Bedarf beim HW-Stack zu addieren. Falls nicht in der ISR-Routine verschachtelter Interrupt-Aufruf zugelassen wird, genügen hier die Werte der ISR-Routine mit dem höchsten Bedarf.

Eine genaue theoretische Abschätzung ist kaum möglich, da selten bekannt, wie die BASCOM-Befehle selbst unter Umständen die Stacks belegen.

Zudem ist es noch möglich, mit $DBG und DBG (siehe Hilfe-Datei) die Werte im Chip zur Laufzeit zu ermitteln.
Eine schnelle Abschätzung ist auch im Simulator /Reiter UP mit den Differenzen von SoftStack - SoftStack Min, HW Stack - HW Min und Frame max - Frame Pointer möglich. Die Werte hier sind allerdings in Hexadezimal angegeben.

Abschließend ist zu sagen, dass eine zu kleine Einstellung dieser Stacks oft die Ursache von Programmabstürzen bzw. unerklärlichem Verhalten des Programmes ist und daher entsprechend ausreichend dimensierte Stacks von eminenter Bedeutung ist.

Viele Grüße Josef