moin moin, Ich hab inzwischen ein kleineres größeres Problem in meinem Projekt. Ich möchte ein Lauflicht annimieren, indem ich mit einem Taster die Zeit messe. D.h. die Uhr läuft los und wenn ich den Taster drücke, wird diese Zeit festgehalten. Diese Zeit ist die komplette Umlaufzeit der LEDS. D.h. ich dividiere Zahl durch 12, da ich 12 LEDS habe. Diese sollen dann in diesem Takt immer zu viert im Kreis rum aufleuchten. Wenn ich wieder diesen Taster drücke, soll wieder das gleiche passieren. Wenn ich den Taster nicht gedrückt habe, bis die Uhr ein Overflow ausgibt, soll jede 2. LED leuchten. Beim nächsten Interrupt jede andere zweite LED. Mein Problem ist, dass irgendein Problem mit dem Taster besteht. Wenn ich den Taster drücke fängt mal das Lauflicht an, mal bleibt es stehen (das ist der Teil den ich am wenigsten verstehe), manchmal aber eben nicht immer fängt es wieder von vorne an zu leuchten, manchmal dreht sich das Rundlicht auch einfach weiter. Ich verstehe nicht, warum da so ein Fehler ist. Bitte erklärt mir wo und warum ich den Fehler habe. Anbei geb ich die Dokumente, in denen ich den Fehler vermute. Sofern überhaupt noch einer da ist. Thanks im voraus
Ich hab mir den Code jetzt nicht angeschaut (leider Assembler), aber ich tippe mal darauf, dass der Taster nicht entprellt ist. Tipps dazu hier: http://www.mikrocontroller.net/articles/Entprellung
ist das entprellen nur bei tastern nötig, oder allgemein immer. Ich möchte später statt dem taster einen "Magnettaster" einbauen. also eine Art Taster, die durch einen Magneten ausgelöst wird. danke schon für diene Hilfe, probiers gleich mal aus
ok, ich hab jetzt in meiner Interrupt-Schleife noch folgendes eingefügt: //Ist wirklich der Taster gedrückt? ldi temp, PIND sbrc temp, 7 reti Diese Abfrage kommt etwas später. somit müsste die Taste eigentlich entprellt sein, nur irgendwie spinnt das Lauflicht immernoch. Um es in unterschiedliche Fälle zu teilen: 1. Das Licht geht auf den Anfangsstand, wie es soll zurück, bleibt jedoch stehen 2. Das Licht bleibt dort stehen, wo es war, als die Taste gedrückt wurde 3. Das Licht läuft 3 LEDS weiter, solange die Taste gedrückt ist. Sobald ich sie los lasse, bleibt das Licht wieder stehen. 4. Keine Reaktion, das Licht bleibt da stehen, wo's war bzw. läuft eiskalt weiter. Wo ist mein Fehler? Ich begreife es nicht Danke für Hilfe im voraus
ich habe nun den Taster-Interrupt auf INT0 geändert. Somit müsste das Tastenentprellen nicht notwendig sein, da der Interrupt nur bei einer steigenden Flanke reagiert. Trotzdem spinnt meine Schleife noch. Kann mir keiner helfen? Ich habe nochmal den aktuellen Stand des Programms angehängt. Thanks for help
Hi >Somit müsste das >Tastenentprellen nicht notwendig sein, da der Interrupt nur bei einer >steigenden Flanke reagiert. Tastenprellen bedeutet mehrere steigende und fallende Flanken hintereinander. Und poste bitte deine Dateien als .asm und nicht als .txt. MfG Spess
Fabian S. schrieb: > ich habe nun den Taster-Interrupt auf INT0 geändert. Somit müsste das > Tastenentprellen nicht notwendig sein, da der Interrupt nur bei einer > steigenden Flanke reagiert. Rate mal, was bei einem prellenden Taster passiert...? Da kommen viele steigende (und fallende) Flanken hintereinander. Auf den ersten Blick sieht Dein Code nicht so aus, als würde er das korrekt behandeln. Edit: Zu langsam ;-)
okay, ich hab jetzt in dem code einfach später nochmal die tastenabfrage, wenn die taste immernoch gedrückt ist, bleibt er im interrupt, ansonsten geht er wieder zurück ins Hauptprogramm. Aber ich kann nicht glauben, dass da das Problem dran liegt. Wenn der Externe-Tasten-Interrupt 2mal ausgeführt wird, würden nicht nur die ersten 4 LEDS leuchten, sondern eher alle.
Ist eine Sache der Vorliebe, aber das Entprellen einer Taste mit z.B. einem 22 pF Kondensator finde ich viel einfacher.
ich hab blöderweise keinen 22 pF Kondensator da, aber ich habe jetzt 2 Kondensatoren in reihe geschaltet. (einer hat 100yF, der andere 250yF) Jetzt erkennt man schon ein Muster, erst leuchten die ersten vier, dann andere vier, danach wieder die ersten vier. etc. Warum bleibt das dann aber mittendrinnen stehen? und läuft nicht weiter, bzw. warum sieht man nicht alle LEDS flackern? Theoretisch müsste er das vorgegebene Muster irre schnell durchgehen. Wenn ich den Taster austausch und mit einem Magneten und dem entsprechenden Sensor (weiß grad nich wie man das nennt) austauscht, brauch ich dann auch nen Kondensator? Bzw. irgendeine Methode zum entprellen? Danke für die Hilfe
Fabian S. schrieb: > (einer hat 100yF, der andere 250yF) so ein Yokto-Farad ist aber ziemlich klein ... http://de.wikipedia.org/wiki/Yokto
moin moin, leider ist mein Problem immer noch nicht weg. Ich habe nun einen Kondensator mit 80 nanoFarad angeschlossen, der die Taste entprellen soll. Trotzdessen spinnt noch mein Licht. Wo könnte noch ein Fehler sein? @Wegstaben Verbuchsler Lern erstmal selber das schreiben, bevor du dich über andere lustig machst. Sinnlose Kommentare sind hier genau wie überall unerwünscht. Ich denke jeder, der das hier ernsthaft durchliest, weiß dass ich mit "y" eigentlich mikro meinte. @Spess53 Ich hab mir das Tutorial schon einmal durchgelesen, über die Hardwareenptrellung steht leider nix drinnen, deswegen wusst ich davon nix (ich bin noch voll am einsteigen und versuchten durchsteigen).
hallo Fabian Schau einmal hier: http://newbiehack.com/MicrocontrollerTutorial.aspx Unter Button Debouncing und Software Debounce findest Du einiges zum Thema. Im Button Game wird ebenfalls ein Lauflicht implementiert. Der Code ist in C.
Hi >Ich hab mir das Tutorial schon einmal durchgelesen, über die >Hardwareenptrellung steht leider nix drinnen, deswegen wusst ich davon >nix (ich bin noch voll am einsteigen und versuchten durchsteigen). Gibt es aber schon: http://www.mikrocontroller.net/articles/Entprellung Allerdings ist eine Softwareentprellung flexibler. Wenn man das Prinzip aus meinem ersten Link mal richtig verstanden hat wird man die Hardwareentprellung schnell wieder vergessen. Übrigens sind solche Konstrukte >clock: >#include "ClockOverflow_Interrupt.asm" >reti recht gewöhnungs bedürftig. MfG Spess
sry, bezüglich des gewöhnungsbedürftigen Programmes. Mir ist es einfach irgendwann zu viel Code für ein Dokument geworden. Deswegen hab ich eiskalt alles in andere dokumente geschoben. Ich wusste nicht, wie ich es hätte besser machen können. Wie vorhin schon geschrieben bin ich noch blutiger Anfänger. Ich bin für jeden hilfreichen Tip dankbar. Inzwischen hab ich im Programm eine Entprellabfrage eingebaut, indem einfach nach 10 Befehlen des Interrupts nochmal nachgefragt wird, ob der Button immernoch gedrückt ist. Zusätzlich hab ich noch parallel zum Taster einen Kondensator. Trotzdessen versteh ich nicht, warum das Programm so spinnt. Es bleibt aus unersichtlichen Gründen (also zumindest für mich) manchmal einfach stehen. z.b.: ich drücke das erste mal den Knopf, die ersten 4 LEDS gehen an, laufen aber nicht wie sie sollen weiter. Dann drücke ich zum zweiten mal den Knopf, das Lauflicht läuft. Das dritte mal gedrückt, die LEDS bleiben wieder irgendwo stehen, ohne wieder zum Anfang zu springen, was sie eigentlich doch mindestens tun sollten. Das ist mein größtes Verständnisproblem: Warum bleiben die LEDS einfach stehen und laufen dann nicht mit der neuen Zeit weiter, bzw. setzen sich nicht auf den Anfang zurück?
inzwischen kann ich nicht mehr glauben, dass noch ein Fehler an meinem Taster ist, ich habe zum einen mehrere Kondensatoren (22, 100 und 250 mikroFarad) ausprobiert, zum anderen habe ich nun noch eine Abfrage routine in der Software, ob der Taster wirklich gedrückt ist/war? Kann mir keiner weiter helfen? So langsam bin ich verzweifelt und weiß echt nicht mehr weiter.
Fabian S. schrieb: > Lern erstmal selber das schreiben, bevor du dich über andere lustig > machst. Sinnlose Kommentare sind hier genau wie überall unerwünscht. Ich > denke jeder, der das hier ernsthaft durchliest, weiß dass ich mit "y" > eigentlich mikro meinte. Ganz sinnlos ist mein Kommentar nicht. So richtig mit den Dimensionen bist du scheinbar nicht vertraut. Daher der Link, der die verschiedenen Dimensionsbezeichnungen aufführt. Schau mal nach, was die Vorsilbe µ (Mikro) und p (Pico) bedeuten, wieviel 100 µF in Reihe zu 250 µF ergibt, und ob das irgendwie zu 30 pF passt. und dann meldest du dich nochmal mit sinnvollen Fragen, ob oder warum eine Hardware-Tastenentprellung mit diesen Kapazitätswerten funktioniert. Kleiner Tip: es gibt auch in der anderen Richtung (größerer Dimensionen) gewisse Beschränkungen. Eine Wurst von 1 m Länge kann man noch gut essen, bei einer Wurst von 1000 Km Länge (ist auch 10 hoch 6 abweichend) wird das schon schwieriger ...
ich habs inzwischen kapiert, dass da ein "kleiner" unterschied ist (Achtung: "" -> ironie!) Nur leider hat mich deine Behlerung über die größenverhältnisse nicht weitergebracht, da das Problem immernoch da ist, trotzdessen dass ich unterschiedliche Kondensatoren angeschlossen habe und auch ein Programm zur Tastenentprellung geschrieben hab. Kannst du dir ja mal anschauen, den entsprechenden Programmteil dazu habe ich oben angefügt. Kannst du sonst noch hilfreiche Kommentare geben? so langsam bin ich verzweifelt, da ich an diesem Problem schon ca 1/2 Monat hänge
1 | .include "tn2313def.inc" |
2 | |
3 | .def temp = r16 //Register für alles Kann jederzeit verwendet werden |
4 | .def bout = r17 //Register für Ausgang PORTB |
5 | .def dout = r18 //Register für Ausgang PORTD |
6 | .def divl = r19 //Register zum Speichern der Zeit |
7 | .def divh = r20 //Register zum Speichern der Zeit |
8 | .def matchL = r21 //Register zum Vergleichen von MatchA und Clock |
9 | .def matchH = r22 //ehemals divo; jetzt matchH //Register für Divisor der Division Kann außerhalb der Division verwendet werden |
10 | .def xbit = r23 //Register zum 8Bit dividieren Kann außerhalb der Division verwendet werden |
11 | .def stand = r24 //Register zur Ausgabe des Idle-Modes |
12 | .def exti = r25 //Register für den externen Interrupt |
13 | |
14 | //-------------------- |
15 | //Interruptaktivierung |
16 | //-------------------- |
17 | |
18 | .org 0x000 //Reset |
19 | rjmp main |
20 | .org 0x0004 //Clock-Match-A-Interrupt |
21 | rjmp matcha |
22 | .org 0x0005 //Clock-Overflow-Interrupt |
23 | rjmp clock |
24 | .org 0x000B //External Interrupt (PINB,7) |
25 | rjmp extpin |
26 | |
27 | |
28 | main: |
29 | |
30 | #include "Initialisierung.asm" |
Bissi wenig Vektoren oder? Ich glaube Du hast nicht nur das Problem der entprellung.
wieso nur? Ich glaube das Problem mit der Entprellung gelöst zu haben. Außerdem ist mein Programm nicht sehr groß, diesbezüglich brauche ich nicht so viele Vektoren. Mein Programm läuft ab und zu auch so wie es soll, nur eben nicht bei jedem Tastendrücken. Manchmal läuft es wie es soll für 2 - 3 Tastendrücke, danach bleibt das lauflicht einfach stehen. Probiere ich aber das Lauflicht alleine aus, also mit einem Extra Programm, Taste drücken -> Lauflicht macht einen Schritt weiter, dann läuft es auch. Aber ich weiß nicht wo noch ein Fehler sein sollte. Kommentare, wie probiere es mal linksherum, bringen nichts, außer dass man genervt wird. Wenn noch eine Erklärung dazu geschrieben wird, bzw. min. ein Link zu einer Erklärung, versuche ich auch gerne das zu verstehen und nach zu vollziehen
Hi Das was ich weiter oben angesprochen habe ist nicht nur gewöhnungsbedürftig, sonder auch extrem fehleranfällig: Aus ExternalPin_Interrupt.asm: >weiter: > clc > cpi taste, 0x07 //Wie oft, muss der Taster auf 1 >gewesen sein in > brsh weiter2 > reti >weiter2: > > ldi temp, PIND > sbrc temp, 7 > reti Hauptprogramm: >extpin: >#include "ExternalPin_Interrupt.asm" >reti Wenn in deiner ISR die Labels 'weiter' und 'weiter2' angesprungen werden wird theoretisch reti zweimal ausgeführt und dein Controller würde sich dadurch ins Nirwana verabschieden. Aber dazu kommt es nicht, da durch den unbereinigten Stack der Controller schon bein ersten reti macht. Gewöhne einfach an, das eine ISR eine Austrittsstelle hat. Und an der und nur an der sind die notwendigen 'POPs', Rekonstruktion des SREG und das RETI. Alles andere ist Murks. MfG Spess
danke für den Hinweis, Murks ist beseitigt, statt dem reti kommt nun ein Verweis zum Ende des Interrupts. Wie geht man am besten vor, wenn man den Fehler nicht findet und keiner Hilfe hat, die das Problem löst?
Du das war gut gemeint und ein kleiner Wink. Ich bin auch neuling und habe mit dem 2313 angefangen und daher meine ich die Vektoren noch zu wissen.
1 | .org 0x00 ; Reset-Address |
2 | rjmp Reset |
3 | .org 0x01 ; External Interrupt0 Vector Address |
4 | reti |
5 | .org 0x02 ; External Interrupt1 Vector Address |
6 | reti |
7 | .org 0x03 ; Input Capture1 Interrupt Vector Address |
8 | reti |
9 | .org 0x04 ; Output Compare1 Interrupt Vector Address |
10 | reti |
11 | .org 0x05 ; Overflow1 Interrupt Vector Address |
12 | reti |
13 | .org 0x06 ; Overflow0 Interrupt Vector Address |
14 | reti |
15 | .org 0x07 ; UART Receive Complete Interrupt Vector Address |
16 | reti |
17 | .org 0x08 ; UART Data Register Empty Interrupt Vector Address |
18 | reti |
19 | .org 0x09 ; UART Transmit Complete Interrupt Vector Address |
20 | reti |
21 | .org 0x0a ; Analog Comparator Interrupt Vector Address |
22 | reti |
Und es ist nicht wichtig wie groß dein Programm wird oder ist. es ist wichtig sie alle zu behandeln.
ok, sry, ich hab die Vektoren auf die Register bezogen gehabt. Wie finde ich am besten einen Fehler? Das Programm bin ich schon mehrmals mit dem Debugger im Computer durchgegangen, da klappt es eigentlich so wie es soll. Nur auf der Hardware will es einfach nicht.
Unter anderem hatte ich hier die Falschen geschrieben. Das sind die Richtigen:
1 | .org 0x000 ; kommt ganz an den Anfang des Speichers |
2 | rjmp RESET ; Interruptvektoren überspringen |
3 | ; und zum Hauptprogramm |
4 | |
5 | reti ; IRQ0 Handler |
6 | reti ; IRQ1 Handler |
7 | reti ; Timer/Counter1 Capture Event |
8 | reti ; Timer/Counter1 Compare Match A |
9 | reti ; Timer/Counter1 Overflow |
10 | reti ; Timer/Counter0 Overflow |
11 | reti ; USART0, Rx Complete |
12 | reti ; USART0 Data Register Empty |
13 | reti ; USART0, Tx Complete |
14 | reti ; Analog Comparator |
15 | reti ; Pin Change Interrupt |
16 | reti ; Timer/Counter1 Compare Match B |
17 | reti ; Timer/Counter0 Compare Match A |
18 | reti ; Timer/Counter0 Compare Match B |
19 | reti ; USI Start Condition |
20 | reti ; USI Overflow |
21 | reti ; EEPROM Ready |
22 | reti ; Watchdog Timer Overflow |
23 | |
24 | RESET: ; hier beginnt das Hauptprogramm |
Ja den Teil hab ich inzwischen auch schon aus dem Datasheet abgeschrieben, mein Problem bleibt trotzdem bestehen, dass das Programm einfach nicht so will und ich inzwischen nicht mehr weiter weiß. Ich schreibe jetzt sämtliche Interruptschleifen in eigene Programme um diese abzukontrollieren, wo noch ein Fehler ist. Am Schluss füge ich wieder alle zusammen. Allerdings bezweifle ich, dass das so viel Sinn machen wird. Aber das werde ich am Schluss sehen.
schalte doch erstmal die leds mit jedem tastendruck eine weiter, oder (eine) an und aus. um den taster und die entprellung zu testen. nimm die falschen Cs beim taster weh, und mache es per software.
Okay, ich hab das "Programm" für den externen Interrupt fertig. Nun da, stell ich doch fest, dass in meiner Hardware ein Fehler ist. Zwischen welchen Dimensionen befinden sich normalerweise die Kondensatoren, die den Taster enptrellen sollen? Anbei das passende Programm
1 | brlo externerInterrupt0Ende |
Erkläre bitte mal was warum Du da machst.
Ist mir erst nach dem Upload aufgefallen. Am Anfang wollte ich gleich eine software enptrellung machen. Das ist der Rest davon. Mit Hardware entprellung (einem 250 microFarad Kondensator) funktioniert die Entprellung super. Softwareenptrellung läuft das noch nicht. Ab und zu wechselt die LED doppelt.
das ist inzwischen richtig interessant. Warum leuchtet die LED, die am 3. PIN von PORTB angeschlossen ist, auf, wenn ich den Taster drücke? Eigentlich müsste es wie vorhin auch, zwischen LED1 und LED2 hin und her wechseln.
1 | .. |
2 | .. |
3 | in temp, PIND |
4 | sbrc temp, 2 |
5 | inc counts |
6 | inc cicles |
7 | cpi cicles, 0xFF //Anzahl der Wiederholungen |
8 | brlo again |
9 | cpi counts, 0xFE //Anzahl der Bestätigung der gedrückten Taste |
10 | brlo externerInterrupt0Ende |
11 | .. |
12 | .. |
13 | externerInterrupt0Ende: |
14 | |
15 | out PORTB, temp |
Warum nur? Was machst Du da meit temp. Bzw. was machst Du da nicht?
ich glaub inzwischen seh ich den code vor lauter buchstaben nicht mehr. Danke. Jetzt mach ich erstmal pause, wenn ich schon so einen müll, fabrizier und nicht find. Danke
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.