Hallo, ich arbeite gerade den AVR-GCC-Tutorial durch. Bei den Interrupts komme ich nun nicht mehr weiter. Ich hab versucht in ein bereits bestehendes (funktionierendes) Programm einen externen Interrupt einzubauen. Ein Lauflicht soll dabei vom Interrupt unterbrochen werden und die LED's 5x gemeinsam aufleuchten lassen. Das Programm (siehe Anhang) lässt sich ohne Probleme compilieren und an den uC übertragen. Beim Testen läuft das ganze nur nicht wie geplant. Wenn der externe Interrupt ausgelöst wird scheint der uC nix zu machen oder die main-Funktion neu zu starten. Vielleicht kann mir ja wer von euch weiterhelfen. danke
Servus, nun ich seh grad in deinem Code, dass Main() oberhalb von den drei Subs steht. Sollte man wohl an letzter Stelle schreiben! Aber ansonsten bin ich grad ratlos! MfG MingliFu
Danke für deine schnelle Antwort. Da sich vor der Main-Funktion allerdings die Prototypen befinden sollte dies nicht das Problem sein. Außerdem denke ich würde das Programm nicht zu compilieren gehen wenn das der Fehler wäre.
ich hab einen Atmega8 verwendet und das Programm mit
1 | avr-gcc -O2 -c -mmcu=atmega8 -DF_CPU=1000000 main.c -o main.o |
bzw.
1 | avr-gcc -O2 -mmcu=atmega8 -DF_CPU1000000 main.o -o main.hex |
compiliert. Irgend etwas scheint der uC allerdings zu erkennen, da er beim betätigen des Tasters das Lauflicht von vorn startet.
>Irgend etwas scheint der uC allerdings zu erkennen, da er beim betätigen >des Tasters das Lauflicht von vorn startet. Vieleicht schliesst dein Taster ja die Betriebsspannung kurz. Drück mal ganz lange drauf und schau nach ob es irgendwo qualmt.
Hallo ohne zu wissen welcher uC nun genau genutzt wird kann man die getätigten Einstellungen schlecht überprüfen... Ich habe mal nachgeschaut was es beim ATMega32 für Register gibt diese decken sich jedoch nicht mit den hier beschriebenen Registern. Daher wäre es nett wenn du nochmal kurz sagen könntest welchen uC du benutzt.
@Bjoernc Das hat er doch geschrieben, zwar nicht im ersten Beitrag aber immerhin... Ich vermute mal dass es zu einem Prellen kommt, und da der Befehl blink(5) wohl eine ganze Sekunde(!!!) für sich beansprucht, kann das nicht gut gehen. Meine Empfehlung: 1. Einen kleinen Kondensator an den Interrupt-Eingang legen, das sollte das Prellen verhindern (vielleicht 100nF, weiss auch nicht, einfach ausprobieren). 2. Bei der Interrupt-Routine nur eine Variable setzen, und das blink(5) in der Hauptschleife abarbeiten, danach die Variable wieder zurücksetzen. Dann kann die Interruptroutine nicht mehr mehrmals gleichzeitig aufgerufen werden. mfg
>Dann kann die Interruptroutine nicht mehr mehrmals >gleichzeitig aufgerufen werden. Das kann sie sowieso nicht. Wenn schon dann mehrmals nacheinander.
holger schrieb: >>Dann kann die Interruptroutine nicht mehr mehrmals >>gleichzeitig aufgerufen werden. > > Das kann sie sowieso nicht. Wenn schon dann > mehrmals nacheinander. Hmm ja irgendwie logisch...aber ich dachte es gäbe Probleme wenn Interrupts auftreten bevor der letzte Interrupt abgearbeitet wurde? Aber wenn ich es mir jetzt genau überlege werden dann wohl einfach Interrupts übersprungen, was in diesem Fall egal wäre. Aber ich würde meinen, die feine Art ist das nicht, so wie es jetzt gemacht ist. Wenns kein Softwarefehler ist tippe ich auch mal auf einen Kurzschluss ;) Oder gehen die LEDs nicht aus solange du den Interrupt aktivierst?
1200 schrieb:
1 | avr-gcc -O2 -mmcu=atmega8 -DF_CPU1000000 main.o -o main.hex |
> compiliert.
Und mit der main.hex programmierst du dann den Controller, richtig?
Dann wird nie irgendein Interrupt funktionieren. Was der Compiler
ausspuckt ist eine ELF-Datei. Die auf den Controller zu ladenden Daten
müssen aus dieser erst mittels objcopy extrahiert werden. Tu dir selbst
einen Gefallen und verwende ein bekanntermaßen funktionierendes
Makefile, z.B. ein von MFile generiertes.
Wie sieht denn die Beschaltung hardwareseitig aus? Und: > Wenn der externe Interrupt ausgelöst wird scheint der uC nix zu machen > oder die main-Funktion neu zu starten. Ersteres kann man mit einer extra(!) LED gut kontrollieren, die am Anfang des Interrupts kurz(!) eingeschaltet wird, letzteres mit ebendieser LED die am Anfang von main() lange(!) eingeschaltet wird. Wenn selbige LED dann noch einen ganz "eigenen" Pin (im Sinne von 'am selben Port hängt sonst nix dran wo man sich verhauen könnte' - augenscheinlich hast Du die Ports B und C noch vollständig frei, da wär dann wann hüpsches mit dabei für eine extra Status-LED) bekommt, dann kann man Resets & co gut verfolgen.
@ Urban, ja das habe ich auch gesehen als ich meinen Beitrag abgeschickt habe. Die Vermutung das der Schalter prellt, ist soweit ja ok nur würde die ISR dann ja nur 2 mal aufgerufen werden einmal den quasi regulären aufruf und dann noch einen Aufruf durch das prellen dh. der uC müsste dann nach 2 Sekunden wieder normal laufen aber anscheinend macht er das nciht. hmm mal eine andere idee, kann es nicht sein, dass der ExtIntr1 ausgelöst wird da im Register GIFR evtl. ncoh ein falscher wert steht? Das würde das Phaenomenen erklären, dass der uC resetet wird da der Interruptvector ja nicht existiert bzw. auf die startaddr 0x0000 steht.
Bjoernc schrieb: > hmm mal eine andere idee, kann es nicht sein, dass der ExtIntr1 > ausgelöst wird da im Register GIFR evtl. ncoh ein falscher wert steht? Nein > Das würde das Phaenomenen erklären, dass der uC resetet wird da der > Interruptvector ja nicht existiert bzw. auf die startaddr 0x0000 steht. Du ratest. Sieh zu, dass du vom Raten weg kommst. g457 hat schon erklärt wie man das macht. Und den Rat von Stefan Ernst solltest du dir auch zu Herzen nehmen. (Ich tipp auch auf einen Kurzschluss durch den Taster, wenn es nicht der Fehler im Makefile ist)
Nur mal so ganz nebenbei: Dein Programm funktioniert auf einem Atmega8. Habs grad mal ausprobiert.
das Programm läuft jetzt fehlerfrei auf dem uC. Das Prellen des Tasters wars nicht. Ich hab den Kondensator aber trotzdem drinnen lassen als Sicherheit (Danke für den Tipp!). Im Endeffkt lags tatsächlich am Makefile. Ich hab mir hier auf der Seite ein anständiges Makefile gehohlt, daraufhin hats sofort funktioniert. Danke für eure Hilfe!
Hallo zusammen, ich hab bezüglich der Interruptverwendung im Atmega8-Datenblatt folgendes gelesen: "Note that recognition of falling or rising edge interrupts on INT0 and INT1 requires the presence of an I/O clock, described in “Clock Systems and their Distribution” on page 23" Das kann aber nicht heißen, dass ich da einen externen Taktgeber oder sowas brauche? Ich kann das gerade nicht richtig übersetzen. Also einfach Signal an INT0 oder INT1 legen, und das Programm erkennt den Interrupt. Richtig? Danke Christian
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.