zurück

Logikgatter mit dem Arduino

19.06.2018

Ein Logikgatter ist eine Anordnung bzw. eine elektronische Schaltung zur Realisierung einer booleschen Funktion, die binäre Eingangssignale zu einem binären Ausgangssignal verarbeitet. Die Eingangssignale werden durch Implementierung logischer Operatoren, z.B. AND, OR oder NOT zu einem einzigen logischen Ergebnis umgewandelt und auf das Ausgangssignal abgebildet. (siehe auch Logikgatter-Typen)

Standard-Logik-Gatter und deren Wertetabellen
Abb.: Standard-Logik-Gatter und deren Wertetabellen

Verwendete Bauteile

Aufbau

Die Funktion der Logikgatter wird in diesem Experiment per Software-Programmierung realisiert.
Es werden als Eingabewerte jeweils eine Kombination von einem Mikrotaster und einer farbigen LED verwendet (rot und grün). Die verschiedenen Gatter-Typen können mit dem dritten Mikrotaster durchgewechselt werden. Die dritte (gelbe) LED wird als Ausgangssignal verwendet.

Aufbau der Schaltung
Abb.: Aufbau der Schaltung

Sketch

#define PIN_LED_A 12
#define PIN_LED_B 11
#define PIN_LED_OUT 10

#define PIN_BUTTON_A 7
#define PIN_BUTTON_B 6
#define PIN_BUTTON_MODE 5

#define DEBOUNCE_TIME 350

const char* gateTypes[]={"AND", "OR", "NAND", "NOR", "XOR", "XNOR"};
bool hasStateChanged = true;
byte statusA = 0, statusB = 0, statusOut = 0, gateType = 0;
unsigned long lastButtonPressed;

void setup()
{
  pinMode(PIN_LED_A, OUTPUT);
  pinMode(PIN_LED_B, OUTPUT);
  pinMode(PIN_LED_OUT, OUTPUT);
  pinMode(PIN_BUTTON_A, INPUT);
  pinMode(PIN_BUTTON_B, INPUT);
  pinMode(PIN_BUTTON_MODE, INPUT);

  lastButtonPressed = millis();

  Serial.begin(9600);
  Serial.flush();
  printGateType();
  calculateGateResult();
}

void loop()
{
  if (digitalRead(PIN_BUTTON_MODE) == HIGH && ((millis() - lastButtonPressed) > DEBOUNCE_TIME)) {
    lastButtonPressed = millis();
    gateType++;
    gateType %= 6;
    printGateType();
    hasStateChanged = true;
  }

  if (digitalRead(PIN_BUTTON_A) == HIGH && ((millis() - lastButtonPressed) > DEBOUNCE_TIME)) {
    lastButtonPressed = millis();
    statusA++;
    statusA %= 2;
    digitalWrite(PIN_LED_A, statusA);
    hasStateChanged = true;
  }
  if (digitalRead(PIN_BUTTON_B) == HIGH && ((millis() - lastButtonPressed) > DEBOUNCE_TIME)) {
    lastButtonPressed = millis();
    statusB++;
    statusB %= 2;
    digitalWrite(PIN_LED_B, statusB);
    hasStateChanged = true;
  }

  calculateGateResult();
}

void calculateGateResult()
{
  if (!hasStateChanged) {
    return;
  }
  switch(gateType)
  {
    case 0: // AND
      if(statusA == 1 && statusB == 1) {
        statusOut = 1;
      } else {
        statusOut = 0;
      }
      break;
    case 1: // OR
      if(statusA == 1 || statusB == 1) {
        statusOut = 1;
      } else {
        statusOut = 0;
      }
      break;
    case 2: // NAND
      if(!(statusA == 1 && statusB == 1)) {
        statusOut = 1;
      } else {
        statusOut = 0;
      }
      break;
    case 3: // NOR
      if(!(statusA == 1 || statusB == 1)) {
        statusOut = 1;
      } else {
        statusOut = 0;
      }
      break;
    case 4: // XOR
      if((statusA == 0 && statusB == 1) || (statusA == 1 && statusB == 0)) {
        statusOut = 1;
      } else {
        statusOut = 0;
      }
      break;
    case 5: // XNOR
      if((statusA == 1 && statusB == 1) || (statusA == 0 && statusB == 0)) {
        statusOut = 1;
      } else {
        statusOut = 0;
      }
      break;
  }

  Serial.println("  " + String(statusA) + " " + (String)gateTypes[gateType] + " " + String(statusB) + " = " + String(statusOut));
  digitalWrite(PIN_LED_OUT, statusOut);
  hasStateChanged = false;
}

void printGateType()
{
  Serial.println("Current gate: " + (String)gateTypes[gateType]);
}

Ergebnis

Ausgabe in der seriellen Konsole
Abb.: Ausgabe in der seriellen Konsole: hier wurden alle Typen und Schaltmöglichkeiten durchprobiert