Grüß Euch, bin neu hier im Forum (eher Anfänger), um ein aktuelles Problem mit eurer Hilfe zu lösen, da ich nicht weiter komme. Hardware: - myAVR Board Mk2 (aus den myAVR Einsteigerset) mit einen Atmet ATmega8 - dieses Board ist mit einen selbstgebautem Adapterkabel (anstelle der grünen Platine) mit einen AVRISP MK2 Programmer verbunden - Der Programmer ist über ein USB Kabel mit den Rechner verbunden - Entwicklungsumgebung ist das Atmel Studio 6 - Konstat- Spannungsversorgung: Voltcraft DPS-4005PFC 9.01V, 0.009A im Idle Ziel: Eine LED auf Anschluss PIN B0 soll über einen Taster1 auf Pin D2 ein- und ausgeschaltet werden. Anfangs soll die rote led nicht leuchten. Wird Taster gedrückt (UND LOSGELASSEN FÜR EINE UNBESTIMMTE ZEIT), so geht die LED an. WIRD nun in einen beliebigen Intervall nochmals gedrückt, geht die LED aus. Realisiert werden soll das ganze durch einen externen Interrupt über INT0_ect auf Pin4 auf'n Atmel. Es dürfen keine Delays verwendet werden, auf Nesting soll verzichtet werden. Problem: 1. Anfangs leuchtet nichts. --> OK 2. Bei drücken von TAster 1 leuchet die rote led --> OK 3. bei drücken von Taster 1 geht die rote led wieder aus --> OK 4. Manchmal geht bei drücken von Taster 1 die Rote led garnicht aus, obwohl sie davor an war --> NICHT OK --> Manchmal realisiert er den Tastendruck nicht. Funktionen für das Entprellen habe ich bereits in meinem Code drin (taster_was_pressed und taster_was_pressed2()). Die Taster_was_pressed- methode geht jedoch nicht, sie funktionert aber in einen anderen Programm tadellos. Die ausdokumentierte Methode "taster_was_pressed" funktioniert, nimmt jedoch nicht jeden Tastendruck war. Artikel wie Beitrag "Unterbrechung mit Taster" Beitrag "Entprellen für Anfänger" Beitrag "Interrupt Taster "flackert"" die über das entprellen und interrupt handeln, sind mir bekannt, aber ich komme nicht weiter! Könnte mir bitte jemand von euch helfen? Vielen Dank. Mit freundlichen Grüßen, tommyProg >>>>CODE IM ANHANG<<<<
Ergänzend müsste ich noch erwähnen, dass ich den Interrupt aktuelle von einer fallenden Flanke (High auf Low) programmiert habe, da der Schalter auf Logisch 0 ist, wenn dieser gedrückt wird. Mit freundlichen Grüßen, TommyProg
Hast du das schon gelesen?: http://www.mikrocontroller.net/articles/Entprellung Ich kann bei dir nirgends eine Entprellung sehen.
*** Ergänzend: Dank der Debounce Methode von Peter (http://www.mikrocontroller.net/attachment/67964/debounce.c) funktioniert das System einwandfrei. Einziges Problem ist, dass in dieser Methode ein _delay_us(xx) drin ist. Ein Delay darf ich eben nicht benutzen^^.
Daniel V. schrieb: > Ich kann bei dir nirgends eine Entprellung sehen. wahrscheinlich meint er sein konfuses sei() und cli()-Konstrukt ist eine Entprellung...
@Daniel Ja, ich hatte diesen Artikel gelesen. Scheinbar hat mir der Anhang mein längeeres Codestück nicht mitgenommen. Ich poste es einfach mal hier: *************************************************************
1 | bool taster_was_pressed2(int input_port,int input_bit) //Funktion, um den Taster 1 auf Status "gedrückt" zu prüfen |
2 | {
|
3 | int state=0; //Deklariere Statusvariable |
4 | while(1) //while- Schleife, da er die Statusse immer wieder überprüfen muss |
5 | {
|
6 | if ((state==0) &&(!(input_port&(1<<input_bit)))) //wenn der Schalter davor noch nicht gedrückt wurde, und wenn er gerade gedrückt wird |
7 | {
|
8 | state=1; //setze den Status auf 1 (einmal gedrückt) |
9 | }
|
10 | else
|
11 | {
|
12 | if((state==1) && (!(input_port&(1<<input_bit)))) //wenn der Schalter davor gedrückt worden ist, und der Taster noch gedrückt wird, |
13 | { //also der Schalter gehalten wird |
14 | state=2; //setze den Status auf 2 |
15 | }
|
16 | else
|
17 | {
|
18 | if((state==1||state==2) &&(!(input_port&(1<<input_bit)))) //fast gleiches wie darüber, nur der Taster kann auch länger gehalten werden |
19 | {
|
20 | state=2; //status zurücksetzen |
21 | }
|
22 | else
|
23 | {
|
24 | if((state==2) &&(input_port&(1<<input_bit))) //erst wenn der Taster gehalten worden ist, und losgelassen wurde, wird |
25 | { //der Schalter offiziell als gedrückt gemeldet |
26 | state=0; //und der Status wieder für die nächst Tastendruckprüfung auf 0 gesetzt |
27 | return true; |
28 | }
|
29 | else
|
30 | {
|
31 | return false; //ist nichts gedrückt, wird false als ergebnis zurückgeliefert |
32 | }
|
33 | }
|
34 | }
|
35 | }
|
36 | }
|
37 | }
|
********************************************************************** Diese Funktion nimmt auch das entprellen weg, funktioniert aber scheinbar in diesem Problemfall überhaupt nicht. Mfg, tommyProg
:
Bearbeitet durch User
@Justus Nein, das sei() und cli() ist keine Entprellung. Es wird damit das global interrupt enable im SREG- Register gesetzt und geweils gelöscht. Dies ist mir bewusst. Entprellung war wie gesagt meine letzte Funktion "taster_was_pressed2". Meines Achtens macht die Funktion "taster_was_pressed" aber auch die entprellung, oder irre ich mich da? dennoch danke euch ;) Mfg, tommyProg
@justus Dann sag mir bitte genau, was die Funktion "taster_was_pressed" bewirkt. Mfg, tommyProg
Wieso machst du deine Hausaufgaben eigentlich nicht komplett selbst, die Aufgabenstellung ist doch trivial. Wenn dir das Forum das löst ist der Lerneffekt gleich null.
Tho Wes schrieb: > Dann sag mir bitte genau, was die Funktion "taster_was_pressed" bewirkt. omg. kann es sein, dass du gar nicht weißt, wie sich Prellen auswirkt?
Tho Wes schrieb: > @justus > > Dann sag mir bitte genau, was die Funktion "taster_was_pressed" bewirkt. keine Ahnung, müsste man genauer analysieren. Auf jeden Fall ist es keine Entprellung, denn Entprellung bedeutet immer, dass es in irgendeiner Form eine hinreichend lange Zeitkomponente geben muss und die kommt in dieser Funktion nun mal nicht vor. Da werden ein paar Status Variablen hin und her geschoben und irgendwann mündet das dann in einem der beiden returns. Da dieses hin und herschieben aber um Zehnerpotenzen schneller geht als das Tastenprellen, ist irgendeiner der returns erreicht noch ehe der Taster mechanisch überhaupt eine Chance hatte zu prellen. qed. Ich kann mich nur immer wieder wiederholen. Die PeDa Entprellung mittels Timer-Interrupt ist zwar nicht leicht zu verstehen, dafür aber in der Anwendung äusserst simpel
1 | ....
|
2 | |
3 | // Initialisierung aus dem PeDa Code übernehmen
|
4 | |
5 | while( 1 ) { |
6 | |
7 | if( get_key_press( 1 << KEY ) ) |
8 | PORTB ^= ( 1 << PB0 ); // oder wo auch immer die LED sitzt |
9 | }
|
10 | }
|
fertig. Einfacher gehts nicht mehr. Einfach die Codeteile aus dem PeDa Code übernehmen, die #define auf die eigenen Verhältnisse anpassen. In 5 Minuten hat man funktionierende Taster, die alle Stückeln spielen, die man je brauchen wird. Und nein. Den Kern des PeDa Codes muss man auch nicht verstehen um ihn zu verwenden. Könntest du eine Funktion schreiben, die eine Wurzel aus einer Zahl zieht? Nein? Dann dürftest du der 'ich benutze nur Dinge, die ich auch verstehe' Doktrin nach auch eine sqrt() Funktion nicht benutzen.
:
Bearbeitet durch User
AVR-Großmeister schrieb im Beitrag #3825917: > Wieso machst du deine Hausaufgaben eigentlich nicht komplett selbst, die mach ich, aber nun häng ich, und schein von etwas nicht soviel ahnung zu haben. Deshalb bitte ich um Hilfe. Über Tipps würde ich mich auch freuen, bruache ja net gleich die Lösung >Wenn dir das Forum das löst ist der > Lerneffekt gleich null. Das ist nicht ganz richtig, wenn ich die Lösung nachvollziehen kann, habe ich auch möglichkeiten aufgefasst, wie man ein Problem umsetzt. Aber das ist eher jetzt nicht relevant. Ich bröchte nen Tipp, vlt. von dir mfg,Thomas
Karl Heinz schrieb: > Die PeDa Entprellung mittels Timer-Interrupt ist zwar nicht leicht zu > verstehen, dafür aber in der Anwendung äusserst simpel das hier ist aber doch offensichtlich eine Hausaufgabe oder so, also wird er "seinen" Code auch erklären können müssen...und wenn er schon nicht versteht, was seine eigene kurze Funktion macht, wird er bei PeDas Entprellung erst recht nicht durchsteigen...
Justus Skorps schrieb: > Karl Heinz schrieb: >> Die PeDa Entprellung mittels Timer-Interrupt ist zwar nicht leicht zu >> verstehen, dafür aber in der Anwendung äusserst simpel > > das hier ist aber doch offensichtlich eine Hausaufgabe oder so, also > wird er "seinen" Code auch erklären können müssen...und wenn er schon > nicht versteht, was seine eigene kurze Funktion macht, wird er bei PeDas > Entprellung erst recht nicht durchsteigen... Im Artikel Entprellung ist die PeDa Entprellung dem Prinzip nach auch erklärt und ich hab auch mal eine Langform dafür geschrieben, die nicht so dicht gepackt ist und eigentlich nicht schwer verständlich sein sollte. Ist ja schliesslich nur ein Zähler pro Taster und ein bischen Logik in einem Timer-Interrupt, die bestimmt wann der Zähler um 1 verringert bzw. rückgesetzt wird. Am Timer allerdings führt kein Weg vorbei. Entprellung ist unmittelbar mit einer zeitlichen Komponente verknüpft. Und da gibt es nur 2 Möglichkeiten. Entweder delay oder Timer. Wenn delay nicht erlaubt ist, bleibt nur Timer. Was ja auch die vernünftigere der beiden Lösungen ist.
:
Bearbeitet durch User
> keine Ahnung, müsste man genauer analysieren. > Auf jeden Fall ist es keine Entprellung, denn Entprellung bedeutet > immer, dass es in irgendeiner Form eine hinreichend lange Zeitkomponente > geben muss das warten habe ich doch eigentlich in den geschweiften klammern bei dem while in der funktion taster_was_pressed eingebaut da steht das so da: while (!(PIND&(1 << input_bit))) {} //geht das nicht ? >Da dieses hin und herschieben aber > um Zehnerpotenzen schneller geht als das Tastenprellen, ist irgendeiner > der returns erreicht noch ehe der Taster mechanisch überhaupt eine > Chance hatte zu prellen. qed. Das war mir nicht bewusst, danke. > Ich kann mich nur immer wieder wiederholen. > Die PeDa Entprellung mittels Timer-Interrupt ist zwar nicht leicht zu > verstehen, dafür aber in der Anwendung äusserst simpel Ah okay, danke dir für den Tipp. Timer- Interrupts darf ich noch nicht verwenden, muss noch die externen Interrupts verwenden, so ist die Aufgabenstellung xD. Aber ich schaus mir zusätzlich an, danke dir.
Justus Skorps schrieb: > Tho Wes schrieb: >> Dann sag mir bitte genau, was die Funktion "taster_was_pressed" bewirkt. > > omg. kann es sein, dass du gar nicht weißt, wie sich Prellen auswirkt? Das könnte allerdings sein, dass es hier ein gewaltiges Begriffs-Missverständnis gibt.
> Am Timer allerdings führt kein Weg vorbei. > Entprellung ist unmittelbar mit einer zeitlichen Komponente verknüpft. > Und da gibt es nur 2 Möglichkeiten. Entweder delay oder Timer. Wenn > delay nicht erlaubt ist, bleibt nur Timer. Was ja auch die vernünftigere > der beiden Lösungen ist. Ah, da ist der Groschen gefallen, das wusste ich garnicht. Wollte das ganze ohne zeit realisieren. Man merkt's das das forum was bringt^^. Nochmals danke, und dann sage ich mal topic closed hier im forum, und ich schau mir nochmals die Beiträge an.
Tho Wes schrieb: > Das ist nicht ganz richtig, wenn ich die Lösung nachvollziehen kann, > habe ich auch möglichkeiten aufgefasst, wie man ein Problem umsetzt. Das ist der falsche Ansatz. Selbst auf die Lösung kommen ist extrem wichtig! Lösung produzieren -> Fehler finden, verstehen, lösen -> Lösung 2 produzieren -> Fehler finden und verstehen -> ... and so on. Deine Variante lässt dich spätestens dann scheitern, wenn es dir keiner vorkaut und es mal keine fertige Lösung (hallo reale Welt!) gibt und eigene Kreativität gefragt ist. Das Forum hat dir doch eigentlich alles geliefert. Ich kaue mal vor: 1) Verstehe was Prellen macht. Verstehe den Unterschied zwischen langem Tastendruck und Prellen. Jetzt solltest du wissen wieso deine Methode nicht zur Entprellung beigetragen hat. 2) Erkennen, dass man zur Entprellung nach einem Tastendruck eine gewisse Zeit weitere Tastendrücke ignorieren sollte 3a) Fertige Methoden zur Entprellung nehmen (das MC Wiki liefert da ja x Varianten) oder 3b) Eigenen Code dafür schreiben -> da Delay Funktionen nicht erlaubt sind, Warten nach einem Tastendruck per Timer realisieren.
Ah zu spät. Wenn du weder Timer noch Delay verwenden darfst, bietet dir das MC Wiki ja die Flankenerkennung an, die ohne Zeitkomponente auskommt (aber hier u.U. ungenügend ist).
Tho Wes schrieb: > Ah okay, danke dir für den Tipp. Timer- Interrupts darf ich noch nicht > verwenden, muss noch die externen Interrupts verwenden, so ist die > Aufgabenstellung xD. Aber ich schaus mir zusätzlich an, danke dir. Wenn du Timer nicht benutzen darfst, delay nicht erlaubt ist, dann gibt es keine Software-Lösung für das Entprell-Problem. Bist du sicher, dass du Entprellen überhaupt behandeln musst? Denn Entprellen macht das Problem schweirig. Kann man Entprellen ignorieren (was in Produktionscode natürlich unsinnig ist, aber man kann ja nicht alles auf einmal lernen), dann ist eine Tastenerkennung nichts anderes als eine Flankenerkennung. Die wiederrum ist einfach zu realisieren. Kurz und gut: Bist du sicher, dass du selbst nicht eine einfache Hausaufgabe eigentlich schwieriger machst, als sie sein muss? Einfach nur, weil du eine Perfektion erreichen willst, die du mit deinem Wissen noch gar nicht erreichen kannst? (Denn Hand aufs Herz. Der Code im Eröffnungsposting ist ziemlich konfus) Weiters: Ist das hier > Realisiert werden soll das ganze durch einen externen Interrupt über INT0_ect auf Pin4 auf'n Atmel. Teil der Aufgabenstellung oder ist es etwas, was du selbst ins Spiel gebracht hast, in der Annahme das ein externer Interrupt dir helfen kann?
:
Bearbeitet durch User
Karl Heinz schrieb: > Wenn du Timer nicht benutzen darfst, delay nicht erlaubt ist, dann gibt > es keine Software-Lösung für das Entprell-Problem. Okay > Bist du sicher, dass du Entprellen überhaupt behandeln musst? Ja, ich muss das Entprellen (verhindern des"Nachschwingens" eines schalters) behandeln. > Entprellen macht das Problem schweirig. Kann man Entprellen ignorieren > (was in Produktionscode natürlich unsinnig ist, aber man kann ja nicht > alles auf einmal lernen), dann ist eine Tastenerkennung nichts anderes > als eine Flankenerkennung. Die wiederrum ist einfach zu realisieren. Flankenerkennung wollte ich auch durchsetzen,indem ich mein MCUCR auf fallende Flanke programmiert hab. Drücke ich jedoch den Taster, so muss ich manchmal mehrmals den Taster drücken, dass das passiert, was ich haben will. > Kurz und gut: Bist du sicher, dass du selbst nicht eine einfache > Hausaufgabe eigentlich schwieriger machst, als sie sein muss? Einfach > nur, weil du eine Perfektion erreichen willst, die du mit deinem Wissen > noch gar nicht erreichen kannst? Es ist keine Hausaufgabe, sondern eine Einarbeitung in das Thema. Ja, da könntest du recht haben. Aber ich versuch auch viel zu dokumentieren udn zu vereinfachen, wie es nur geht. > Weiters: Ist das hier >> Realisiert werden soll das ganze durch einen externen Interrupt über INT0_ect > auf Pin4 auf'n Atmel. > Teil der Aufgabenstellung oder ist es etwas, was du selbst ins Spiel > gebracht hast, in der Annahme das ein externer Interrupt dir helfen > kann? Das ist die Aufgabenstellung. Der Pin4 ist ja der PIND2 auf den Board, und somit hängt da der Schalter dran, der Auf masse schaltet. Durch das Drücken des Schalters wird ein Interrupt ausgelöst.
Karl Heinz schrieb: > Am Timer allerdings führt kein Weg vorbei. > Entprellung ist unmittelbar mit einer zeitlichen Komponente verknüpft. > Und da gibt es nur 2 Möglichkeiten. Entweder delay oder Timer. Es gibt noch eine weitere Möglichkeit, nämlich ein RC-Glied zu verwenden. Ein Beitrag dazu steht in der Codesammlung. Ich will hier aber nicht Alles wieder vorkauen.
M. N. schrieb: > Karl Heinz schrieb: >> Am Timer allerdings führt kein Weg vorbei. >> Entprellung ist unmittelbar mit einer zeitlichen Komponente verknüpft. >> Und da gibt es nur 2 Möglichkeiten. Entweder delay oder Timer. > > Es gibt noch eine weitere Möglichkeit, nämlich ein RC-Glied zu > verwenden. Schon klar. Ich hatte mich dann in weitere Folge noch auf die zusätzliche Einschränkung 'in Software' geeinigt. Damit sind Hardware-Lösungen in dieser Einschränkungen automatisch nicht mit drinnen. Ausserdem hat er sein Board erwähnt und ich ging davon aus, dass eine Board-Modifikation nicht erlaubt ist.
:
Bearbeitet durch User
Karl Heinz schrieb: > Wenn du Timer nicht benutzen darfst, delay nicht erlaubt ist, dann gibt > es keine Software-Lösung für das Entprell-Problem. Es gibt immer eine Lösung:
1 | #ifndef F_CPU
|
2 | #error F_CPU not defined.
|
3 | #endif
|
4 | |
5 | #include <avr/io.h> |
6 | #include <avr/interrupt.h> |
7 | |
8 | volatile long nDebounce = 0; |
9 | |
10 | #define DEBOUNCE F_CPU / 400
|
11 | |
12 | int main(void) |
13 | {
|
14 | DDRB |= (1 << 0); |
15 | PORTD |= (1 << 2); |
16 | EIMSK |= (1 << INT0); |
17 | sei(); |
18 | |
19 | while(1) |
20 | {
|
21 | if(nDebounce == DEBOUNCE) |
22 | {
|
23 | PINB |= (1 << 0); |
24 | nDebounce++; |
25 | }
|
26 | |
27 | if((nDebounce != DEBOUNCE) && (PIND & (1 << 2))) nDebounce = 0; |
28 | }
|
29 | }
|
30 | |
31 | ISR(INT0_vect) |
32 | {
|
33 | if (nDebounce < DEBOUNCE) nDebounce++; |
34 | }
|
Bisschen doof ist nur, dass er unbedingt den Interrupt benutzen muss. mfg.
:
Bearbeitet durch User
Danke auch Dir für die Info, aber ich hätte dazu mal einige Fragen.
(Hab das Problem wie gesagt bereits mit der Debounce- Methode vom PeDa
gelöst)
> EIMSK |= (1 << INT0);
Für welches Register steht EIMSK? Im Atmega8 Datenblatt kontte ich es
nicht finden. Ist damit das GICR gemeint?
Warum teilst du anfangs die F_CPU exakt durch 400?..Es könnten auch 500
oder 800 sein..
Mit freundlichen Grüßen,
TommyProg
Tho Wes schrieb: > Für welches Register steht EIMSK? Im Atmega8 Datenblatt kontte ich es > nicht finden. Ist damit das GICR gemeint? Das ist Atmega48..328. Beim 8er ist das GICR. Tho Wes schrieb: > Warum teilst du anfangs die F_CPU exakt durch 400?..Es könnten auch 500 > oder 800 sein.. Die 400 habe ich eingesetzt, damit man das mit der Hand testen kann. Wenn man mit dem Finger den Specht macht, wird das weggefiltert. Der Wert darf gern etwas grösser sein. Die Funktion ist nicht unbedingt zur Nachahmung empfohlen. Ich wollte nur zeigen, dass es ohne Delay und Timer auch geht. mfg.
ah okay, trotzdem danke^^. Mfg, tommyProg
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.