zurück zur Übersicht...
06.07.2019

Schieberegister 74HC165

Mit dem Schieberegister 74HC165 lassen sich bis zu 8 Eingang-Pins gleichzeitig verarbeiten, wobei aber nur 3 Pins auf der Seite des Mikrocontrollers (z.B. Arduino) benötigt werden. Durch Verwendung von mehreren Schieberegistern können noch weitaus mehr Pins angesteuert werden.

Schieberegister 74HC165 als DIP-Baustein
Abb.: Schieberegister 74HC165 als DIP-Baustein

Anschlüsse des 74HC165

Anschlüsse des 74HC165
Abb.: Anschlüsse des 74HC165
Pin Symbol Beschreibung
1 PL "Parallel Load" (active low)
2 CP / CLK "Clock"
3 D4 Eingangspin #4
4 D5 Eingangspin #5
5 D6 Eingangspin #6
6 D7 Eingangspin #7
7 QH / Q7 "Serial Out" (active low)
8 GND Ground / Masseanschluss
9 QH / Q7 "Serial Out"
10 SER / DS "Serial In": zur Verkettung mehrerer Schieberegister
11 D0 Eingangspin #0
12 D1 Eingangspin #1
13 D2 Eingangspin #2
14 D3 Eingangspin #3
15 CE "Clock Enable" (active low)
16 VCC Stromversorgung (5V)

Funktionsweise des 74HC165

Grundsätzlich ist die Funktionsweise invertiert zum Schieberegister 74HC595, welchen aus einem seriellen Eingangssignal 8 parallele Ausgangssignale generierte. Das 74HC165 generiert nun aus 8 parallel anliegenden Eingangssignalen ein serielles Ausgangssignal.
Sobald PL aktiviert wird (HIGH), werden die internen Register mit dem Zustand der Eingangspins 1-8 befüllt uns stehen nun am Ausgang bereit. Durch aufeinander folgendes aktivieren (Flanke zu HIGH) werden die Zustände nun nacheinander durch den Ausgang QH geleitet.

Verwendete Bauteile

Diskreter Aufbau

Zunächst wird der 74HC165-Baustein mit Tastern und ohne Mikrocontroller (oder ähnliche Steuerung) getestet. Dazu wird am PL- und CLK-Pin jeweil ein Mikrotaster angeschlossen und am Ausgang eine LED, die die End-Zustände anzeigen soll. Ein DIP-Schalter (="Mäuseklavier") wird zum setzen der Eingänge verwendet.
Sobald die Stromversorgung verbunden wird, kann man mit aktivieren des PL-Pins die internen Register befüllen. Durch je einen Druck des Mikrotasters bei CLK wird nacheinander der Zustand der Eingänge zum Ausgang weitergegeben und die LED leuchtet, wenn ein Eingang mit HIGH beschaltet wurde und erlischt, wenn der entsprechende Eingang mit LOW beschaltet wurde.

Schaltplan: Schieberegister 74HC165 ohne Mikrocontroller
Abb.: Schaltplan: Schieberegister 74HC165 ohne Mikrocontroller
Video: Testen des Schieberegisters 74HC165 ohne Mikrocontroller

Aufbau mit dem Arduino

Nun wird PL, CLK und CE durch Pins des Arduinos verbunden, um so die Steuerung den Mikrocontroller übernehmen zu lassen. Statt einer LED am Ausgang werden die Ergebnisse in der seriellen Konsole ausgeben.

Aufbau: Schieberegister 74HC165 mit dem Arduino
Abb.: Aufbau: Schieberegister 74HC165 mit dem Arduino

Sketch

Der folgende Sketch liest jede Sekunde die Daten am Ausgang des 74HC165 und gibt sie in der seriellen Konsole aus, wenn Änderungen festgestellt werden.

#define AMOUNT_IC   1 // amount of used 74HC165 chips
#define DATA_WIDTH  AMOUNT_IC * 8

#define PIN_PL  5
#define PIN_CE  3
#define PIN_Q7  6
#define PIN_CLK 4

unsigned long pinValues, oldPinValues;

void setup()
{
    Serial.begin(9600);

    pinMode(PIN_PL, OUTPUT);
    pinMode(PIN_CE, OUTPUT);
    pinMode(PIN_CLK, OUTPUT);
    pinMode(PIN_Q7, INPUT);

    digitalWrite(PIN_CLK, LOW);
    digitalWrite(PIN_PL, HIGH);

    pinValues = readShiftRegisters();
    printByte();
    oldPinValues = pinValues;
}

void loop()
{
    pinValues = readShiftRegisters();
    if (pinValues != oldPinValues) {
        printByte();
        oldPinValues = pinValues;
    }

    delay(1000);
}

unsigned long readShiftRegisters()
{
    long bitVal;
    unsigned long bytesVal = 0;

    digitalWrite(PIN_CE, HIGH);
    digitalWrite(PIN_PL, LOW);
    delayMicroseconds(5);
    digitalWrite(PIN_PL, HIGH);
    digitalWrite(PIN_CE, LOW);

    for (byte i = 0; i < DATA_WIDTH; i++) {
        bitVal = digitalRead(PIN_Q7);
        bytesVal |= (bitVal << ((DATA_WIDTH - 1) - i));

        digitalWrite(PIN_CLK, HIGH);
        delayMicroseconds(5);
        digitalWrite(PIN_CLK, LOW);
    }

    return (bytesVal);
}

void printByte()
{
    for (byte i = 0; i <= DATA_WIDTH - 1; i++) {
     Serial.print("D" + String(i + 1) + " ");
    }
    Serial.println("");
    for (byte i = 0; i <= DATA_WIDTH - 1; i++) {
        Serial.print(pinValues >> i & 1, BIN);
        Serial.print("  ");
    }

    Serial.println("\n");
}
Ausgabe auf der seriellen Konsole
Abb.: Ausgabe auf der seriellen Konsole