Forum: Mikrocontroller und Digitale Elektronik Flankenerkennung Makro?


von waalter (Gast)


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)


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


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)


Lesenswert?

Alter Wert XOR neuer Wert = Flanke

Wenn du es zyklisch Pollen möchtest.

von Nop (Gast)


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


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
}

von Einer K. (Gast)


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.

von Nop (Gast)


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)


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)


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.

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.