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


von Daniel (Gast)


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.
1
PCICR|=(1<<PCIE0); // Pin Change Interrupt Enable   
2
  // für PCINT0_vect    
3
  DDRB &=~0x04;    // Eingang
4
  PORTB|=(1<<DDB4);    // PULL UP
5
  PCMSK0|=(1<<PCINT4);  // Maske für PCINT4
6
7
         // für PCINT0_vect      
8
  DDRB &=~0x02;    // Eingang
9
  PORTB|=(1<<DDB2);    // PULL UP
10
  PCMSK0|=(1<<PCINT2);  // Maske für PCINT2
11
12
SIGNAL(PCINT0_vect)
13
{
14
.
15
.
16
.
17
18
}
Initialisiert habe ich sie schon .wie kann ich dann implementieren  , 
dass sie unterschiedlich auf den selben INT-vect reagieren ???
Danke

von Karl H. (kbuchegg)


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?

von Daniel (Gast)


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 ?

von Karl H. (kbuchegg)


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.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

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

von Daniel (Gast)


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.

von Hannes L. (hannes)


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.

...

von Daniel (Gast)


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

von Karl H. (kbuchegg)


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.
1
uint8_t oldPinB;
2
3
SIGNAL(PCINT0_vect)
4
{
5
  uint8_t newPinB = PINB;
6
7
  // die beiden interessanten Pins herausmaskieren
8
  newPinB &= ( 1 << PB4 ) | ( 1 << PB2 );
9
10
  // welche Pins haben sich verändert?
11
  uint8_t changed = newPinB ^ oldPinB;
12
13
  if( changed & ( 1 << PB2 ) ) {
14
    ... PB2 hat sich verändert
15
  }
16
17
  if( changed & ( 1 << PB4 ) ) {
18
    .. PB4 hat sich verändert
19
  }
20
21
  oldPinB = newPinB;
22
}

von Karl H. (kbuchegg)


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 :-)

von Rolf Magnus (Gast)


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.

von Daniel (Gast)


Lesenswert?

ok

Danke . Nun verstehe ich.

@ Karl heinz Buchegger

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

von Daniel (Gast)


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.

von Karl H. (kbuchegg)


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.

von Andreas V. (tico)


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

von Daniel (Gast)


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.

von Karl H. (kbuchegg)


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.

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
Noch kein Account? Hier anmelden.