PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : State Machine



Loro
16.03.2009, 12:20
Hallo zusammen, ich bins mal wieder und wieder mit meinem Lieblings Thema, der State Machine.

Ich habe Folgendes Problem, beim Lesen der States werden nicht alle Daten gelesen.
In der Sub "Change_state" wird der letzt READ nicht ausgeführt also "Read Change_allow" Wenn ich die Read-Anweisungen vertausche ist es das gleich, die letzte Anweisung wird nicht gelesen.

Hat jemand eine Idee woran das liegen könnte, im Moment sehe nicht meinen Fehler nicht und das schon seit zwei Tagen :-)
Hier der Code

Main Loop:


Do
'Menüeintrag und Tastencodes finden und ggf. State wechseln
'hier nur Tastendruck auswerten
Gosub Change_state

'Pointer nach Statuswechsel neu setzen
If State_renew = 1 Then Gosub Change_state

'Unterprogramm des aktuellen State anspringen
LDS R31, {State_gosub+1} 'High see Bascom-Doc Mixing ASM and BASIC
LDS R30, {State_gosub} 'Low
LSR R31 'Division durch 2 (Alternativ ADR verwenden)
ROR R30
'Call zum Sub
ICALL


'Pina1-2 werden vom Diplay belegt, Pina6 u PinA7 haben eine schwache Spannung
Debounce Pina.3 , 0 , Up_press , Sub
Debounce Pina.4 , 0 , Down_press , Sub
Debounce Pina.5 , 0 , Plus_press , Sub
Debounce Pina.6 , 0 , Minus_press , Sub
Debounce Pina.7 , 0 , Ok_press , Sub


If Change_allow = 1 Then
If Pina.5 = 0 Then
Gosub Plus_press
'Value_change = 1
Elseif Pina.5 = 1 Then
Gosub Reset_plus
End If

If Pina.6 = 0 Then
Gosub Minus_press
'Value_change = 1
Elseif Pina.6 = 1 Then
Gosub Reset_minus
End If
End If


'LCD refresh wenn Menü verändert
If State_renew = 1 Then
State_renew = 0
Gosub Lcdprint
End If
Loop
End



Die States:


'--------------------------------------------------------------------
'Subroutine: Change_state_
'Call from: main loop
'Status der State Machine feststellen und ggf. Wechseln
'--------------------------------------------------------------------
Change_state:
lds R8, {State}
lds R9, {State + 1}
For Icount = 1 To Key_buttons
Read W
If Key = Keycode(icount) Then
If W <> Loadlabel(null) Then
State_renew = 1
Key = Key_null 'reset key status after get a new state of state
'machine (prevent influence on GOSUBs)
State = W
End If
End If
Next Icount
Read State_gosub 'Adresse des akt. Unterprogramms einlesen
Read Lcd_textbuffer 'read LCD text
Read Options_id
Read Array_id 'Identifier für Array Information
Read Change_allow
Return

P1_1: 'Programm 1
Adr2 P1_2 : Adr2 Null : Adr2 Null : Adr2 P1_1_edit : Adr2 Null : Adr2 Null
Adr2 Over_view 'Subroutine for current State
Data Title1
Data 1% 'Aktulee Zeile (Hervorheben)
Data $10
Data 0% 'Change_allow

P1_1_edit:
Adr2 Null : Adr2 Null : Adr2 Null : Adr2 Null : Adr2 Null : Adr2 Null
Adr2 Change 'Subroutine for current State
Data Title1
Data 1% 'Aktulee Zeile (Hervorheben)
Data $10
Data 1% 'Change_allow

[/b]

PicNick
16.03.2009, 12:38
Da der "READ" ein brutalo-Befehl ohne irgendwelche Durchführungsbedingungen ist, lässt er nicht einfach einen aus.

Tücke beim READ : Bascom überprüft NICHT, ob der definierte "DATA"-Datentyp und der Datentyp beim "READ" übereinstimmt (wegen der Länge)
Da müsste man die DIM's sehen.

Btw: Du hast einmal "Data Title1 " und einmal "Data Titel1 "
ist das korrekt ? gibt es beides ?

Loro
16.03.2009, 14:42
"Data Title1 " und "Data Titel1 " gibt es beides, eigentlich nur Data Title1 das ist ein Const, damit ich den Wert leicht umändernkann. Hab es mal oben umgeändert.




Dim Lcd_textbuffer As String * 32
Dim Options_id As Integer
Dim Array_id As Byte , Old_array_id As Byte
Dim Change_allow As Integer


Der Code ansich Funktioniert auch, nur das halt Change_allow keine Veränerung erfährt, der Wert ist immer 0.

-tomas-
16.03.2009, 16:04
Picknick hat Dir den Tip schon gegeben - aber leider bist Du nicht tiefer eingestiegen.

Du kannst solche Probleme jederzeit als Codeausschnitt (Restore + Read/Read/Read etc) im Simulator debuggen.

das sieht dann so aus:

$regfile = "m48def.dat"
$crystal = 8000000
$baud = 19200

$hwstack = 32
$swstack = 8
$framesize = 24

Dim Lcd_textbuffer As String * 32
Dim Options_id As Integer
Dim Array_id As Byte
Dim Change_allow As Integer

Restore P1_1_edit

Read Lcd_textbuffer 'read LCD text
Read Options_id
Read Array_id 'Identifier für Array Information
Read Change_allow

Print Lcd_textbuffer
Print Options_id
Print Array_id
Print Change_allow

End

Const Title1 = "Hallo"

P1_1: 'Programm 1
Data Title1
Data 1% 'Aktulee Zeile (Hervorheben)
Data $10
Data 0%

P1_1_edit:
Data Title1
Data 1% 'Aktulee Zeile (Hervorheben)
Data $10
Data 1% 'Change_allow


die Simulator Ausgabe ist:
Hallo
1
10
256...und schon sehen wir Data $10 belegt 2 Bytes und ist somit keine Byte!! (Das Low Byte rutschte eine Position zum High Byte herüber)

Übrigens: Ich wusste gar nicht, das Bascom Konstanten mit "dollar sign" frisst. Ich habe dazu nichts im Manual gefunden. Ist das eine undokumentierte Syntax?

PicNick
16.03.2009, 16:25
aaarghhh !
Das ist wahr, das ist wohl cut & paste von einem anderen Basic.

stefan_Z
17.03.2009, 11:13
Ich glaube bei Konstanten ist es Bascom egal ob du ein Zeichen davor machst. Der passt das dem Inhalt an.
Bei Binär-Variablen kann man übrigens auch Tiefstriche in den Wert einfügen - das erhöht die Lesbarkeit bei manchen Sachen: &B00_10_1111 wird einfach als &B00101111 erkannt.

PicNick
17.03.2009, 12:05
Es ist ihm tatsächlich egal.
Nur dass er eben zwei statt des gewünschten einen Bytes verbrät

-tomas-
17.03.2009, 12:51
Tiefstriche in den Wert einfügen - das erhöht die Lesbarkeit bei manchen Sachen: &B00_10_1111 wird einfach als &B00101111 erkannt.

!!KEINE TIEFSTRICHE MIT DATA!!

Aufpassen, Bascom ist mit Tiefstrichen sehr eigen!! Als Beispiel ein kurzer Schnipsel:

Dim I As Byte , J As Byte

Const A = &B110_0111

I = A
Print I ; " " ; A

Restore Test

Read I
Read J
Print I ; " " ; J

End

Test:
Data &B1100111
Data &B110_0111
und hier die Ausgabe im Simulator:

103 &B1100111

103 6

Alles klar ;-)
&B110_xxxx wird zu 6.
Und der Hammer ist der entfallene Unterstrich von Print A, hier wird &B110_0111 zu &B1100111

(ich hatte das früher schon mal geschrieben)