2 Externe Interrup auf gleichen Vektor

Gast #1522828
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
Gast #1522852
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 ?
Gast #1522869
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.
#1522871
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.

...
Gast #1522881
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.).
#1522889
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
}
Gast #1522896
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.
Gast #1522949
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.
#1522953
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.
Gast #1554566
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren