Forum: Mikrocontroller und Digitale Elektronik Flankenerkennung Makro?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von waalter (Gast)


Bewertung
-1 lesenswert
nicht lesenswert
Guten Morgen,
ich verfolge schon lange dieses Forum. Habe auch sehr viel gelernt durch 
Euch. Danke dafür.
Nun habe ich eine Frage auf die ich keine zufriedenstellende Antwort 
gefunden habe.
Nämlich suche ich ein C-Makro oder eine kleine Funktion die mir einen 
Flanken Wechsel erkennt. Stelle mir das so vor das ich einfach diesem 
Makro oder Funktion die Quelle übergebe und ich dann ein True bekomme 
wenn steigende oder faltende Flanke da war.

Kennt ihr so was? Ist es teil der Gcc Toolcain vom Atmelstudio?

Lg
W

von flank (Gast)


Bewertung
-2 lesenswert
nicht lesenswert
soll das eine blockierede Funktion werden?
wenn du so lange warten möchtest, bis der Flankenwechsel passiert, 
kannst es quick and dirty mit so etwas wie

while ((PINA ^ PINA) & (1 << gewünschte Pin Nr) != 0)

machen. Ansonsten würde ich empfehlen mit pin change interrupts zu 
arbeiten

von Christopher B. (chrimbo) Benutzerseite


Bewertung
4 lesenswert
nicht lesenswert
flank schrieb:
> while ((PINA ^ PINA) & (1 << gewünschte Pin Nr) != 0)

Ich Frage mich gerade wie viele Flanken man damit wirklich erfasst. Die 
muss ja zufällig gerade zwischen den beiden PINA reads passieren

von Frank (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Alter Wert XOR neuer Wert = Flanke

Wenn du es zyklisch Pollen möchtest.

von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
So könnte man es auch machen (nur eben runtercodiert, ungetestet). 
Voraussetzung ist, daß get_measurement() bereits die Entprellung macht.
1
typedef enum {RISING=1, FALLING=2, BOTH=3} T_FLANK;
2
typedef enum {LOW, HIGH} T_LEVEL;
3
typedef struct {
4
  T_LEVEL prev_val;
5
  T_FLANK direction;
6
} T_STATE;
7
8
bool detect_flank(T_STATE *state, T_LEVEL new_val) {
9
  T_LEVEL prev_val = state->prev_val;
10
  state->prev_val = new_val;
11
  
12
  if (((state->direction) & RISING) && (new_val == HIGH) && (prev_val == LOW))
13
    return true;
14
  
15
  if (((state->direction) & FALLING) && (new_val == LOW) && (prev_val == HIGH))
16
    return true;
17
    
18
  return false;
19
}
20
21
void main(void)
22
{
23
  T_STATE my_state = {LOW, RISING};
24
  T_LEVEL my_level;
25
  bool flank_seen;
26
  
27
  for (;;) {
28
    my_level = get_some_measurement();
29
    
30
    flank_seen = detect_flank(&my_state, my_level);
31
    
32
    if (flank_seen) {
33
      do_something();
34
    }
35
  }
36
}

von Stefan ⛄ F. (stefanus)


Bewertung
0 lesenswert
nicht lesenswert
Für einen ganzen Port (8 Bits) auf einen Schlag:
1
uint8_t alt=PINA; 
2
3
void loop()
4
{
5
    uint8_t neu = PINA;
6
    if (neu != alt)
7
    {
8
        alt = neu;
9
        // Flanke erkannt    
10
    }
11
}

Für ein einzelnes Bit (Bit 3 in diesem Fall):
1
uint8_t alt = (PINA & 1<<3);
2
3
void loop()
4
{
5
    uint8_t neu=(PINA & 1<<3);
6
    if (neu != alt)
7
    {
8
        alt = neu;
9
        // Flanke erkannt    
10
    }
11
}

jedenfalls kommst du wohl nicht umhin, für jeden Pin oder Port eine 
Variable zu deklarieren, die den alten Zustand speichert. Ich würde das 
nicht mit einem Makro hintricksen, da es den Code schwer lesbar macht. 
Vor allem wenn du den dann mal debuggen sollst wird das ärgerlich.

Falls du loop() nicht kennst: Im Arduino Fraemwork wird die loop() 
Funktion nach der Initialisierung in einer Endlosschleife immer wieder 
aufgerufen.
1
int main()
2
{
3
  setup();
4
  while (1)
5
  {
6
    loop(); 
7
  }
8
}

: Bearbeitet durch User
von Arduino Fanboy D. (ufuf)


Bewertung
-1 lesenswert
nicht lesenswert
Eigentlich doch einfach...

Macros haben kein Gedächtnis.
Denn es gibts da keine "Merker"
Ohne Merker keine Flankenerkennung.

Macros taugen also für den Zweck nicht.


waalter schrieb:
> Nun habe ich eine Frage auf die ich keine zufriedenstellende Antwort
> gefunden habe.

War meine Antwort befriedigend genug für dich?

Nein?

Dann klarer:
Du bist mit deinen Macros auf einem Irrweg.

: Bearbeitet durch User
von Nop (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Arduino F. schrieb:
> Eigentlich doch einfach...
>
> Macros haben kein Gedächtnis.

Man kann Macros aber Variablen übergeben, beispielsweise ein struct. 
Meine detect-Funktion oben könnte man auch als Macro realisieren.

von Peter D. (peda)


Bewertung
0 lesenswert
nicht lesenswert
Arduino F. schrieb:
> Du bist mit deinen Macros auf einem Irrweg.

Nö, man kann auch in einem Macro statische Variablen anlegen.
Man darf dann das Macro natürlich nur an einer einzigen Stelle 
expandieren.

Hier mal ein Macro zum Tasten einlesen:
Beitrag "Entprellen für Anfänger"

Wenn man das Entprellen nicht braucht, läßt man die Delays einfach weg. 
Übrig bleibt die Flankenerkennung.

von Jim M. (turboj)


Bewertung
0 lesenswert
nicht lesenswert
waalter schrieb:
> Nämlich suche ich ein C-Makro oder eine kleine Funktion die mir einen
> Flanken Wechsel erkennt.

Moderne µC haben oft flankengetriggerte Interrupts in Hardware, und 
mitunter auch auslesbare Flags.

Hat den Vorteil dass der CPU Kern nicht die ganze Zeit rumrödeln muss, 
und man auch relativ kurze Pulse erkennen kann.

Leider sind die Details herstellerspezifisch.

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]
  • [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.