Frage

Ich habe eine (etwas) große Wahrheitstabelle / Zustandsmaschine, die ich brauche in meinem Code (Embedded C) zu implementieren. Ich gehe davon aus, das Verhalten Spezifikation dieser Zustandsmaschine in der Zukunft zu ändern, und so würde Ich mag diese in Zukunft leicht modifizierbar halten.

Meine Wahrheitstabelle hat 4 Eingänge und 4 Ausgänge. Ich habe sie alle in einer Excel-Tabelle, und wenn ich nur, dass in meinen Code mit einer wenig Formatierung einfügen könnte, das wäre ideal.

Ich dachte, ich möchte meine Wahrheitstabelle für den Zugriff auf in etwa so:

u8 newState[] = decisionTable[input1][input2][input3][input4];

Und dann konnte ich den Ausgangswert Zugriff mit:

setOutputPin( LINE_0, newState[0] );
setOutputPin( LINE_1, newState[1] );
setOutputPin( LINE_2, newState[2] );
setOutputPin( LINE_3, newState[3] );

Aber um das zu bekommen, sieht es aus wie ich würde eine ziemlich verwirrend Tabelle zu tun haben, etwa so:

static u8 decisionTable[][][][][] =
 {{{{ 0, 0, 0, 0 },
    { 0, 0, 0, 0 }},
   {{ 0, 0, 0, 0 },
    { 0, 0, 0, 0 }}},
  {{{ 0, 0, 1, 1 },
    { 0, 1, 1, 1 }},
   {{ 0, 1, 0, 1 },
    { 1, 1, 1, 1 }}}},
 {{{{ 0, 1, 0, 1 },
    { 1, 1, 1, 1 }},
   {{ 0, 1, 0, 1 },
    { 1, 1, 1, 1 }}},
  {{{ 0, 1, 1, 1 },
    { 0, 1, 1, 1 }},
   {{ 0, 1, 0, 1 },
    { 1, 1, 1, 1 }}}};

Diese verschachtelten Klammern können etwas verwirrend sein - hat jemand eine bessere Idee, wie ich einen ziemlich aussehenden Tisch in meinem Code halten

?

Danke!

Bearbeiten basierend auf HUAGHAGUAH Antwort:

Mit einem Zusammenschluss von jedem Eingang (danke - ich wünschte, ich könnte „akzeptieren“ 3 oder 4 diese Antworten), ich denke, ich werde es als ein zweidimensionales Array versuchen. Ich werde Index in meinem Array ein kleines Bitverschiebung Makro:

#define SM_INPUTS( in0, in1, in2, in3 ) ((in0 << 0) | (in1 << 1) | (in2 << 2) | (in3 << 3))

Und das wird mein Wahrheitstabelle Array wie folgt aussehen lassen:

static u8 decisionTable[][] = {
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 1, 1 },
{ 0, 1, 1, 1 },
{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 },
{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 },
{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 },
{ 0, 1, 1, 1 },
{ 0, 1, 1, 1 },
{ 0, 1, 0, 1 },
{ 1, 1, 1, 1 }};

Und dann kann ich meine Wahrheitstabelle zugreifen wie folgt:

decisionTable[ SM_INPUTS( line1, line2, line3, line4 ) ]

Ich gebe, dass ein Schuss und sehen, wie es funktioniert. Ich werde auch die 0 und 1 ist mit hilfreichem #defines ersetzen, das, was jeden Staat Mittel auszudrücken, zusammen mit / ** / Kommentaren, die die Eingaben für jede Zeile der Ausgänge erklären. Danke für die Hilfe, jeder!

War es hilfreich?

Lösung

Keine Notwendigkeit für eine mehrdimensionale Tabelle. Mit einem 4-Bit => 4-Bit-mapping, können Sie eine einzelne u8 haben [16] -Array Abbildungseingänge mit den Ausgängen. Staat Lookups wird viel billiger, und Sie können einzelne Bits extrahieren mit einigen Schiebe- und Masken ops.

Wenn der Algorithmus Reihen aufzufüllen leicht zu kodifizieren, könnten Sie ein Makro #define jede Zeile von Indexnummer zu füllen.

Andere Tipps

Ich würde vorschlagen, entweder (bevorzugte Ansätze zuerst):

  • ein Makro Verwenden Sie jede „Zeile“ intialize -. Dies wird die Klammern innerhalb des Makroaufruf verbergen
  • Verwenden Sie Kommentare, die Reihen zu brechen.
  • Verwenden Sie eine init-Funktion den Kontext explizit zu initialisieren - vielleicht Funktionen verwenden, um jeden Abschnitt zu initialisieren. Dies ist ähnlich wie die erste Option oben, hat aber einen Nachteil, dass die init-Funktion aufgerufen werden muss, bevor die Zustandsmaschine verwendet werden kann.

Ich persönlich es aus einer Konfigurationsdatei gelesen habe. CSV, vielleicht, das leicht zu von Excel zu exportieren. Oder Sie könnten nur aus Excel in Klartext kopieren und einfügen, die Sie durch Leerzeichen getrennte Werte gibt, die gleichermaßen einfach zu importieren.

Dies bedeutet auch, da Sie mit C arbeiten, dass Sie nicht jedes Mal Ihres Code der Entscheidungstabelle Änderungen neu kompilieren müssen.

, wenn Ihre Wahrheitstabelle alle booleans sind, könnten Sie es einfach kollabieren, um eine Liste von Paaren, z.

1111,0000
1110,0110
...

zur Datenkompression repräsentieren die Werte als Bytes (zwei Nibbles) ...

wo / wie sie gespeichert wird für Soft-Codierung in Ihrer speziellen Embedded-System-Konfiguration, nur kann man sagen; -)

Wenn die Wahrheitstabelle wirklich nur 4x4x4x4 ist, dann würde ich Makros verwenden. Wenn es jemals Vergangenheit, die gehen zu wachsen, würde ich verwenden Ragel . Aller Wahrscheinlichkeit nach wird es kleiner, schneller C-Code machen, als Sie.

Ich sehe keinen Hinweis auf den aktuellen Stand, um Ihren Ausgangszustand zu erhalten. Das bedeutet, es nicht eine Zustandsmaschine ist, sondern nur eine Wahrheitstabelle. Es gibt vier Eingänge, so gibt es nur 16 mögliche Eingangskombinationen. Also, ein Tisch mit 16 Positionen sollte es tun.

Normalerweise, wenn Sie ein Problem wie dieses haben, versucht man es auf eine einfache Formel boolean zu reduzieren. Ich sehe nicht, warum das hier nicht der beste Ansatz wäre. Es wäre sehr viel kompakter und besser lesbar sein, und es hat das Potenzial, schneller zu sein (Ich stelle mir eine Handvoll ANDs und OPs würde schneller als die Sammlung von Multiplikationen / Verschiebungen + Speicherzugriff ausführt für den Lookup-Tabelle Ansatz erforderlich). Der einfachste Weg, um diese Tabelle zu einer Booleschen Formel zu reduzieren, ist mit einem K-Karte .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top