/**********************************************************************\ * Kurzbeschreibung: automat.c * Stellt Funktionen zur Realisierung eines Automaten zur Verf�gung, * die �ber die in der automat.h vorgegebene C-Schnittstelle * mit einer grafischen Schnittstelle kommunizieren. * * Datum: Autor: Grund der Aenderung: * * \**********************************************************************/ #include #include #include "automat.h" /*--- #defines -------------------------------------------------------*/ /* Macro zur Ermittlung der Array Groesse */ #define SIZE_OF(a) (sizeof((a)) / sizeof(*(a))) #define NR_OF_STATES (I - A + 1) /*--- Datentypen (typedef) -------------------------------------------*/ /* Definition der Zustaende */ typedef enum { A = 0, B, C, D, E, F, G, H, I } state_t; /* Definition der fsm-spezifischen Variablen */ /* Struktur zur Beschreibung eines Uebergangs mit "Don't Care"-Moeglichkeit */ typedef struct { int input; int mask; state_t nxtstate; } fsm_state_t; /* Struktur zur Beschreibung aller Uebergaenge eines Zustands */ typedef struct { const fsm_state_t *transitions; int nrOfTransitions; state_t defaultNxtState; } fsm_full_state_t; /*--- Modulglobale static Variablen ----------------------------------*/ /* Definition der Zustandsvariablen */ static state_t s_curstate = A; /* Initialisierung */ /* Definition aller Zustandsuebergaenge fuer jeden Zustand */ static const fsm_state_t s_transitions_A[] = {/* input mask nxtstate */ {0x002, ~0x004, B}, {0x003, ~0x004, C}}; static const fsm_state_t s_transitions_B[] = {/* input mask nxtstate */ {0x002, ~0x004, C}, {0x003, ~0x004, D}}; static const fsm_state_t s_transitions_C[] = {/* input mask nxtstate */ {0x002, ~0x004, D}, {0x003, ~0x000, F}, {0x007, ~0x000, H}}; static const fsm_state_t s_transitions_D[] = {/* input mask nxtstate */ {0x002, ~0x000, F}, {0x003, ~0x004, E}, {0x006, ~0x000, H}}; static const fsm_state_t s_transitions_E[] = { /* input mask nxtstate */ {0x000, ~0x005, D}, {0x002, ~0x000, F}, {0x006, ~0x000, H}}; static const fsm_state_t s_transitions_F[] = { /* input mask nxtstate */ {0x002, ~0x001, G}, {0x006, ~0x001, I}, {0x004, ~0x001, H}}; static const fsm_state_t s_transitions_G[] = { /* input mask nxtstate */ {0x000, ~0x001, F}, {0x004, ~0x001, H}, {0x006, ~0x001, I}, }; static const fsm_state_t s_transitions_H[] = { /* input mask nxtstate */ {0x000, ~0x001, A}, {0x002, ~0x000, B}, {0x003, ~0x000, C}, {0x006, ~0x001, I}}; static const fsm_state_t s_transitions_I[] = { /* input mask nxtstate */ {0x000, ~0x001, A}, {0x002, ~0x000, B}, {0x003, ~0x000, C}, {0x004, ~0x001, H}}; /* Definition der Uebergangstabelle */ /* Die Reihenfolge der Zustaende in der enum Definition muss der * Reihenfolge der Zustaende in der Uebergangstabelle entsprechen * [Zeile] [Spalte] */ static const fsm_full_state_t s_state_table[NR_OF_STATES] = { /* transitions nrOfTransitions defaultNxtState */ {s_transitions_A, SIZE_OF(s_transitions_A), A}, {s_transitions_B, SIZE_OF(s_transitions_B), B}, {s_transitions_C, SIZE_OF(s_transitions_C), C}, {s_transitions_D, SIZE_OF(s_transitions_D), D}, {s_transitions_E, SIZE_OF(s_transitions_E), E}, {s_transitions_F, SIZE_OF(s_transitions_F), F}, {s_transitions_G, SIZE_OF(s_transitions_G), G}, {s_transitions_H, SIZE_OF(s_transitions_H), H}, {s_transitions_I, SIZE_OF(s_transitions_I), I}}; /* Definition der Ausgaenge */ static const fsm_action_t s_out_table[NR_OF_STATES] = { /* display muenz_rueck kaffee_los guthaben, display_string */ {false, false, false, 0, "Warten"}, /* state A */ {false, false, false, 1, "1 Euro"}, /* state B */ {false, false, false, 2, "2 Euro"}, /* state C */ {false, false, false, 3, "3 Euro"}, /* state D */ {false, true, false, 3, "3 Euro + M"}, /* state E */ {true, false, false, 4, "4 Euro"}, /* state F */ {true, true, false, 4, "4 Euro + M"}, /* state G */ {true, false, true, 0, "Glühwein"}, /* state H */ {true, true, true, 0, "Glühwein + M"}, /* state I */ }; /*--- Funktionsdefinition --------------------------------------------*/ void automat_reset(void) { printf("---- automat_reset ----\n"); s_curstate = A; } /*--- Funktionsdefinition --------------------------------------------*/ void automat_transition(BOOL becher, BOOL muenze, BOOL muenz_wert) { printf("---- automat_transition becher(%0d) muenze(%0d) muenz_wert(%0d) ----\n", becher, muenze, muenz_wert); int bitTrain = (becher << 2 | muenze << 1 | muenz_wert); fsm_full_state_t curState = s_state_table[s_curstate]; for (int i = 0; i < curState.nrOfTransitions; i++) { if ((curState.transitions[i].input & curState.transitions[i].mask) == (bitTrain & curState.transitions[i].mask)) { s_curstate = curState.transitions[i].nxtstate; } } } /*--- Funktionsdefinition --------------------------------------------*/ fsm_action_t automat_output(void) { return s_out_table[s_curstate]; }