www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupt mit ATmega328P an PCINT0


Autor: A. S. (21addo12)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

Eigentlich Programmiere ich PIC. Nun aber liegt ein ATmega328P vor mir, 
auf diesen möchte ich den PCINT0 Interrupt laufen lassen. Er soll 
ausgelöst werden wenn der PIN auf HIGH steht. Ich habe nun viele 
möglichkleiten ausprobiert, aber er springt mir nur beim Initialisieren 
in den Interrupt! Nun wollte ich fragen ob jemand erkennen kann was ich 
da falsch gemacht habe.

Den Port habe ich folgendermaßen Initialisiert dazu dann auch noch 
Interrupt enabled
 DDRB |= 0x00;

 PCICR |= (1 << PCIE0);
 PCMSK0 |= (1 << PCINT0);

Damit rufe ich den Interrupt auf:

 ISR(PCINT0_vect)
 {
  PORTD |= (1 << PD4);
 }


void main (void)
{
 sei();

 while(1)
 {
  PORTD &= ~(1 << PD4);
 }
}

Bei diesem Beispiel soll eine LED so lang leuchten wie der Interrupt 
anliegt.

Habe ich da was falsch gemacht?

Ich danke für Hilfe!

Grüße, Arthur

Autor: Qwertz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Habe ich da was falsch gemacht?

>Bei diesem Beispiel soll eine LED so lang leuchten wie der Interrupt
>anliegt.

Da liegt ein Verständnisproblem vor. Ein Interrupt ist kein "Zustand" 
sondern ein "Ereignis". Man kann demzufolge keine Bedingung 
programmieren die lautet: "solange der Interrupt anliegt".

Letztlich ist es sinnvoll in Ereignissen zu denken also z.B. 
"Pegelwechsel".

Schau Dir die Beschreibung im Datenblatt an. Da steht genau beschrieben, 
was der uC an Ereignissen erkennen kann und wie er darauf reagiert.

Autor: Qwertz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch was: Ein Interrupt wird nicht "aufgerufen" sondern durch ein 
äusseres Ereignis ausgelöst. Du kannst kontrollieren durch welche 
Ereignisse ein Interrupt ausgelöst wird. Aber Du löst ihn nie durch Dein 
Programm aus.

Autor: Helfer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Er soll ausgelöst werden wenn der PIN auf HIGH steht.
> DDRB |= 0x00;

Also du hast PortB als Eingang, korrekt für PCINT. Aber damit ist der 
LOW Ruhepegel nicht sichergestellt, denn die Eingänge sind Tristate! Du 
brauchst ein angeschlossenes Gerät mit sauberen TTL Pegeln oder einen 
externe Pull down Widerstände an deinen PCINT Eingängen.

Anm.: Bei DDRB |= 0x00; die VerODERung kontrollieren, die ist sinnlos.

Autor: A. S. (21addo12)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok! Sorry! Im eifer des schreibens/tippens und mit der tatsache das 
Freitag war g habe ich mich doch etwas unglücklich ausgedrückt!

Mir ist klar das ein Interrupt ein Ereignis ist und das man den nicht 
per Software auslösen kann.


Ich habe einen 2ten Controller der einen Port auf High zieht wenn er 
etwas empfängt!

@Qwertz:

Ich habe mich an das Datenblatt gehalten bin aber verwirrt da mein 
Controller  mehrere PCINTx Pins besitzt, ich aber in den Interrupt 
Vectoren nur PCINT0 - PCINT2 habe.

Daher meine Frage ob die Initialisierung passt oder ob ich da was 
übersehen habe!

@Helfer:
Danke für den Tipp! Werde das mal ändern und ausprobieren!

Autor: MWS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arthur Samol schrieb:
> Er soll
> ausgelöst werden wenn der PIN auf HIGH steht.

Es gibt beim ATM328 noch Int0 und Int1, diese können als "level 
triggered" konfiguriert werden und lösen solange aus, wie Low Level 
anliegt (level triggered geht nur Low Level)

Arthur Samol schrieb:
> Ich habe mich an das Datenblatt gehalten bin aber verwirrt da mein
> Controller  mehrere PCINTx Pins besitzt, ich aber in den Interrupt
> Vectoren nur PCINT0 - PCINT2 habe.

Für eine Gruppe PCINT-Pins ist jeweils eine ISR zuständig, darin muss 
man dann selbst rausfinden, welcher Pin getriggert hat.

Arthur Samol schrieb:
> Mir ist klar das ein Interrupt ein Ereignis ist und das man den nicht
> per Software auslösen kann.

Könnte man. Es ist erlaubt einen ext. Int zu definieren, auf diesen 
Portpin zu schreiben und damit den Int auszulösen.

Die Initialisierung lt. obigen Code ist ok, aber dennoch wird da nix 
leuchten, im Falle eines Flankenwechsels wird PD4 gesetzt und in der 
main sofort wieder gelöscht.

Um das gewünschte Verhalten über PCINT zu erreichen, müsste in der ISR 
PD4 bei steigender Flanke gesetzt und bei fallender Flanke gelöscht 
werden. Ob die Flanke steigend oder fallend war, lässt sich am Zustand 
von PB0 ablesen.

Autor: A. S. (21addo12)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Um den Thread sauber abzuschliessen.

Ich habe den Fehler gefunden lag nicht an obiger Initilisierung, diese 
hat gestimmt!

Der andere Controller hat gesponnen!

Danke an alle die mir geantwortet haben!

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.