PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] Frage zum Thema Arrays in Bascom



Kampi
24.06.2012, 14:52
Hallo Forum,

ich programmiere gerade etwas meinen CAN-Bus und bin dabei auf ein kleines Hindernis gestoßen.
Ich habe dieses Unterprogramm welches ein Datenpaket verschicken soll:



Sub Send_can(byval Daten(8) As Byte , Byval Tx_identifier As Long , Byval Ex_id_enable As Byte)

Local Tx_low As Integer
Local Tx_high As Integer
Local Id_high As Byte
Local Id_low As Byte

'Prüfen ob die Nachricht mit einem 29-Bit Identifier versendet werden soll oder nicht
If Ex_id_enable = 0 Then

'Prüfen ob der Identifier die richtige Länge hat
If Tx_identifier > 2047 Then

Print "Identifier beträgt " ; Tx_identifier ; " und ist damit zu groß. Maximaler Wert ist 2047!"
Error = 1
Return

Else

'Identifier einstellen
Tx_low = Tx_identifier 'Speichert den Filter in zwei Variablen und schiebt
Tx_high = Tx_identifier 'den Wert um 5 Stellen nach rechts um die drei
Shift Tx_low , Left , 5 ' niedrigsten Bits zu gewinnen. Dasselbe passiert für
Shift Tx_high , Right , 3 'die acht höchsten Bits. Anschließend werden die Werte
'in die passenden Register geschrieben.
Id_high = Tx_high
Id_low = Tx_low

'ID in die ID-Register schreiben
Write_register Txb0sidh , Id_high
Write_register Txb0sidl , Id_low

'Daten in die Datenregister schreiben
Write_register Txb0dlc , 8
Write_register Txb0d0 , Daten(1)
Write_register Txb0d1 , Daten(2)
Write_register Txb0d2 , Daten(3)
Write_register Txb0d3 , Daten(4)
Write_register Txb0d4 , Daten(5)
Write_register Txb0d5 , Daten(6)
Write_register Txb0d6 , Daten(7)
Write_register Txb0d7 , Daten(8)

Reset Cs
Spdr = Spi_rts0 'Übertragung auslösen
Do
Loop Until Spsr.spif = 1
Set Cs

End If

Elseif Ex_id_enable = 1 Then

Else

Print "Error. Unbekannter Identifier!"
Error = 2
Return

End If

End Sub


Wie zu erkennen ist, ist oben in dem Funktionskopf eine Variable mit dem Namen "Daten" als 8 Byte Array angelegt worde.
Meine Grundidee war es, dass ich ein 8-Byte Array in die Funktion übergebe und das von diesem 8-Byte Array jede Stelle in ein anderes Register zum Senden kommt (so wie es in dem Unterprogramm bereits gemacht worden ist).
Sprich ich übergebe das Array in das Unterprogramm ein 8-Byte Array und er speichert das Array dann in der lokalen Variable "Daten" ab, welche ebenfalls ein Array ist.
Nur das Übergeben klappt bei mir noch nicht so ganz....wie rufe ich das Unterprogramm auf und übergebe das komplette Array, sodass es versendet werden kann?

Wenn ich schreibe

Send_can Test(2) , 5 , 0

wird ja nur der Wert welcher an Stelle 2 des Arrays Test steht, übergeben.
Es soll aber der komplette Inhalt von Test übergeben werden und dann richtig in dem Unterprogramm gespeichert werden.
Sprich Stelle 1 von "Test" an Stelle 1 von "Daten", Stelle 2 von "Test" an Stelle 2 von "Daten" usw.
Kann mir da jemand einen kleinen Denkanstoß geben?
Danke schonmals :)

for_ro
24.06.2012, 15:27
Hallo Daniel,
schau mal in der Hilfe unter "Declare Sub". Dort ist das eigentlich ganz gut erklärt und es gibt auch ein Beispiel.
Melde dich dann noch mal, wenn du damit nicht klarkommst.

MagicWSmoke
24.06.2012, 15:32
Hatte ich mal zur Demonstration geschrieben:

$Regfile = "m32def.dat"
$Crystal = 8000000
$hwstack = 32
$swstack = 8
$framesize = 24

Const ArSz = 5
Dim Ar(ArSz) As Byte
Dim Sz As Byte
Dim Rslt As Word

Declare Function Addall(ArToAdd As Byte , ByVal ArSize As Byte) As Word

Ar(1) = 10
Ar(2) = 25
Ar(3) = 9
Ar(4) = 21
Ar(5) = 66

Rslt = Addall(Ar(1) , ArSz)
Print Rslt

End

Function Addall(ArToAdd As Byte , ByVal ArSize As Byte) As Word
Local idx As Byte
Local rt As Word
rt = 0
For idx = 1 to ArSz
rt = rt + ArToAdd(idx)
Next
Addall = rt
End Function
Du darfst nicht byval übergeben, sondern byref, das ist Standard und muss nicht extra dazu geschrieben werden.
Byref ist einen Zeiger und für den Zugriff auf's ganze Array muss der auf das erste Arrayelement zeigen, deswegen Addall(Ar(1) , ArSz).
Eine implizite Übergabe per byval is soweit ich weiß nicht vorgesehen, so wie Dein Code aussieht auch nicht nötig. Du kannst ohne Weiteres mit dem Originalarray arbeiten, solange es durch die aufgerufene Routine nicht ungewollt verändert wird.

Kampi
24.06.2012, 15:45
Danke euch beiden erstmal für die Hinweise!


Hatte ich mal zur Demonstration geschrieben:

$Regfile = "m32def.dat"
$Crystal = 8000000
$hwstack = 32
$swstack = 8
$framesize = 24

Const ArSz = 5
Dim Ar(ArSz) As Byte
Dim Sz As Byte
Dim Rslt As Word

Declare Function Addall(ArToAdd As Byte , ByVal ArSize As Byte) As Word

Ar(1) = 10
Ar(2) = 25
Ar(3) = 9
Ar(4) = 21
Ar(5) = 66

Rslt = Addall(Ar(1) , ArSz)
Print Rslt

End

Function Addall(ArToAdd As Byte , ByVal ArSize As Byte) As Word
Local idx As Byte
Local rt As Word
rt = 0
For idx = 1 to ArSz
rt = rt + ArToAdd(idx)
Next
Addall = rt
End Function
Du darfst nicht byval übergeben, sondern byref, das ist Standard und muss nicht extra dazu geschrieben werden.
Byref ist einen Zeiger und für den Zugriff auf's ganze Array muss der auf das erste Arrayelement zeigen, deswegen Addall(Ar(1) , ArSz).
Eine implizite Übergabe per byval is soweit ich weiß nicht vorgesehen, so wie Dein Code aussieht auch nicht nötig. Du kannst ohne Weiteres mit dem Originalarray arbeiten, solange es durch die aufgerufene Routine nicht ungewollt verändert wird.

Danke der Tipp mit Byref war die Lösung.
Nachdem ich das Byval durch Byref ersetzt habe klappt es. Genau so eine Zeigeroperation habe ich gesucht. Wusste nur nicht wo ich die finde ;)
Vielen Dank nochmals an euch!

MagicWSmoke
24.06.2012, 15:51
Genau so eine Zeigeroperation habe ich gesucht. Wusste nur nicht wo ich die finde ;)
Die hattest Du schon immer :D
Denn meistens wirst Du in Deinen Subs nicht mit byval übergeben haben und dann waren's per Default immer Zeiger.

Kampi
24.06.2012, 16:01
Die hattest Du schon immer :D
Denn meistens wirst Du in Deinen Subs nicht mit byval übergeben haben und dann waren's per Default immer Zeiger.

Da hast du schon recht :)
Nur ich habe da nicht drauf geachtet
Ich stell das Thema damit mal auf erledigt :)