PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Übergabe von Werten an eine SUB per Byval



mat-sche
22.11.2008, 18:16
Hallo @ All,

ich brauch mal wieder Eure Hilfe! Folgendes wollt ich machen:
1.
*Dim Temperaturbyte(4) As Byte At Temp1 Overlay
*Declare Sub Master_transmit(byval Slave_adress As Byte , Komando1 As Byte )

2.
ich lasse mir eine Temperatur als Single geben (Temp1) und lege darüber mit Overlay das Temperaturbyte

3.
Slave_adress = &H6A
Komando1 = Temperaturbyte(1)
Call Master_transmit(slave_adress , Komando1)
hier soll die Sub aufgerufen werden in der die 4 einzelnen Byte (Temperaturbyte(4) ) per TWI übertragen werden

4. nun wird die Sub aufgerufen und die Daten werden übergeben:

Sub Master_transmit(byval Slave_adress As Word , Komando1 As Byte )
Twi_mst_buff(1) = Komando1
Twi_mst_addr = Slave_adress
Twi_mt_cntr = 4
Twi_mt_data = Varptr(twi_mst_buff(1))
Twi_mr_cntr = 0
Gosub Run_wait_master

Die TWI Übertragung ist die aus der Wiki TWI-Master/Slave. bei mir besteht das Problem, dass die Sub aufgerufen wird, jedoch werden leider nur 4x Nullen zum Master übergeben. Irgend wie wird die Info vom Temperaturbyte nicht an die Sub gesendet.

Hat jemand nen Plan wie ich dies hinbekomme?

Danke und Gruß
MAT

Rage_Empire
22.11.2008, 19:21
versuchs mal nicht mit byval sondern mit byref

for_ro
23.11.2008, 00:24
Komando1 = Temperaturbyte(1)
Call Master_transmit(slave_adress , Komando1)

Sub Master_transmit(byval Slave_adress As Word , Komando1 As Byte )
Twi_mst_buff(1) = Komando1
Twi_mst_addr = Slave_adress
Twi_mt_cntr = 4
Twi_mt_data = Varptr(twi_mst_buff(1))
Twi_mr_cntr = 0


Hallo, wenn ich deine Sub richtig lese, sollen hier die 4 byte übertragen werden, auch wenn du nur das erste Byte angibst. Das funktioniert aber nur, wenn eine Referenz auf das erste Element des Arrays angegeben wird. Also Rage_empire hat schon recht, dass du das mit byref übergeben musst.
Nur bringt das nichts, wenn du vor dem Call erst noch die Variable umsetzt. Da Komando1 nur eine Byte Variable ist, wird mit
Komando1 = Temperaturbyte(1) nur das erste Byte genommen und dessen Wert - nicht die Speicherstelle - in Komando1 gesetzt.
Was du machen musst, ist den Call ändern auf
Call Master_transmit(slave_adress , Temperaturbyte(1))
Mit byref übergibst du dann die Speicherstelle, an der das erste Byte der Overlay variable liegt.
In der Sub musst du dann genauso vorgehen, denn mit
Twi_mst_buff(1) = Komando1
verlierst du wieder die Speicherposition und übergibst nur den Wert. Damit setzt du dann eine ganz andere Adresse im Befehl
Twi_mt_data = Varptr(twi_mst_buff(1)).
Twi_mt_data soll ja tatsächlich auf das erste Byte der Single Variable zeigen.

Gruß

Rolf

mat-sche
23.11.2008, 09:51
Moin moin,

erst einmal Dank für die Antworten!
@Rolf:

Gestern hab ich mir das schon überlegt das ich ich byval nicht nehmen kann und es byref heißen muss, wie gedacht auch getan. Leider ohne Erfolg!
Nun habe ich Deine Erklärung gelesen und ich ahne mein Problem, nur leider komme ich nicht mit Deiner Erklärung zurecht. Ich wollte die Sub nutzen für mehrere unterschiedliche Übertragungen und "Ursprungsorte" von Variablen.


In der Sub musst du dann genauso vorgehen, denn mit
Twi_mst_buff(1) = Komando1
verlierst du wieder die Speicherposition und übergibst nur den Wert. Damit setzt du dann eine ganz andere Adresse im Befehl
Twi_mt_data = Varptr(twi_mst_buff(1)).
Twi_mt_data soll ja tatsächlich auf das erste Byte der Single Variable zeigen.


Könntest Du mir dazu mal ein Beispiel aufzeigen.
Wie kann ich die Variable so übergeben das ich "Twi_mst_buff(1) = Komando1 " nutzen kann. Hintergrund ist der, dass ich so aus anderen Programmschritten nur über Call die Adresse und den Wert übergeben brauche und dann in die Senderoutine springen muss, um diese dann zu senden.
Gruß MAT

for_ro
23.11.2008, 11:17
Hallo MAT,
in deinem Programm sehe ich im Moment noch nicht die eigentliche Übertragung, nur die Vorbereitungen dafür.
Die Variable Twi_mt_data scheint auf die erste Adresse der zu übertragenden Daten verweisen zu müssen, daher das VARPTR.
Die Variable Twi_mt_cntr scheint die Anzahl der zu übertragenden Bytes zu halten.
Dann musst du die Sache etwa so angehen

Declare Sub Master_transmit(byref Slave_adress As Byte , Byref Komando1 As Byte )
...
Call Master_transmit(slave_adress , temperaturbyte(1))
...
Sub Master_transmit(byref Slave_adress As Word , byref Komando1 As Byte )
...
Twi_mt_data = Varptr(Komando1)
...
End Sub

In dem Call wird dann die Speicheradresse von temperaturbyte(1) übergeben, die du in der Sub unter dem Name Komando1 benutzen kannst. Mit Varptr() holst du dann die Speicherstelle von Komando1 (also tatsächlich die von Temperaturbyte(1)) und übergibst sie an Twi_mt_data.

Deine ganze Überlegung muss dahin gehen, dass du am Ende keine Werte sondern eine Speicherstelle übergeben willst. Entsprechend darfst du auch keine dieser Variablen auf den "Wert" einer anderen setzen, sondern immer nur auf die Speicherstellen. Dies wird mit Byref und mit Varptr() gemacht.
Um zu prüfen, ob die Übergaben funktionieren, kannst du auch die Speicherstellen ausgeben oder Printen lassen (also Varptr() der Variable) und dann mit dem Variablen-Layout in Program -> Show_Result vergleichen. Dort muss dann die gleiche Speicherstelle stehen.

Jetzt klarer?

Gruß

Rolf

mat-sche
23.11.2008, 11:38
Hallo Rolf

jup und vielen Dank!!!
Es war mir schon klar, dass ich immer nur einen Zeiger auf die entsprechende Speicherstelle weitergeben muss, nur war mir immer nicht klar wie es in Bascom zu proggen ist :).
Also Dank noch mal!

Gruß MAT

mat-sche
23.11.2008, 11:52
@ Rolf,

Klasse.... so solltes es funktionieren => bestens!

Gruß MAT