Archiv verlassen und diese Seite im Standarddesign anzeigen : ungewollt geänderte Variable in einer function - spuk?
mathias172
01.01.2008, 03:44
Hallo und Frohes Neues!
Ich kämpfe hier mittlerweile seit 2 Tagen mit einer Kleinigkeit herum, die in anderen Sprachen vielleicht in 2 Minuten erledigt ist aber irgendwie brauche ich mal eine kleine Aufklärung.
Ich versuche eine Kleine Routine zu schreiben, der ich einen Prozentwert übergebe. Ich möchte dann hinterher den Prozentwert als Balken auf einem Display ausgegeben haben. Ein ähnliches Programm habe ich hier bereits entdeckt, aber der Stolz... ;)
Hier die Deklaration:
Declare Function Ausgabe(byval Prozent As Byte) As String
Hier meine Funktion:
Function Ausgabe(byval Prozent As Byte)
Local Temp As Integer
Local Temp2 As Word
Local Temp3 As String * 20
Temp = Prozent / 10
For Temp2 = 1 To Temp Step 1
Temp3 = Temp3 + "#"
Next
Ausgabe = temp3
End Function
Mein Problem: Ich kann mit der Programmierung meiner Routine nicht fortfahren weil die übergebenen Werte ständig falsch ankommen.
Beispiel:
Ich rufe die Funktion auf: ausgabe(125)
Der Wert 125 kommt so momentan an. Fein.
Ändere ich die Funktion mit einer Kleinigkeit ab funktioniert nix mehr:
Function Ausgabe(byval Prozent As Byte)
Local Pe As Word
Local Temp As Integer
Allein die Deklaration von Pe als Word führt dazu, dass sich der Wert von "Prozent" auf den vollkommen unklaren Wert von 59 ändert.
Das kann und darf doch wohl auf keinen Fall sein, oder habe ich etwas übersehen? Ich hätte nie gedacht, dass ich mich mal an so einer Kleinigkeit so festbeissen würde.
Beste Grüße,
Mathias[/php]
Hi,
ich würde das mit ner Sub machen:
$regfile = "m8def.dat" ' specify the used micro
$crystal = 1000000
$baud = 4800
Declare Sub Get_prozent
Dim Ausgabe As String * 20
Dim Eingabe As Byte
Do
Input "Eingabe: " , Eingabe
Call Get_prozent
Print "Ausgabe: " ; Ausgabe
Loop
End
Sub Get_prozent
Ausgabe = ""
Local Temp As Integer
Local Temp2 As Byte
Temp = Eingabe / 10
For Temp2 = 1 To Temp Step 1
Ausgabe = Ausgabe + "#"
Next
Temp2 = 0
End Sub
Das funktioniert bei mir in Simulator.
roboterheld
01.01.2008, 12:22
....ich würde das mit ner Sub machen: .....
warum nicht eine funktion. wenn die werte richtig übergeben werden funktioniert sie auch.
linux_80
01.01.2008, 13:11
Hallo,
@mathias172
evtl. musst Du Dir mal diese Seite durchlesen:
https://www.roboternetz.de/wissen/index.php/Bascom_Inside
und die Werte im Programm für $swstack und $framesize erhöhen !
mathias172
01.01.2008, 13:15
Hallo Furtion, hallo roboterheld,
mir gehts eigentlich gar nicht um die Lösung meiner Programmieraufgabe, sonder eher darum, dass ich herausbekomme, warum ausgerechnet diese Konstellation nicht funktioniert. So ein Kleinkram kann für eine Menge Verwirrung sorgen wenn man mal ein umfangreicheres Projekt hat.
Könnt ihr dasselbe Problem beobachten wenn ihr die Funktion mal bei euch laufen lasst?
Im Anhang nochmal das komplette Programm (mittlerweile recht zerrupft).
Allein durch die Zeile "Local Pe As Word" ändert sich der Ausgabewert der Funktion obwohl nirgens mit "Pe" gearbeitet wird.
$crystal = 8000000
Config Lcd = 20 * 4 'Anzeigemodus 40 x 4 Zeichen
Config Lcdpin = Pin , E = Portb.6 , Rs = Portb.7 , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E2 = Portb.5
Dim X As Integer , Mini As Byte , Maxi As Byte , Ausgabe As Byte , Teststring As String * 10
Dim A As Long , B As Long
Dim ___lcdno As Byte
Config Servos = 1 , Servo1 = Portc.0 , Reload = 10 , Timer = Timer0
Config Portb = Output
Config Portd = Input
Enable Interrupts
Declare Function Ausgabe(byval Prozent As Byte) As String
___lcdno = 0
Initlcd
Cls
Portd = 1
Mini = 30
Maxi = 160
X = Maxi - Mini
X = X / 2
X = X + Mini
Do
If Pind.0 = 0 Then X = X + 1
If Pind.1 = 0 Then X = X - 1
If Pind.2 = 0 Then X = X + 10
If Pind.3 = 0 Then X = X - 10
Waitms 50
Dim P As Integer , P2 As Integer , Y As Integer
Y = X
P = Maxi - Mini
P = P / 100
P2 = Mini + Y
P = P2 / P
Locate 1 , 1
Teststring = Ausgabe(90)
Servo(1) = X
Loop
End
Function Ausgabe(byval Prozent As Byte)
Local Pe As Word
Local Temp As Integer
Lcd Prozent
Local Temp2 As Word
Local Temp3 As String * 20
Temp = Prozent / 10
For Temp2 = 1 To Temp Step 1
Temp3 = Temp3 + "##"
Next
Ausgabe = Str(prozent) + " " + Temp3
Temp3 = ""
Temp2 = 0
Ausgabe = Str(prozent)
End Function
Hallo Matthias,
Linux_80 hat vermutlich die Problemlösung bereits aufgezeigt. Was hast du denn als Stackwerte eingetragen? Hast du schon versucht, die zu erhöhen?
mathias172
01.01.2008, 16:53
Hello again ;)
Es liegt/lag tatsächlich am swstack. Vielen Dank für die Hilfe.
Ich werde mal meine Zeilen entwirren und dann nochmal posten. Vielleicht kann ja mal jemand die Funktion brauchen.
"local" geht direkt auf die Framesize, vorsicht !
https://www.roboternetz.de/wissen/index.php/Bascom_Inside
mathias172
01.01.2008, 23:24
Gibt es einen empfehlenswerteren Weg als lokale Variablen?
Mir fiel auch auf, dass die Locals Ihre Werte nach Ablauf der Funktion behalten und beim nächsten Aufruf immer noch zur Verfügung stehen, d.h. in meinem Fall jedes Mal wieder auf 0 gesetzt werden müssen.
Wie auch immer. Anbei nochmal mein gesamtes Programm mit der Funktion.
Kurzfassung: Das Ganze hat einen Servo an den Ports C und ein Wintek (Pollin) Display an Port B. An Port D hole ich mir Schalterzustände mit denen ich die Servoposition einstellen kann. In der ersten Display-Zeile wird der Prozentuale Wert angegeben, in der zweiten Zeile der Balken. Funktionsaufruf ist mit Prozentwert und Maximal möglicher Balkenlänge.
$crystal = 8000000
$framesize = 32 ' die Größe des Frames
$swstack = 320 ' die Größe des Software-stacks
$hwstack = 32 ' die Größe des Hardware-Stacks
Config Lcd = 20 * 4 'Anzeigemodus 40 x 4 Zeichen
Config Lcdpin = Pin , E = Portb.6 , Rs = Portb.7 , Db4 = Portb.3 , Db5 = Portb.2 , Db6 = Portb.1 , Db7 = Portb.0 , E2 = Portb.5
Dim ___lcdno As Byte
Config Servos = 1 , Servo1 = Portc.0 , Reload = 10 , Timer = Timer0
Config Portb = Output
Config Portd = Input
Dim X As Byte , Mini As Byte , Maxi As Byte , Ausgabe As Byte , Temp As Byte
Dim P As Single , P2 As Integer
Enable Interrupts
Declare Function Balken(byval Prozent As Single , Byval Laenge As Byte) As String
___lcdno = 1
Initlcd
Cls
___lcdno = 0
Initlcd
Cls
Cursor Off
Portd = 1
Mini = 40
Maxi = 155
X = Maxi - Mini
X = X / 2
X = X + Mini
Do
P = Maxi - Mini
P = P / 100
P2 = X - mini
P = P2 / P
P = Round(p)
If Pind.0 = 0 Then
Temp = X + 2
If Temp <= Maxi Then X = X + 2
End If
If Pind.1 = 0 Then
Temp = X - 2
If Temp => Mini Then X = X - 2
End If
If Pind.2 = 0 Then
Temp = X + 10
If Temp <= Maxi Then X = Maxi
End If
If Pind.3 = 0 Then
Temp = X - 10
If Temp => Mini Then X = Mini
End If
Locate 1 , 1
Lcd P
Locate 2 , 1
Lcd Balken(p , 20)
Servo(1) = X
Loop
End
Function Balken(byval Prozent As Single , Byval Laenge As Byte)
Local Temp1 As Single
Local Temp2 As Single
Local Temp3 As String * 40
Laenge = Laenge - 2
Temp1 = Prozent * Laenge
Temp1 = Temp1 / 100
If Prozent <= 1 Then Temp3 = "" Else Temp3 = "#"
For Temp2 = 1 To Temp1 Step 1
Temp3 = Temp3 + "#"
Next
Balken = Temp3 + " "
End Function
stefan_Z
02.01.2008, 01:48
Also die Locals werden glaubich im Simulator nur einfach nicht gelöscht.
Sobald die Sub zuende ist, werden die Speicherplätze wieder "recyclet" und beim neu initialisieren gelöscht.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.