Hallo, ich habe eine Frage zu einem Diagramm für eine state machine. Eine ISR wird alle 30ms ausgelöst und ein Taster wird abgefragt. Bei einem langen Tastendruck soll LED1 toggeln Bei einem kurzen Tastendruck soll LED2 toggeln Ist das Diagramm so wie ich es gezeichnet habe korrekt?
Das ist kein statemachine Diagramm sondern ein Flußdiagramm, das ist was anderes. Die erste Frage müsste eher lauten "Wurde ein Taster losgelassen?".
Ich finde - nein. FlagLang FlagKurz muessen irgendwo wieder zurückgesetzt werden. Sonst flackern die LED's nur so vor sich hin. Und den Rest hat MAC und Falk schon geschrieben. z.B. -> Wo geht Dein Automati z.B. nach "Flag kurz setzen" oder "Led 1 On" als nächstes hin ?
Hinter "Start ISR alle 32ms" darf es nicht heißen "Wurde eine Taste gedrückt?". Wenn die Taste inzwischen wieder losgelassen wurde, läßt sich das nämlich gar nicht feststellen. Sonst müßte der Tastendruck einen Interrupt auslösen. An der Stelle läßt sich also nur die Frage "Ist eine Taste gedrückt?" beantworten.
Ist es eigentlich so schwer seinem Thread eine sinnvolle, auf das eigentliche Thema weisende Überschrift zu geben? Offensichtlich schon Angenervt Udo
Eine state machine besteht aus Zuständen, die man z.B. durch Kreise symbolisiert, in die man diese dann hineinschreibt. Der Übergang zwischen Zuständen, die transitions, werden durch Pfeile symbolisiert, die Bedingung für den Zustandswechsel ordnet man dann dem jeweiligen Pfeil zu. Was du gezeichnet hast, ist tatsächlich eher ein Flussdiagramm, dass in dieser Form auch nicht besonders leicht lesbar ist. Such hier in der Artikelübersicht mal nach State Machines oder Zustandsautomaten, da wird das schön anhang einer Ampelsteuerung erklärt. Es gibt eine etwas andere Notation, wenn man nach UML arbeitet, wird gerne bei komplexeren meist objektorientierten Ansätzen genommen. Ist für deinen Fall aber sicher nicht nötig, also, hier suchen und neu anfangen.
Thomas schrieb: > Hinter "Start ISR alle 32ms" darf es nicht heißen "Wurde eine Taste > gedrückt?". Wenn die Taste inzwischen wieder losgelassen wurde, läßt > sich das nämlich gar nicht feststellen. Sonst müßte der Tastendruck > einen Interrupt auslösen. An der Stelle läßt sich also nur die Frage > "Ist eine Taste gedrückt?" beantworten. Langsam. Wenn das zb auf den Tastenroutinen vom PeDa beruht, dann geht das durchaus. Ansonsten ist natürlich der ganze Kreis "war es ein langer Tastendruck" recht sinnfrei. Denn genau da besteht ja die Problemtik am ganzen. Die PeDa Routinen erledigen das. Allerdings hat er nicht gesagt ob er da was benutzt, oder ob er selber die Tasten auswertet.
Also der Code dazu sieht so aus:
1 | /* Tasterzustandserkennung Tastendruck kurz / lang
|
2 | * ATtiny2313 @ 8MHz
|
3 | * mittels Watchdogtimer Overflow Interrupt (alle 32ms)
|
4 | * Tastendruck = kurz --> LED am PB4 toggeln
|
5 | * Tastendruck = lang --> LED am PB3 toggeln
|
6 | */
|
7 | |
8 | #include <avr/io.h> |
9 | #include <avr/interrupt.h> |
10 | #include <avr/wdt.h> |
11 | |
12 | #define button_down !(PINB & (1<<PB0)) // Button = Low
|
13 | #define button_up (PINB & (1<<PB0)) // Button = High
|
14 | #define debounce_time 2 // Entprellzeit = 32ms x 2
|
15 | #define short_keypress_timeout 15
|
16 | #define long_keypress_time 15
|
17 | |
18 | enum press_type {short_keypress, long_keypress, running}; |
19 | |
20 | int main(void) |
21 | {
|
22 | WDTCSR = (1<<WDIE) | (1<<WDP0); // watchdog @32ms (4096 cycles) + interrupt enabled |
23 | DDRB |= (1 << PB3)+(1 << PB4); // PB3 und PB4 = Ausgang |
24 | DDRB &= ~(1<<PB0); // PB0 = Eingang |
25 | sei(); |
26 | while(1) |
27 | {
|
28 | asm ("NOP"); |
29 | }
|
30 | }
|
31 | |
32 | ISR (WDT_OVERFLOW_vect) |
33 | {
|
34 | static unsigned int button_timer; // timer to determine button state |
35 | static enum press_type typ; |
36 | static enum state led; |
37 | |
38 | typ = running; // vorherigen Tasterzustand verlassen |
39 | |
40 | if (button_down) // button wurde gedrückt (LOW) |
41 | {
|
42 | if (button_timer < long_keypress_time) |
43 | button_timer ++; |
44 | }
|
45 | |
46 | else // button wurde (ist) losgelassen (HIGH) |
47 | {
|
48 | if (button_timer == long_keypress_time) // Tastendruck = langer Tastendruck |
49 | {
|
50 | typ = long_keypress; |
51 | }
|
52 | |
53 | else if ((button_timer > debounce_time) && (button_timer < short_keypress_timeout)) // Tastendruck = kurzer Tastendruck |
54 | {
|
55 | typ = short_keypress; |
56 | }
|
57 | |
58 | if (button_timer) // Button Timer nach Tastendruck zurücksetzen |
59 | {
|
60 | button_timer = 0; |
61 | }
|
62 | }
|
63 | |
64 | if (typ == long_keypress) // Langer Tastendruck |
65 | {
|
66 | PORTB ^= (1<<PB3); // Portpin PB3 toggeln |
67 | }
|
68 | |
69 | else if (typ == short_keypress) // Kurzer Tastendruck |
70 | {
|
71 | PORTB ^= (1<<PB4); // Portpin PB4 toggeln |
72 | }
|
73 | |
74 | WDTCSR = (1<<WDIE); // Watchdog Interrupt aktivieren |
75 | }
|
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.