Info2P5/Modul4 neu/automat.c
2025-06-11 09:42:59 +02:00

194 lines
3.5 KiB
C
Raw Blame History

/**********************************************************************\
* Kurzbeschreibung: automat.c
* Stellt Funktionen zur Realisierung eines Automaten zur Verf<72>gung,
* die <20>ber die in der automat.h vorgegebene C-Schnittstelle
* mit einer grafischen Schnittstelle kommunizieren.
*
* Datum: Autor: Grund der Aenderung:
*
*
\**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "automat.h"
typedef enum {A=0,B,C,D,E,F,G,H,I} state_t;
typedef struct {
int input;
int mask;
state_t nxtstate;
} fsm_state_t;
typedef struct {
const fsm_state_t * transitions;
int nrOfTransitions;
state_t defaultNxtState;
} fsm_full_state_t;
#define SIZE_OF(a) (sizeof((a))/ sizeof(*(a)))
#define NR_OF_STATES (I-A + 1)
static state_t s_curstate = A;
static const fsm_state_t s_transitions_A[] = {
{0x002, ~0x004, B},
{0x003, ~0x004, C}
};
static const fsm_state_t s_transitions_B[] = {
{0x002, ~0x004, C},
{0x003, ~0x004, D}
};
static const fsm_state_t s_transitions_C[] = {
{0x002, ~0x004, D},
{0x003, ~0x000, F},
{0x007, ~0x000, H}
};
static const fsm_state_t s_transitions_D[] = {
{0x002, ~0x000, F},
{0x003, ~0x004, E},
{0x006, ~0x000, H}
};
static const fsm_state_t s_transitions_E[] = {
{0x006, ~0x000, H},
{0x002, ~0x004, F},
{0x003, ~0x004, G}
};
static const fsm_state_t s_transitions_F[] = {
{0x006, ~0x000, H}
};
static const fsm_state_t s_transitions_G[] = {
{0x006, ~0x000, I}
};
static const fsm_state_t s_transitions_H[] = {
{0x000, ~0x000, A}
};
static const fsm_state_t s_transitions_I[] = {
{0x000, ~0x000, A}
};
static const fsm_full_state_t s_state_table[NR_OF_STATES] = {
{ 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 }
};
static const fsm_action_t s_out_table[NR_OF_STATES] = {
{ false, false, false, 0, "Warten" }, // A
{ false, false, false, 1, "1 Euro" }, // B
{ false, false, false, 2, "2 Euro" }, // C
{ false, false, false, 3, "3 Euro" }, // D
{ true, false, false, 3, "3 Euro + M" }, // E
{ true, false, false, 4, "4 Euro" }, // F
{ true, true, false, 4, "4 Euro + M" }, // G
{ true, false, true, 4, "Kaffee" }, // H
{ false, false, false, 0, "Kaffee + M" } // I
};
void automat_reset(void) {
s_curstate = A;
}
void automat_transition(BOOL becher, BOOL muenze, BOOL muenz_wert) {
int input = ((becher & 0x1) << 2) | ((muenze & 0x1) << 1) | (muenz_wert & 0x1);
const fsm_full_state_t *current = &s_state_table[s_curstate];
for (int i = 0; i < current->nrOfTransitions; ++i) {
if ((input & ~current->transitions[i].mask) == (current->transitions[i].input & ~current->transitions[i].mask)) {
s_curstate = current->transitions[i].nxtstate;
return;
}
}
s_curstate = current->defaultNxtState;
}
fsm_action_t automat_output(void) {
return s_out_table[s_curstate];
}