Pages: [1]   Go Down
Author Topic: Interrupt Frage CHANGE FALLING Pinstate  (Read 636 times)
0 Members and 1 Guest are viewing this topic.
Germany, BW
Offline Offline
Sr. Member
****
Karma: 7
Posts: 302
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ich verwende attachInterrupt und die ISR um damit Impulse zu Messen.

Das Problem ist jetzt, dass ich gerne beide Flanken messen würde. Die Pinabfrage ist aber zu langsam, da ich Impulse mit 600µs erfassen möchte.
Gibt es oder kennt jemand eine Alternative, um in der ISR den Event (FALLING,RISING, HIGH oder LOW) zu bekommen?
Logged

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 258
Posts: 21488
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

CHANGE
attachInterrupt(0, intFunktion, CHANGE);

siehe http://arduino.cc/en/Reference/AttachInterrupt

Grüße Uwe
Logged

Germany, BW
Offline Offline
Sr. Member
****
Karma: 7
Posts: 302
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In dem Beispiel wird aber nicht der Zustand des Interrupts verarbeitet.
Ich weiß in der ISR, dass der Signalzustand sich gewechselt hat, aber nicht wie der aktuelle Zustand ist.
Gibt es kein Register in dem die Ursache für den IRQ steht?
« Last Edit: February 08, 2013, 07:54:35 pm by mde110 » Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 143
Posts: 3009
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In dem Beispiel wird aber nicht der Zustand des Interrupts verarbeitet.
Ich weiß in der ISR, dass der Signalzustand sich gewechselt hat, aber nicht wie der aktuelle Zustand ist.
Gibt es kein Register in dem die Ursache für den IRQ steht?

Also ich kenne nur die Methode, dass ich den aktuellen Zustand in der allerersten Programmzeile der ISR abfrage, z.B.:
int State = digitalRead(DATAPIN);
und dann steht der Pinstatus innerhalb der ISR in einer Variablen.

Und das funktioniert auch dann bestens, wenn ich z.B. bei einem 433MHz Empfänger beim Funkempfang Impulse mit 600 µs Dauer von solchen mit 1200 µs Dauer unterscheiden möchte.
Logged

Forum Moderator
BZ (I)
Online Online
Brattain Member
*****
Karma: 258
Posts: 21488
+39 349 2158303
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In dem Beispiel wird aber nicht der Zustand des Interrupts verarbeitet.
Ich weiß in der ISR, dass der Signalzustand sich gewechselt hat, aber nicht wie der aktuelle Zustand ist.
Gibt es kein Register in dem die Ursache für den IRQ steht?
Die zweite metode ist ähnlich: direkt das datenregister der Eingänge auslesen und das entsprechende Bit kontrollieren:
http://playground.arduino.cc/Learning/PortManipulation
Das gesagte gilt auch für den Atmega328.

Grüße Uwe
Logged

Germany, BW
Offline Offline
Sr. Member
****
Karma: 7
Posts: 302
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

... bei einem 433MHz Empfänger beim Funkempfang Impulse mit 600 µs Dauer von solchen mit 1200 µs Dauer unterscheiden möchte.
Genau da brauche ich es smiley-cool

Da ich aber mit digitalRead große Schwankungen in der Erkennung hatte muss ich das verwerfen. Wie hast nur du das geschafft???
Bis jetzt läufts mit
Code:
const bool RXPIN = (PINE&B100000)>>5;
Logged

Germany S-H
Offline Offline
Faraday Member
**
Karma: 143
Posts: 3009
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Genau da brauche ich es smiley-cool

Da ich aber mit digitalRead große Schwankungen in der Erkennung hatte muss ich das verwerfen. Wie hast nur du das geschafft???

Timing natürlich mit micros().
Und ISR Routinen laufen dann stabil im System, wenn sie KURZ laufen.

Das erreichst Du dadurch, dass sämtliche langlaufenden Aktionen NUR in der loop laufen, z.B. Auswertung von Funkprotokollen, aber nicht in der ISR!

Die ISR ermittelt die Länge der Impulse, dampft ggf. die Datenmenge ein, und speichert die Werte in einem Ringpuffer weg. Hinweis: Die Variablen des Ringpuffers müssen "volatile" deklariert werden, damit ein problemloser Zugriff auf korrekte Variablenbereiche sowohl von der ISR als auch von der loop aus möglich ist.

Beispielhafter Code für eine Interrupt-Behandlungsroutine zum Ermitteln von sowohl Low- als auch High-Impulsen, die Ringpuffer-Logik zum Wegspeichern der Daten muss dort eingefügt werden, wo die Kommentarzeilen stehen.

Code:
void rx433Handler()
{
  static long rx433LineUp, rx433LineDown;
  long LowVal, HighVal;
  int rx433State = digitalRead(RX433DATAPIN); // current pin state
  if (rx433State) // pin is now HIGH
  {
    rx433LineUp=micros(); // line went HIGH after being LOW at this time
    LowVal=rx433LineUp - rx433LineDown; // calculate the LOW pulse time
    // Hier ggf. viel zu kurze und viel zu lange Impulse verwerfen,
    // sowie ggf. den LowVal ggf. auf int eindampfen (Speicherplatz!),
    // oder ggf. auch direkt per Vergleich ermitteln, ob ein 1-Bit, 0-Bit oder Startbit empfangen wurde
    // und den Wert zur Verarbeitung in der loop in einem Ringpuffer (volatile!) wegspeichern
  }
  else
  {
    rx433LineDown=micros(); // line went LOW after being HIGH
    HighVal=rx433LineDown - rx433LineUp; // calculate the HIGH pulse time
    // Hier ggf. viel zu kurze und viel zu lange Impulse verwerfen,
    // sowie ggf. den HighVal ggf. auf int eindampfen (Speicherplatz!),
    // oder ggf. auch direkt per Vergleich ermitteln, ob ein 1-Bit, 0-Bit oder Startbit empfangen wurde
    // und den Wert zur Verarbeitung in der loop in einem Ringpuffer (volatile!) wegspeichern
  }
}
Logged

Pages: [1]   Go Up
Jump to: