Hallo liebe Community!:)
Ich habe hier mein erstes Script geschrieben, mit welchem man durch
Tastendruck eine LED ein- bzw. ausschalten kann.
Jetzt habe ich das Problem, dass meine Taster "bouncen".
Habe mir schon mehrere Beiträge durchgelesen, jedoch meistens nicht
genau verstanden oder die Beiträge waren mit Interrupts inkompatibel.
Könnte mir jemand eine gute Seite empfehlen oder mein Script
vervollständigen und mir erklären welcher Befehl was macht?
Danke im Vorraus!:)
1
#include<avr/io.h>
2
3
#include<avr/interrupt.h> // enthält alle Routinen
4
//für die Interruptverarbeitung
5
6
7
//ISR (Interrupt-Service-Routine) für
8
//Interrupt 0
9
10
{
11
PORTD|=(1<<PD7);//setze PortD 7 (Lampe an)
12
}
13
14
//ISR (Interrupt-Service-Routine) für
15
//Interrupt 1
16
17
{
18
PORTD&=~(1<<PD7);//lösche PortD 7 (Lampe aus)
19
}
20
21
22
intmain(void)
23
{
24
DDRD|=(1<<PD7)
25
PORTD|=(1<<PD2)|(1<<PD3)
26
27
MCUCR|=(1<<ISC10)|(1<<ISC11);//Interrupt 1 wird konfigriert
28
29
//Interrupt 0 wird konfiguriert
30
31
GICR|=(1<<INT0)|(1<<INT1);//INT0 und INT1 aktiviren
>Ich habe hier mein erstes Script geschrieben, ...> ... mir erklären welcher Befehl was macht?
Unsinn, entweder selbst geschrieben, oder kopiert und nicht verstanden.
Was nun?
Ließ doch mal hier das Tutorial zum Einlesen von Tasten.
Wenn du einen Eingang für Ein und einen für Aus, also wie ein
RS-FlipFlop, verwendest stört das Prellen nicht, außer dass es ein
bisschen Rechenzeit verbraucht.
Schüler E. schrieb:> Könnte mir jemand eine gute Seite empfehlenAVR-GCC-Tutorial
Ich habe das Script selber geschrieben und verstanden? Ich möchte nur
eine Erklärung wie ich das "Entprellen" einbauen kann.
Das Problem ist ich soll das ganze in Scriptform abgeben mit Erklärung
und allem, Teil 1 also Interrupts allgemein hab ich fertig, das
Software Entprellen gäbe noch paar extra Punkte, deshalb würde ich das
ganz gerne machen.
Mit dem flankengesteuertem Interrupt kann man den Taster nicht gut
entprellen, da jede Prell-Flanke ein Interrupt auslöst. Für gewöhnlich
nimmt man ein Timer Interrupt und fragt den Zustand in der ISR ab.
Siehe --> Entprellung <--
Habe ich das richtig verstanden, dass du die LED mit einer Taste ein-
und mit einer anderen ausschaltest, also wie ein RS-FlipFlop? Wenn ja
ist entprellen nicht notwendig. Dein einziges Problem ist dass die ISR
durch das Prellen öfters aufgerufen wird und Rechenzeit verbraucht. Das
kannst du wenn du flankengesteuerte Interrupts verwendest nur in
Hardware lösen.
Stimmt wenn ich es genau überdenke ist ein Entprellen gar nicht
notwendig.
Danke erstmal dafür :)
Ich würde jedoch gerne bei der Verwendung der externen Interrupts
bleiben, ist es möglich den Taster so abzufragen das nach Betätigung die
Interrupts global deaktiviert werden "cli();" und dann nach 100ms
einfach wieder aktiviert werden "sei();". Wäre zwar keine genaue Methode
aber für mich ausreichend.
Schüler E. schrieb:> ist es möglich den Taster so abzufragen das nach Betätigung die> Interrupts global deaktiviert werden "cli();" und dann nach 100ms> einfach wieder aktiviert werden "sei();"
Bitte komm NICHT auf die Idee ein Delay in die ISR zu stecken, das ist
ein ABSOLUTES NO-GO. Du könntest es so machen, dass du in der ISR
INT0/INT1 deaktivierst und einen Timer, der nach 100ms überläuft,
startest und in der Timer ISR das entsprechende Interrupt wieder
aktivierst.
Ok dann werde ich das mit dem delay schnell wieder vergessen :D
Ich werde mir mal "Timer Interrupts" anschauen und mich später wieder
melden, habe bisher nur die externen Interrupts behandelt.
Wozu der Timer? Wenn man separate Tasten fürs Ein- und Ausschalten hat,
ist Entprellen nicht nötig, da immer nur die erste Flanke von genau
einem Eingang interessiert.
Also:
Interrupt0:
- Int.0 sperren
- Licht an
- Int.1 einschalten
Interrupt 1:
- Int.1 sperren
- Licht aus
- Int.0 einschalten
Solange das Licht an ist, bekommt der Prozessor dann natürlich nicht
mehr mit, wenn die Einschalttaste nochmal gedrückt wird (Interrupt 0 ist
ja deaktiviert). Aber das macht nichts; der Prozessor würde ja sowieso
nichts für den Benutzer wahrnehmbares tun.
Nosnibor schrieb:> Wozu der Timer? Wenn man separate Tasten fürs Ein- und Ausschalten hat,> ist Entprellen nicht nötig, da immer nur die erste Flanke von genau> einem Eingang interessiert.>> Also:>> Interrupt0:> - Int.0 sperren> - Licht an> - Int.1 einschalten>> Interrupt 1:> - Int.1 sperren> - Licht aus> - Int.0 einschalten>
Und wenn man sich das mal genau überlegt, erhebt sich die Frage, wozu
man da überhaupt externe Interrupts braucht.
Nur dazu, damit man eine Flankenerkennung gratis bekommt. Die ist aber
so kompliziert auch wieder nicht. Und wenn es nur darum geht ein Licht
mit 2 Tastern ein bzw. aus zu schalten, braucht man noch nicht mal das.
Alles was man braucht ist eine Variable, die festhält ob das Licht
brennen soll oder nicht. Wobei man sogar die noch einsparen könnte, bzw.
in das Bit des Portregisters legen kann, mit der die LED verbunden ist.
1
intmain()
2
{
3
.....
4
5
while(1)
6
{
7
if(!(PIND&(1<<PD0)))
8
PORTB|=(1<<PB1);
9
10
if(!(PIND&(1<<PD1)))
11
PORTB&=~(1<<PB1);
12
}
13
}
fettich.
Wobei: ordentliches Einlesen von Tastendrücken und deren Entprellung ist
eine Technik, die man irgendwann sowieso braucht. Aber sicher nicht ...
1
...IchhabehiermeinerstesScriptgeschrieben.
... in dieser Situation. Tastendrücke zu erkennen (im Gegensatz zu 'ist
eine Taste gedrückt') ist erstaunlicherweise nicht so einfach. Lediglich
das Stichwort 'externer Interrupt' zu benutzen, greift da deutlich zu
kurz.
> Interrupt0:> - Int.0 sperren> - Licht an> - Int.1 einschalten>> Interrupt 1:> - Int.1 sperren> - Licht aus> - Int.0 einschalten
Wenn die beide IRQ-Routinen schnell genug durchlaufen werden, dann sorgt
eine lange Prellzeit dafür, dass das Ganze ein Zufallsgenerator ist
(Licht ist AN oder AUS).
Karl-Otto schrieb:> Wenn die beide IRQ-Routinen schnell genug durchlaufen werden, dann sorgt> eine lange Prellzeit dafür, dass das Ganze ein Zufallsgenerator ist> (Licht ist AN oder AUS).
Nur wenn der Benutzer beide Tasten gleichzeitig (im Sinne von: die
zuerst gedrückte Taste prellt noch, während die zweite gedrückt wird)
drückt.
Selber schuld, wenn er sich nicht entscheiden kann.
Auf alle Fälle ist es der Welt dümmster Ansatz, prellende Tasten per
Interrupt zu behandeln.
Würd ich meinem Lehrer sagen und auch begründen können.
Haben die denn keine besseren Beispiele parat, wenn die Behandlung von
Interrupts im Unterricht besprochen wird????
Ich habe das grade mal probiert und kann bestätigen - per Interrupt
Taster entprellen ist eine schlechte Idee. Habe das jetzt so weit
getrieben:
- Interrupt auf steigende Flanke an PinB3 (Taster zieht mit 150Ohm auf
Vcc; Pin hat 10k Pulldown auf GND).
- Erste Schnellschussfassung: Bis 3 zählen (also 3 Interrupts abwarten)
und erst das als Tastendruck erkennen. Kommt bei etwa 75% der
Tastendrücke hin. Aber immer noch ein ziemlicher Zufallsgenerator.
- Ich merke mir TasteGedrückt beim ersten Druck, werfe einen Timer an
und in dessen ISR führe ich meine Sachen aus. Dazu deaktiviere ich die
erste Interrupt-Routine. Idee: damit warte ich das Prellen einfach ab.
Ist aber ein viel schlimmerer Zufallsgenerator; erzeugt immer 2-3
erkannte Tastendrücke, die dann nach der Wartezeit ausgeführt werden.
Hätte gedacht, dass die durch das Deaktivieren des ISR nicht aufgenommen
würden, war aber nichts.
Ich glaube so langsam, entprellen in Software ist doch nicht trivial ;)
Ich brauche die Interrupts, weil mein Programm weiterlaufen und der
Prozessor in einer Stellung sogar im Powerdown schlafen soll (Strom
sparen). Per ISR geht das, und der Prozi wird wieder geweckt.
Lest euch mal den Artikel Entprellung durch, dort steht geschrieben,
welche Möglichkeiten es in Software (und Hardware) gibt und welche zu
bevorzugen sind.
Dirk K. schrieb:> Ich brauche die Interrupts, weil mein Programm weiterlaufen und der> Prozessor in einer Stellung sogar im Powerdown schlafen soll (Strom> sparen). Per ISR geht das, und der Prozi wird wieder geweckt.
Zum Aufwachen ist der Interrupt geeignet. Danach wird dann normal
entprellt.
Programmfunktion und Sleepmode/Aufwachen sind quasi 2 eigenständige
Tasks, die man auch getrennt entwickelt:
Beitrag "AVR Sleep Mode / Knight Rider"
@Dirk K.
Du musst schon 10-50mS abwarten, je nach verwendeten Taster. Man darf
aber auch nicht vergessen das Taster auch beim loslassen prellen
können!
Teo Derix schrieb:> aber auch nicht vergessen das Taster auch beim loslassen prellen> können!
wie kann man sich der erklären? Oder meinst du einen öffner kontakt?
Peter II schrieb:> Teo Derix schrieb:>> aber auch nicht vergessen das Taster auch beim loslassen prellen>> können!>> wie kann man sich der erklären?
Wie beim Dribbeln, Du schlägst auf den Ball und er kehrt wieder zur Hand
zurück.
Die Kontaktfeder speichert beim Betätigen Energie und gibt sie als
gedämpfte Schwingung ab.
Bei Tasten ohne Schnappmechanik (Druckpunkt) kann auch Deine
Muskelbewegung eine Mehrfachbetätigung auslösen. Muskeln werden ja
gepulst.
Peter Dannegger schrieb:> Wie beim Dribbeln, Du schlägst auf den Ball und er kehrt wieder zur Hand> zurück.> Die Kontaktfeder speichert beim Betätigen Energie und gibt sie als> gedämpfte Schwingung ab.
schon klar, aber sie schwinkt doch wohl nie so stark das sich die
kontakte wieder verbinden.
Peter II schrieb:> Peter Dannegger schrieb:>> Wie beim Dribbeln, Du schlägst auf den Ball und er kehrt wieder zur Hand>> zurück.>> Die Kontaktfeder speichert beim Betätigen Energie und gibt sie als>> gedämpfte Schwingung ab.>> schon klar, aber sie schwinkt doch wohl nie so stark das sich die> kontakte wieder verbinden.
Wenn du Kontakte stark genug abgenudelt sind, kann alles mögliche
passieren.
Mit der PeDa Entprellung ist das ja kein Problem. Die entprellt in
beiden Richtungen.
Peter II schrieb:> schon klar, aber sie schwinkt doch wohl nie so stark das sich die> kontakte wieder verbinden.
Ist eine Frage der Konstruktion. Die Schnappmechanik speichert deutlich
mehr Energie, als für das reine Bewegen der Kontaktfeder nötig ist.
Zusätzlich werden Taster immer kleiner (billiger), d.h. kleiner
Kontaktabstand, kleine Federn. Die Betätigungskraft des Menschen bleibt
aber gleich.
Ein weiterer Prellgrund, Tasten altern, d.h. es bilden sich kleine
isolierende Bereiche (Staub, Oxydschicht) die beim darüber Bewegen den
Strom unterbrechen.
Das Heimtückische am fehlenden Enprellen ist, daß fabrikneue Tasten oft
kaum prellen. Und nach einem halben Jahr Benutzung geht dann das Drama
los.
Peter Dannegger schrieb:> Programmfunktion und Sleepmode/Aufwachen sind quasi 2 eigenständige> Tasks, die man auch getrennt entwickelt:
Darüber hatte ich nur kurz sinniert und bin noch zu keiner für mich
schlüssigen Umsetzung gekommen (Programm ist wie ein Artikel für mich:
Der muss im Kopf fertig sein und wird dann nur noch am Ende auf Papier
geworfen.)
Danke für den Tipp, war die Richtung also gar nicht so verkehrt. Werde
das mal umsetzen - ist zwar nur ein Lernstück für mich selber (quasi ein
LED-Throwie mit RGB-LED und Taster an 'nem ATtiny85 mit Speisung aus
CR2032), aber genau diesen Zweck (lernen, Probleme machen) erfüllt es
trotz eigentlich größter Simplizität hervorragend.