Home Navigationspfeil Arduino Navigationspfeil 7-Segmentanzeige

Ansteuern einer 7-Segmentanzeige

Diesmal möchte ich eine kleine Spielerei vorstellen, die ich aus Langeweile geschrieben habe als ich in meiner Bastelkiste eine 7-Segmentanzeige gefunden habe. Noch schnell einen passenden TTL Schaltkreis dazu gesucht und schon konnte es los gehen.

Was wird benötigt ?

Das Studium der Lektüre

Nun sollte man sich zuerst einmal mit den beiden Bauteilen auseinandersetzen und die Datenblätter lesen. Wichtig sind vor allem die Pinbelegungen der beiden Bauteile, sonst kann es bei der Anzeige hinterher ein ziemliches durcheinander geben. Die folgende Abbildung veranschaulicht noch mal die Verdrahtung, ich verzichte bewusst auf die übliche Fritzing Darstellung, da sie bei den vielen Verbindungen zu unübersichtlich würde.

Verdrahtung SN7447 - MAN72A

Verdrahtung SN7447 - MAN72A

In der nächsten Zeichnung ist die Verdrahtung zwischen dem IC (SN7447) und dem Arduino dargestellt. Hierfür sind lediglich fünf Drähte vom Arduino zum IC zu führen. Die Verwendeten Pins am Arduino sind D0 … D4.

Vollständige Verdrahtung

Vollständige Verdrahtung

Die Software

Kommen wir nun zur Software. Ich stelle zuerst das Sketch vor, dann folgen einige Erklärungen dazu.

/*
 * Arduino Sketch für das 7-Segment Experiment
 *
 * Das Programm demonstriert die Ansteuerung einer 7-Segmentanzeige wobei
 * auf einen BCD-to-7-Segment Schaltkreis zugegriffen wird. Dieser Schalt-
 * kreis übernimmt die Ansteuerung der Segmentanzeige wodurch die Ports des
 * Arduino entlasstet werden.
 *
 * Die folgenden Verbindungen müssen vom Arduino zum SN7447 BCD-to-7-Segment
 * Schaltkreis gesteckt werden:
 *
 * Arduino -> SN7447
 * -------------------
 * D0      -> A (Pin 7)
 * D1      -> B (Pin 1)
 * D2      -> C (Pin 2)
 * D3      -> D (Pin 4)
 * D4      -> Direkt an 7-Segment Anzeige (dp)
 *
 * @author  Frank A. Dullinger
 * @version 1.0 - 25.10.2015 04:54:29
 *
 */

#define SN7447_A  0
#define SN7447_B  1
#define SN7447_C  2
#define SN7447_D  3
#define MAN72A_DP  4 // Dezimal Punkt wird extra gesteuert

int dpState = LOW;                  // Status des Dezimalpunktes
unsigned long previousMillis = 0;   // speichert die Zeit der letzen aktualisierung des Dezimalpunktes.
const long interval = 1000;         // Blinkintervall in Millisekunden

void showNumber(int value, int offset) {

  // Ausmaskieren des zu setzenden Ports
  // Es werden die Ports D0 .. D3 für die Ansteuerung des SN7447 verwendet
  // deshalb werden auch nur die 4 unteren Bits geprüft, werden andere
  // Ports verwendet so kann der Offset gesetzt werden.
  // Dies Funktioniert aber nur mit fortlaufenden Ports!
  digitalWrite(offset + SN7447_D, HIGH && (value & B00001000));
  digitalWrite(offset + SN7447_C, HIGH && (value & B00000100));
  digitalWrite(offset + SN7447_B, HIGH && (value & B00000010));
  digitalWrite(offset + SN7447_A, HIGH && (value & B00000001));

}

void setup() {
  pinMode(SN7447_A, OUTPUT);
  pinMode(SN7447_B, OUTPUT);
  pinMode(SN7447_C, OUTPUT);
  pinMode(SN7447_D, OUTPUT);
  pinMode(MAN72A_DP, OUTPUT);

  // zum Test eine 8 anzeigen
  showNumber(8, 0);
}

void loop() {

  // Zeige alle Ziffern von 0 .. 9
  for (int number=0; number <10; number++) {
    showNumber(number, 0);

    // Überprüfen ob es Zeit ist den Dezimalpunkt blinken zu lassen.
    // Dies geschieht immer dann wenn di Differenz der aktuellen Zeit
    // und der Zeit des letztn Blink-Ereignsses größer als der Wert von
    // interval ist.
    unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= interval) {
      // save the last time you blinked the LED
      previousMillis = currentMillis;

      // wenn der Dezimaplpunkt nicht leuchtet wird er eingeschaltet,
      // andernfall wird er aus geschaltet.
      if (dpState == LOW) {
        dpState = HIGH;
      } else {
        dpState = LOW;
      }
      digitalWrite(MAN72A_DP, dpState);
    }
    delay(400); // wartezeit bis zu nächsten Ziffer
   
  } // for
   
}


 
7-Segment Demonstration

Das Ergebnis dieses Sketch sollte dann wie im Video zu aussehen.

Kommen wir aber nun zur Erklärung

Der größte Teil des Sketch dürfte keine Verständnisprobleme aufwerfen, bei der „showNumber“ Funktion könnten jedoch Fragen auftauchen die ich versuchen will zu beantworten. Was in dieser Funktion geschieht, ist ja bereits im Kommentar kurz erklärt, hier möchte ich die Funktion etwas ausführlicher erläutern. Dazu betrachten wir die folgende Zeile des Quelltextes:

  digitalWrite(offset + SN7447_A, HIGH && (value & B00000001)); // Bit 0

Zuerst betrachten wir den Teil der letzten Klammer

Der Binärwert interessiert uns im Moment noch nicht, dazu später. Interessant ist der Dezimale Wert „value“. Er stellt eine BCD (Binary Coded Decimal) (Binär kodierte Dezimal) -Zahl dar, die für die Ansteuerung des SN7447 notwendig ist.

Aber was bedeutet BCD genau ? Findige Leser werden jetzt im Lexikon Ihrer Wahl nachschlagen, ist aber nicht nötig ich erkläre das jetzt. Der BCD-Code (häufig auch 8-4-2-1 Code) wird verwendet um die 10 Ziffern des Dezimalsystems darzustellen. Gegenüber dem reinen Binär-Code ist der BCD-Code auf Grund seiner Kompaktheit klar im Vorteil. Die Wertigkeit dieser Darstellung ist die gleiche wie in den unteren 4-Bit des Dualsystems. Im BCD-System werden die Ziffern 0 … 9 mit nur 4 Bit dargestellt (siehe Tabelle)

BCD-Code  
Decimal 23 22 21 20
Tabelle 1: BCD Zahlensystem
0 0 0 0 0
1 0 0 0 1
2 0 0 2 0
3 0 0 1 1
4 0 1 0 0
5 1 0 0 1
6 0 1 1 0
7 0 1 1 1
8 1 0 0 0
9 1 0 0 1

Wer jetzt das Datenblatt zum SN7447 genau studiert hat wird feststellen, das in den Spalten A, B, C und D der Wahrheitstabelle genau diese Werte auftauchen. Nun müssen wir nur noch dem Arduino beibringen bei einer bestimmten dezimalen Zahl den entsprechenden Port anzusteuern. Und genau jetzt sind wir bei der bitweisen UND Verknüpfung. Bei einer UND Verknüpfung ist das Ergebnis immer dann 1 wenn das Entsprechende Bit in der Maske und dem Wert gesetzt ist.
Für unsere Funktion bedeutet dies „value“ und Maske (B00000001) müssen an der gleichen Bitposition den Wert 1 haben damit im Ergebnis eine 1 auftaucht. Das folgende Beispiel soll dies verdeutlichen

  0101
UND 0011
= 0001

Wie zu erkennen ist, stimmt die zuvor aufgestellte Behauptung mit dem Ergebnis überein. Wer nun Lust hat die Behauptung selber zu überprüfen kann sich ja die Mühe machen für die Ziffern 0 … 9 die Berechnungen durchzuführen.
Schauen wir uns nun die Masken (die Binärwerte) genauer an. Die Wertigkeit ist von rechts gesehen das niederwertige Bit 20 und links das höchstwertige Bit 27. In der Funktion wird mit Hilfe der bitweisen UND Verknüpfung nun der/die zu verwendete(n) Ports des Arduino D0, D1, D2, D3 zur Darstellung des in „value“ übergebenen Wertes ermittelt (ausmaskiert). Dazu werden nacheinander die Bits 3, 2, 1 und 0 überprüft.
Die zweite (logische UND) -Verknüpfung (&&) gibt schlussendlich den Entsprechenden Pegel HIGH oder LOW an dem Port des Arduino aus.

Links

 

Da die dargestellten Schaltungen und Programme nur dem Grundverständnis dienen sollen, kann ich für die Funktion keine Gewähr übernehmen.
Wie üblich kann ich für Schäden die durch die Verwendung der hier veröffentlichten Schaltungen und Programme entstehen keine Haftung übernehmen.

Alle genannten und durch Dritte geschützten Marken- und Warenzeichen unterliegen uneingeschränkt den Bestimmungen des jeweils gültigen Kennzeichenrechts und den Besitzrechten der jeweiligen eingetragenen Eigentümer. Allein aufgrund der bloßen Nennung ist nicht der Schluss zu ziehen, dass Markenzeichen nicht durch Rechte Dritter geschützt sind!