194 lines
3.5 KiB
C
194 lines
3.5 KiB
C
/**********************************************************************\
|
||
* 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];
|
||
|
||
}
|