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
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
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
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 | } |
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 | }
|
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.