Hallo!
Ich habe folgende Schaltung auf einem Attiny26 am Laufen:
1
$regfile = "Attiny26.dat"
2
$crystal = 1000000
3
4
5
Config Pinb.6 = Input
6
Portb.6 = 1
7
Config Porta.7 = Output
8
Config Porta.6 = Output
9
Config Porta.5 = Output
10
11
Led1 Alias Porta.5
12
Led2 Alias Porta.6
13
Led3 Alias Porta.7
14
Taster Alias Pinb.6
15
16
17
Do
18
If Taster = 1 Then
19
Gosub Tasteraus
20
Else
21
Gosub Tasterein
22
End If
23
Loop
24
25
Tasteraus:
26
Led1 = 0
27
Led2 = 0
28
Led3 = 0
29
Wait 1
30
Led1 = 1
31
Led2 = 1
32
Led3 = 1
33
Wait 1
34
Return
35
36
Tasterein:
37
Led1 = 0
38
Led2 = 1
39
Led3 = 1
40
Waitms 50
41
Led1 = 1
42
Led2 = 0
43
Led3 = 1
44
Waitms 50
45
Led1 = 1
46
Led2 = 1
47
Led3 = 0
48
Waitms 50
49
Return
50
51
End
Wenn ich jetzt den Taster drücke, läuft erst das Programm Tasteraus
fertig, ERST DANN springt der Controller auf das Programm Tasterein. Da
das Programm Tasteraus 2 Sekunden dauert, und ich beispielsweise bei dem
Umschaltvorgang von Led123=0 auf Led123=1 den Taster drücke, dauert es
noch eine Sekunde, bis das Programm Tasterein aufgeruden wird.
Wie könnte ich diese Wartezeit verhindern?
Thomas
Solches "warten" macht man mit Timern. Das geht bestimmt auch in bascom.
Dann brauchste auch gar keine Subs mehr sondern nur den Timerinterrupt
und eine globale Variable.
Gruß
Fabian
>Und was für Alternativen würden sich da bieten?
Keine. SOnst bleibts Spaghetticode.
Wie Fabian B. (fabs) sagte:
-Die Ausgabedaten für die Leds in eine Tabelle packen.
-Über einen Timerinterrupt neue Daten an den AUsgang schaufeln.
-Die Taster ändern nur den Zeiger, der in die Tabelle zeigt.
=> Kein Delay/Wait mehr nötig.
>Keine. SOnst bleibts Spaghetticode.
Kann man mit Basic eigentlich Nicht-Spaghetticode machen? ;-)
>Und was für Alternativen würden sich da bieten?
Wie bereits gesagt. Mach dir einen Timer und für die Taster irgendwie
globale Flags, die du in der ISR abfragst und entsprechend reagierst.
>Kann man mit Basic eigentlich Nicht-Spaghetticode machen? ;-)
Stimmt. Wohl eher nicht ;-)
Naja, wollen ja keine Diskussion Bascom/Nicht_bascom lsobrechen hier..
Ich will mal was produktives beisteuern. Ich würds etwa so machen:
(pseudocode)
Matthias Beispiel ist aber in C und nicht in Basic. Aber der Ansatz mit
einem Timer-Interrupt ist sicher die schönste Variante, ich weiss aber
nicht ob man das mit Basic kann, bzw. weiss nicht wie man das in Basic
macht.
Aber ich hätte noch einen alternativen Vorschlag:
$regfile = "Attiny26.dat"
$crystal = 1000000
Config Pinb.6 = Input
Portb.6 = 1
Config Porta.7 = Output
Config Porta.6 = Output
Config Porta.5 = Output
Led1 Alias Porta.5
Led2 Alias Porta.6
Led3 Alias Porta.7
Taster Alias Pinb.6
Do
For i=1 to 10
If Taster = 1 Then
If i<6
Gosub TasterausOff
Else
Gosub TasterausOn
Ensdif
Else
Gosub Tasterein
End If
next i
Loop
TasterausOff:
Led1 = 0
Led2 = 0
Led3 = 0
Waitms 100
Return
TasterausOn:
Led1 = 1
Led2 = 1
Led3 = 1
Waitms 100
Return
Tasterein:
Led1 = 0
Led2 = 1
Led3 = 1
Waitms 50
Led1 = 1
Led2 = 0
Led3 = 1
Waitms 50
Led1 = 1
Led2 = 1
Led3 = 0
Waitms 50
Return
End
Oups...
Eine Sekunde ist 10x100ms! Für eine Sekunde sollte es natürlich so sein:
Do
For i=1 to 20
If Taster = 1 Then
If (i < 11)
Gosub TasterausOff
Else
Gosub TasterausOn
Ensdif
Else
Gosub Tasterein
End If
next i
Loop
>Matthias Beispiel ist aber in C und nicht in Basic.
Deshalb habe ich pseudocode drübergeschrieben, weil es nicht exakt C
ist. DIese bascom kann doch keiner...
@Peter:
Dort sind auch auf wieder Warteschleifen drin, in der Zeit kann nix
anderes passieren...
Also nur anders programmiert, aber immernoch dasselbe Problem.
>Deshalb habe ich pseudocode drübergeschrieben, weil es nicht exakt C>ist. DIese bascom kann doch keiner...
Ich kenne Bascom auch nicht und benutze C. Aber ich habe früher viel in
Basic programmiert (Atari, Taschenrechner, VBA) und finde es ist bei
weitem nicht so schlecht wie sein Ruf, schon gar nicht für erste
Schritte. Es gibt keinen Grund, abschätzig auf den Basic-Programmierern
rum zu hacken, wie dies hier im Forum offenbar üblich ist. Spagetticode
hängt vom Programmierer ab, nicht von der Programmiersprache!
>Dort sind auch auf wieder Warteschleifen drin, in der Zeit kann nix>anderes passieren...
Ich schreibe ja, dass eine Lösung mit Timer-Interrupt die bessere Lösung
ist.
Meine Variante lösst einfach mal das Problem, dass man bis zu zwei
Sekunden warten muss, bis ein Tastendruck erkannt wird. Nun wird die
Taste immerhin alle 100...150ms abgefragt, was im Normalfall schon recht
praktikabel ist.
Hallo Peter!
Besten Dank dür deine Hilfe!
Leider gibt mir Bascom eine Fehlermeldung aus, wenn ich versuche, den
Code zu kompilieren. Weißt du eventuell, woran das liegen könnte?
Thomas
Vielleicht an "Ensdif" statt "Endif" in der Schleife? ;-)
Wenn Du in Bascom mit der Maus ganz unten auf die Fehlermeldung gehst
und darauf klickst, hüpft der Compiler in die Zeile mit dem Fehler und
färbt sie rot.
MfG Paul
>Vielleicht an "Ensdif" statt "Endif" in der Schleife? ;-)
Tja, das ist natürlich ein Tippfehler und muss natürlich "End If"
heissen. Vielleicht gibt's noch weitere Fehler. Der Compiler wird Dir
schon sagen, wo's noch was zu mekern gibt.
Ich denke du musst auch die Variable i für den Schleifenzähler
deklarieren, zum Beispiel als Byte.
Nein leider funktioniert auch dieser Code nicht. Jetzt gibt er schon
vier Meldungen aus, die alle entweder zu "< 11" führen, oder gegen den
Befehl "End If" gehen.
Thomas
Thomas E. wrote:
> Nein leider funktioniert auch dieser Code nicht. Jetzt gibt er schon> vier Meldungen aus, die alle entweder zu "< 11" führen, oder gegen den> Befehl "End If" gehen.^
Nur so als Hinweis:
Sehr oft ist der Text einer Fehlermeldung hilfreich beim Suchen
nach dem Fehler