PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Code über Taster



hardstyleroxx
30.10.2005, 13:59
Hey,

ich möchte gerne das, wenn man einen Code über einen Taster eingibt ein Pin am Uc auf high geht.

z.B kurz, lang, lang, kurz, kurz

Wobei kurz unter einer Sekunde liegt und lang über einer Sekunde.

Kann mir vielleicht jemand sagen wie ich das hinbekomme?

Danke schonmal!

Marco78
30.10.2005, 14:22
Entweder mit Wait oder Timerint.

Wenn nach 1000ms der Taster immer noch gedrückt wurde, war es lang. Wenn nicht, war es kurz.

hardstyleroxx
30.10.2005, 15:58
Habs nun mal versucht, aber er spuckt imemr Fehlermeldungen beim Compilieren aus.

Wäre nett wenn mir jemand sagen kann was an dem Code falsch ist.


$regfile = M8def.dat
$crystal = 3686400

Ddrb = &B0000001 'Pin PD3 Ausgang, Rest Eingang
Portd = &B00000100 'Pullup von Pind.2 Aktivieren



Led Alias Portb.0 'Portb.2 als LED deklarieren
Taster Alias Pind.2 'Pind.2 als Taster deklarieren

Declare Sub Stelle1 'Stelle1 als Subroutine deklarieren
Declare Sub Stelle2 'Stelle2 als Subroutine deklarieren
Declare Sub Stelle3 'Stelle3 als Subroutine deklarieren
Declare Sub Stelle4 'Stelle4 als Subroutine deklarieren
Declare Sub Stelle5 'Stelle5 als Subroutine deklarieren
Declare Sub Ledan 'Ledan als Subroutine Deklarieren



Do 'Starte Hauptschleife
Debounce Taster , 0 , Stelle1 , Sub 'Taster entprellen
Loop



Stelle1: 'Wenn Taster unter 1sek. betätigt wird zu stelle2 Springen
If Taster = 0 Then
Waitms 1000
If Taster = 1 Then
Gosub Stelle2
End If

Stelle2 'Wenn Taster über 1sek. betätigt wird zu stelle3 Springen
If Taster = 0 Then
Waitms 1000
If Taster = 0 Then
Gosub Stelle2
End If

Stelle3: 'Wenn Taster über 1sek. betätigt wird zu stelle4 Springen
If Taster = 0 Then
Waitms 1000
If Taster = 0 Then
Gosub Stelle4
End If

Stelle4: 'Wenn Taster unter 1sek. betätigt wird zu stelle5 Springen
If Taster = 0 Then
Waitms 1000
If Taster = 1 Then
Gosub Stelle5
End If

Stelle5: 'Wenn Taster unter 1sek. betätigt wird zu Ledan Springen
If Taster = 0 Then
Waitms 1000
If Taster = 1 Then
Gosub Ledan Led
End If


Ledan:
Toggle Led 'LED togglen

End

Torsten_G
30.10.2005, 18:12
Hi,

da war so einiges, ich hab´s Dir überarbeitet und kommentiert, diesen Code solltest Du fehlerfrei kompilieren können:


$regfile = M8def.dat
$crystal = 3686400

Ddrb = &B0000001 'Pin PD3 Ausgang, Rest Eingang
Portd = &B00000100 'Pullup von Pind.2 Aktivieren



Led Alias Portb.0 'Portb.2 als LED deklarieren
Taster Alias Pind.2 'Pind.2 als Taster deklarieren

Declare Sub Stelle1 'Stelle1 als Subroutine deklarieren
Declare Sub Stelle2 'Stelle2 als Subroutine deklarieren
Declare Sub Stelle3 'Stelle3 als Subroutine deklarieren
Declare Sub Stelle4 'Stelle4 als Subroutine deklarieren
Declare Sub Stelle5 'Stelle5 als Subroutine deklarieren
Declare Sub Ledan 'Ledan als Subroutine Deklarieren



Do 'Starte Hauptschleife
Debounce Taster , 0 , Stelle1 , Sub 'Taster entprellen
Loop



Stelle1: 'Wenn Taster unter 1sek. betätigt wird zu stelle2 Springen
If Taster = 0 Then
Waitms 1000
End If
'**FEHLTE!
If Taster = 1 Then
Gosub Stelle2
End If

Stelle2:
'**Doppelpunkt vergessen! 'Wenn Taster über 1sek. betätigt wird zu stelle3 Springen
If Taster = 0 Then
Waitms 1000
End If
'**FEHLTE!
If Taster = 0 Then
Gosub Stelle2
End If

Stelle3: 'Wenn Taster über 1sek. betätigt wird zu stelle4 Springen
If Taster = 0 Then
Waitms 1000
End If
'**FEHLTE!
If Taster = 0 Then
Gosub Stelle4
End If

Stelle4: 'Wenn Taster unter 1sek. betätigt wird zu stelle5 Springen
If Taster = 0 Then
Waitms 1000
End If
'**FEHLTE!
If Taster = 1 Then
Gosub Stelle5
End If

Stelle5: 'Wenn Taster unter 1sek. betätigt wird zu Ledan Springen
If Taster = 0 Then
Waitms 1000
End If
'**FEHLTE!
If Taster = 1 Then
Gosub Ledan
'**Ledan Led gibt´s nicht!
End If


Ledan:
Toggle Led 'LED togglen

End



Die Kommentare mit dem führenden "**" sind von mir...

Viele Grüße

Torsten

hardstyleroxx
30.10.2005, 18:30
Vielen Dank, werde es nachm essen gleich mal testen. Die ganzen End Ifs waren der fehler.. da wär ich nie drauf gekommen =D>

Torsten_G
30.10.2005, 18:39
Nicht nur - es fehlte auch ein Doppelpunkt und ein Subroutine-Label war falsch benannt...

Bei If-then gibt es folgende Möglichkeiten:

If ... then

end if

oder

If ... then

else

end if

oder auch verschachtelt

If ... then

If ...then

End if

End if

Also, ohne End if wird´s nix - aber vom Bascom-Compiler wird man auch nicht grade dolle bei der Fehlersuche unterstützt...

Viele Grüße

Torsten

hardstyleroxx
30.10.2005, 23:22
Also ich kanns nun Compilieren aber funktionieren tut das Programm trotzdem nicht :(
Ich drücke den Taster einmal kurz und nach 1sek geht die LED an.

Wo liegt der Fehler?

Marco78
31.10.2005, 01:01
Ich würde es auch anders machen. Ist evtl aber etwas komplizierter. Mag sein das es auch einfacher geht!

For I = 1 To 5

Loop Until Taster = 0
Waitms 900 'taster entprellen und etwa die Sekunde einhalten
Do

If Taster = 1 then
kurz = kruz + 1
Else lang = lang + 1
End if

next i

So wird alles was nicht kurz war automatisch zu lang.
Später muss ausgewertet werden, wie oft kurz oder lang gedrückt wurde.
Ist die Reihenfolge noch wichtig müsste sie mit abgespeichert werden.
Nachteil, diese Routine läuft sturr ihre fast 5 Sekunden ab, bevor etwas passieren kann. auch wenn es 5 X kurz werden sollte. Die kurz werden dann ggf. auch nicht wirklich erkannt.

Eleganter wäre es mit einem Timer.

Die Timer-ISR läuft alle 20ms ab.
Sie könnte auch dir einen externen INT aktiviert werden, damit sie nicht dauerhaft läuft.

In der ISR wir jedesmal geprüft, ob der Taster noch gedrückt ist. Wenn ja, wir eine Variable hochgezählt, so lange bis er nicht mehr gedrückt ist.
Ist die Variable über 50 wird ein Merke für lang gesetzt und die Variable auf 0 gesetzt.
Ist sie unter 50 war es ein kurzer Tastendruck.
Eine zweite Variable wird bis 5 hochgezählt (sofern alle Codes aus 5 mal drücken bestehen).
Dann wird das Bitmuster ausgewertet.

Vorteil: nach einnam kurz muss nicht gewartet werden bis die Sekunde vorbei ist und es kann direkt nochmal gedrückt werden. So geht kein Tastendruck verloren.

In Abhänigkeit der Taktfrequenz muss noch abgeschätzt werden ob die ISR mit 20ms den restlichen Code noch ausführen lassen kann.

Um den ganzen Code zu schreiben ist es mir jetzt schon zu spät. Ich bin auch erst Ende der Woche wieder Zuhause. Entweder so lange warten, es selbst probieren oder hoffen das dir jemand anders die Arbeit abnimmt.

Aber wenn du es schon selber probierst und man den guten Willen sieht wird man dir sicherlich helfen!

hardstyleroxx
31.10.2005, 01:06
Hallo,

danke für deine Versuche mir das zu erklären. Blos bin ich gerade erst am Anfang und habe mit Timern noch nichts gemacht. Bei dem was du geschrieben hast verstehe ich auch ehrlichgesagt recht wenig.

Hat jemand vielelicht eine leichtere Lösung?

Marco78
31.10.2005, 01:15
Etwas leichter wäre das erste Beispiel was ich geschrieben habe. Aber da gehen einige Tasten sicherlich bei unter.

Zum Thema Timer findest du in der Hilfe und hier im Forum einige Beispiele. Die werden dir schomal ein wenig helfen. Du kannst ja damit anfangen eine LED jede Sekunde umschalten zu lassen. So siehst du die Zusammenhänge.

Dann musst du nachvollziehen, das das Progamm immer schritt für Schritt abläuft und evtl nur durch Interrupt unterbrochen wird.
Jede Unterbrechung durch den Timer bedeutet dann 20ms sind vorbei. Das 50 mal und eine Sekunde ist vorbei.
Probier es erstmal das die LED an geht wenn die eine Sekunde drückst und ausgeht wenn du nur kurz drückst.
Weiteres kommt dann schon fast von alleine.

hardstyleroxx
31.10.2005, 01:42
Ok danke, werde gleich mal die SuFu bemühen ;)

hardstyleroxx
13.02.2006, 21:01
Hey,

ich habe mir ein AVR Buch gekauft und bin auch schon ein ganzes stück weiter, blos diese Aufgabe bekomme ich einfach nicht hin. Sitze hier nun schon 6 Stunden am Stück und Probiere. Wäre vielleicht jemand so nett mir zu helfen?

Der Code in meinem Beispiel soll kurz-kurz-lang sein und es soll bei richtiger Eingabe eine Led togglen. Sobald eine Taste falsch eingegeben wurde soll sich alles zurück setzen.



$regfile = M8def.dat
$crystal = 3686400

Config Portd = Output
Config Portb = Input

Portb = &B000000001

Ledtest Alias Portd.4
Led Alias Portd.3
Taster Alias Pinb.0


'Timer Config (jede 10ms Interrupt)
Enable Timer0
Enable Interrupts
Config Timer0 = Timer , Prescale = 256
Const Timervorgabe = 112
On Timer0 Ueberlauf

Dim Lang As Bit
Dim Kurz As Bit
Dim Zler As Byte
Dim Ged As Bit
Dim Code_lang As Bit
Dim Code_kurz As Bit
Dim Erste_stelle As Bit
Dim Zweite_stelle As Bit



Do

If Kurz = 1 Then 'wenn kurz = 1, dann Code_kurz setzen und kurz = 0
Set Code_kurz
Kurz = 0
End If

If Lang = 1 Then 'wenn lang = 1, dann Code_lang setzen und lang = 0
Set Code_lang
Lang = 0
End If

If Code_lang = 0 Then 'Erste Stelle vom Code (Kurz)
If Code_kurz = 1 Then
Set Erste_stelle
Else
Reset Erste_stelle
End If
End If

If Code_lang = 0 Then 'Zweite Stelle vom Code (Kurz)
If Code_kurz = 1 Then
If Erste_stelle = 1 Then
Set Zweite_stelle
Else
Reset Erste_stelle
Reset Zweite_stelle
End If
End If
End If


If Code_lang = 1 Then 'Dritte Stelle vom Code (Lang)
If Code_kurz = 0 Then
If Erste_stelle = 1 Then
If Zweite_stelle = 1 Then
Toggle Led
Else
Reset Erste_stelle
Reset Zweite_stelle
End If
End If
End If
End If



Loop



Ueberlauf:



Timer0 = Timervorgabe



If Taster = 0 Then 'Wenn Taster gedrückt Zler um einen erhöhen
Incr Zler
End If

If Zler > 100 Then 'Wenn Zler größer als 100 "lang" setzen
Lang = 1
End If

If Zler <= 100 Then 'Wenn zler kleiner oder gleich 100...
If Taster = 1 Then '...und der Taser nicht mehr gedrückt ist...
Kurz = 1 '..."kurz" setzen
End If
End If

If Kurz = 1 Then
Led = 1
End If


If Lang = 1 Then
Led = 0
End If




Return