www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ext. Interrupt


Autor: Magic Magicjon (magicjon)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,

ich habe ein kleines Problem mit den externen Interrupts.

Hardware:
uC: ATmega8@1MHz

Quellcode: im Anhang

Es geht dabei um folgendes:
An den Eingängen INT0 und INT1 des Atmegas liegt momentan dasselbe 
Signal. Dabei handelt es sich um ein Rechtecksignal mit einer 
Periodenlänge von ca. 4s mit einem Verhältnis von 50/50.

Der Atmega soll nun, sobald das Signal anliegt, zunächst auf eine 
steigende Flanke reagieren. Sobald ein Interrupt ausgelöst wird, startet 
Timer0 (ext. Interrupt0=INT0) und Timer2 (ext. Interrupt1=INT1). Beide 
Timer laufen mit einer Frequenz von ca. 977Hz (1MHz/1024). Ebenfalls 
wird in der ISR die Reaktion auf steigende und fallende Flanke der ext. 
Interrupts umgestellt.
Beide Timer lösen bei einem Overflow ebenfalls eine ISR aus. In ihr 
sollten die Ports PC0 und PC2, bedingt durch ihren derzeitigen Zustand, 
ein- bzw. ausgeschaltet werden.
Jetzt zu meinem Problem:
Eigentlich sollten die beiden Ports PC0 und PC2 nach meinem Verständnis 
beide zur etwa gleichen Zeit ein und ausgeschaltet werden.
Sprich also: Bei der ersten steigenden Flanke sollten PC0 und PC2 nach 
256/977Hz=0,26s eingeschaltet werden und nach der fallenden Flanke um 
ca. 0,26s verspätet ausgeschaltet werden. Und das ganze halt 
fortlaufend.
Leider passiert genau das nicht. Sie schalten nämlich beide im Wechsel. 
Sprich, bei der ersten steigenden Flanke schaltet PC0 verspätet ein und 
schaltet auch erst wieder nach der nächsten steigenden Flanke+0,26s aus. 
In diesem Moment schaltet dann PC2 ein und das ganze dann im Wechsel.

Kann mir da jemand weiter helfen, warum das so ist bzw. wie ich dieses 
Problem behebe? (Hoffe, ich konnte mich deutlich ausdrücken bzw. das 
Programm erklärt fragen)

Danke

Autor: Magic Magicjon (magicjon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, wie ich gerade selber feststellen musste, klappt irgendwie das 
umschalten im Register MCUCR in der ISR nicht. Sprich also, die 
erkennung von "nur steigende flanke" auf "steigende und fallende flanke" 
in der ISR geht so nicht.

Stellt sich nur die frage, warum nich? jemand eine idee?

Autor: Sascha Weber (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja - weil dum mit
>MCUCR = ((0<<ISC01) | (1<<ISC00))
die die anderen Bits löschst, und damit auf LOW-LEVEL Trigger 
umschaltest!

Sascha

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Magic Magicjon schrieb:
> Stellt sich nur die frage, warum nich? jemand eine idee?

nö, glaube ich auch nicht weil es dem atmel ziemlich egal ist ob er in 
einer ISR ist oder nicht,
Man kann es nicht mal sicher rausfinden ob man in einer ISR ist oder 
nicht. Es wird also vermutlich nicht daran liegen.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beim Umschalten kann evtl ein IRQ-Flag gesett werden, so daß direkt nach 
der ISR eine "Schein-IRQ" getriggert wird. Also entsprechende Flags nach 
Umsetzen von MCUCR löschen.

Bits in MCUCR (und anderen SFRs) löscht man nicht durch
  ... |= (0 << XXX)

Autor: Magic Magicjon (magicjon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:
> ja - weil dum mit
>>MCUCR = ((0<<ISC01) | (1<<ISC00))
> die die anderen Bits löschst, und damit auf LOW-LEVEL Trigger
> umschaltest!
>
> Sascha

ja, genau das habe ich gerade auch gemerkt ^^

so sollte es ja gehen oder ?


Für INT0:
MCUCR &= ((0<<ISC01) | (1<<ISC00) | (1<<ISC11) | (1<<ISC10));

Für INT1:
MCUCR &= ((1<<ISC01) | (1<<ISC00) | (0<<ISC11) | (1<<ISC10));

Autor: Magic Magicjon (magicjon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johann L. schrieb:
> Beim Umschalten kann evtl ein IRQ-Flag gesett werden, so daß direkt nach
> der ISR eine "Schein-IRQ" getriggert wird. Also entsprechende Flags nach
> Umsetzen von MCUCR löschen.
>
> Bits in MCUCR (und anderen SFRs) löscht man nicht durch
>   ... |= (0 << XXX)

nur war da kein Oder vor dem Gleichhaltszeichen

Autor: Sascha Weber (sascha-w)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein -
du musst mit AND nur die zu löschenden Bits ausmaskieren, und mit OR die 
anderen wieder setzen.

Sascha

Autor: Magic Magicjon (magicjon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sascha Weber schrieb:
> nein -
> du musst mit AND nur die zu löschenden Bits ausmaskieren, und mit OR die
> anderen wieder setzen.
>
> Sascha

ok, also meinst du der schreibt das SFR, welches zuvor so aussah
MCUCR = ((1<<ISC01) | (1<<ISC00) | (1<<ISC11) | (1<<ISC10));

mit
MCUCR &= ((0<<ISC01) | (1<<ISC00) | (1<<ISC11) | (1<<ISC10));

um so das dort nachher folgendes drin steht ?
MCUCR = ((0<<ISC01) | (1<<ISC00) | (1<<ISC11) | (1<<ISC10));

Autor: Magic Magicjon (magicjon)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
problem hat sich erstmal erledigt:-)

danke für eure hilfe

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.