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.
>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
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?
> 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)
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