Flankenerkennung Makro?

Gast #5074007
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
Gast #5074025
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
Gast #5074080
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
}
Gast #5074108
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
}
Gast #5074121
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.
#5074467
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.
#5074498
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

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