www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik 2 Externe Interrup auf gleichen Vektor


Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute

ich steke momentan in einem kleinen Dilema.
Ich möchte aus  Fehler meinerseits nun zwei Externen Interupp auf den 
gleichen Vektor implementieren. PCINT0_vect
ich benutze den Atmega328p
die pins sind PB4 und PB2 auf PCINT0_vect.
PCICR|=(1<<PCIE0); // Pin Change Interrupt Enable   
  // für PCINT0_vect    
  DDRB &=~0x04;    // Eingang
  PORTB|=(1<<DDB4);    // PULL UP
  PCMSK0|=(1<<PCINT4);  // Maske für PCINT4

         // für PCINT0_vect      
  DDRB &=~0x02;    // Eingang
  PORTB|=(1<<DDB2);    // PULL UP
  PCMSK0|=(1<<PCINT2);  // Maske für PCINT2

SIGNAL(PCINT0_vect)
{
.
.
.

}
Initialisiert habe ich sie schon .wie kann ich dann implementieren  , 
dass sie unterschiedlich auf den selben INT-vect reagieren ???
Danke

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel schrieb:

> Initialisiert habe ich sie schon .wie kann ich dann implementieren  ,
> dass sie unterschiedlich auf den selben INT-vect reagieren ???

Ist das eine Fangfrage?
Indem du innerhalb der ISR feststellst, welcher Pin sich verändert hat?

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Ist das eine Fangfrage?
>
> Indem du innerhalb der ISR feststellst, welcher Pin sich verändert hat?

 ja danke
das hatte ich mir schon überlegt.  hier ist mein vorgehensweise
SIGNAL(PCINT0_vect)
{
         if(PCMSK0 & (1<<PCINT4))   // PB4
  {
          do etwas
          }
          else if(PCMSK0 && (1<<PCINT2))  // PB2
  {

          do was anderes
          }
}
[/c]

wenn ich es so implementiere  wird nur der erste "if auf PB4" gültig 
obwohl ich den Interupp auf den  PB2 erzeugen will.

ist so in ordnung oder ?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel schrieb:

> ist so in ordnung oder ?

Ähm.
Was soll das sein?
Du fragst in der ISR ab, ob das entsprechende Bit gesetzt ist, welches 
steuert, ob ein Interrupt ausgelöst werden darf.


Jetzt muss ich mir doch mal das Datenblatt zum µC holen.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könnte daran liegen das & und && nicht das selbe sind, und auch nicht 
das gleiche...

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Läubi .. schrieb:
> Könnte daran liegen das & und && nicht das selbe sind, und auch nicht
>
> das gleiche...

ich habe schon mit  "&"  und mit "&&"  probiert ohne erfolg. obwohl "&&" 
etwas total verkehr ist.

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nö, ich würde erstmal den Port (PINx) einlesen, damit Änderungen während 
der Auswertung unwirksam bleiben. Dann würde ich die interessierenden 
Bits der Portkopie prüfen und danach die Entscheidungen treffen.

In der ISR an PCMSKx herumzufummeln hat überhaupt keinen Sinn 
(Sonderfälle ausgenommen), denn das ist lediglich die Maske auf die 
Bits, die das Recht haben, den PC-Int auszulösen. PCMSKx setzt man 
bereits im Hauptprogramm, um unerwünschte Bits (Portpins) auszublenden.

...

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hannes Lux schrieb:
> Nö, ich würde erstmal den Port (PINx) einlesen, damit Änderungen während
>
> der Auswertung unwirksam bleiben. Dann würde ich die interessierenden
>
> Bits der Portkopie prüfen und danach die Entscheidungen treffen.
>
>
>
> In der ISR an PCMSKx herumzufummeln hat überhaupt keinen Sinn
>
> (Sonderfälle ausgenommen), denn das ist lediglich die Maske auf die
>
> Bits, die das Recht haben, den PC-Int auszulösen. PCMSKx setzt man
>
> bereits im Hauptprogramm, um unerwünschte Bits (Portpins) auszublenden.

ich versteht nicht so ganz dein Ansatz.

ich  prüfe in der ISR welche mask das Interrup ausgelöst hat. je nach 
dem wird entsprechende LED an bzw ausgeschaltet(z.B.).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es gibt kein Register, in dem du ablesen könntest, welcher der beiden 
Pins den Interrupt ausgelöst hat.
Also bleibt dir nur der Weg, das selbst herauszufinden, indem du dir den 
Pinzustand in einer Variablen sicherst und bei Auftreten eines 
Interrupts den aktuellen Zustand mit dem Gespeicherten vergleichst.

uint8_t oldPinB;

SIGNAL(PCINT0_vect)
{
  uint8_t newPinB = PINB;

  // die beiden interessanten Pins herausmaskieren
  newPinB &= ( 1 << PB4 ) | ( 1 << PB2 );

  // welche Pins haben sich verändert?
  uint8_t changed = newPinB ^ oldPinB;

  if( changed & ( 1 << PB2 ) ) {
    ... PB2 hat sich verändert
  }

  if( changed & ( 1 << PB4 ) ) {
    .. PB4 hat sich verändert
  }

  oldPinB = newPinB;
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Daniel schrieb:

> ich  prüfe in der ISR welche mask das Interrup ausgelöst hat.

Nein das tust du nicht.
Du prüfst, welcher PCI eingeschaltet ist.
Aber das hilft dir nichts. Du weißt ja, dass die beiden eingeschaltet 
sind :-)

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ich  prüfe in der ISR welche mask das Interrup ausgelöst hat.

Die Mask hast du vorher so gesetzt. Sie wird verwendet, um anzugeben, 
welche Pins deinen Interrupt auslösen können sollen. Sie hat nichts, 
aber auch gar nichts damit zu tun, welcher Pin den Interupt ausgelöst 
hat.

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok

Danke . Nun verstehe ich.

@ Karl heinz Buchegger

ich probiere mal über deinen Weg.   Schein also die einzige mögliche 
alternative jetzt.

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke es klappt soweit.

Gibt es eine möglichkeit bei den AVR  nur auf eine Flanke zu triggern?
kann sein das es ein register gibt oder was anderes
denn mommentan fürt er den Befehl zwei mal. wegen den 2 "Change". 
Low->High  und High->Low.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Datenblatt

Aber was hindert dich, bei Erkennung eines Wechsels noch mal in newPinB 
nachzusehen, wie der Pin zur Zeit steht? Ist er 1, dann kann es nur ein 
0->1 Wechsel gewesen sein. Ist er 0, kann es sich nur um einen 1->0 
Wechsel gehandelt haben.

Zusammengenommen erzählen dir die Werte in oldPinB und newPinB alles was 
du wissen möchtest.

PS: Den PCI auf Flanken umzustellen hilft dir nichts. Denn die 
Auswertung, welcher Pin der Schuldige ist, ist darauf angewiesen ALLE 
Pin-Wechsel mitzubekommen.

Autor: Andreas Vogt (tico)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Datenblatt

Das möchte ich unterstreichen.
Darin steht übrigens auch, dass es Flankentrigger für INT0 und INT1 auf 
den Pins PD2 und PD3 gibt. ;)

Autor: Daniel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ,

nach Aufbewahrung in der Schublade und neu Inbetriebnahme habe ich 
festgestellt , dass es nicht so rund läuft.
obwohl nur ein Taster gedrückt ist wird eine dann die tatsächliche 
Funktion aufgerufen.

weiß nicht wieso.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fang erst mal damit an, deine Symptome und die Frage in einem 
verständlichen Deutsch zu formulieren.
Und dann solltest du auch noch bedenken, dass Fehlersuche ohne das 
entsprechende Programm immer etwas schwierig ist.

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.