Eight switches go on D0 to D7, one pulse grabs them all at once, and then they
come out of Q7 one at a time as you clock. Aliases: 74165, SN74HC165, parallel-in
serial-out, PISO, input shift register.
Pins
| Pin | Name | What it does |
|---|---|---|
| 1 | PL |
Parallel load, active low. While low, the register copies D0 to D7. |
| 2 | CP |
Clock. A rising edge shifts the register one place towards Q7. |
| 11 to 14, 3 to 6 | D0 to D7 |
The eight parallel inputs. |
| 10 | DS |
Serial in: what shifts into stage 0. Chain it to the previous chip's Q7. |
| 9 | Q7 |
Serial out: always shows stage 7. |
| 7 | Q7N |
The complement of Q7. |
| 15 | CE |
Clock enable, active low. High stops the clock. |
| 8 | GND |
Ground. |
| 16 | VCC |
Supply, 2 V to 6 V. |
Truth table
PL |
CP |
CE |
What happens |
|---|---|---|---|
| 0 | x | x | Load D0 to D7 (continuously, while PL is low) |
| 1 | 1 | x | Hold |
| 1 | x | 1 | Hold |
| 1 | 0 | rising | Shift (CE acts as the clock) |
| 1 | rising | 0 | Shift |
After a load, Q7 is already showing D7. Seven more clocks bring out D6 to D0.
So read each bit before its clock pulse:
digitalWrite(PL, LOW); // grab the switches
digitalWrite(PL, HIGH);
byte switches = 0;
for (int bit = 7; bit >= 0; bit--) {
bitWrite(switches, bit, digitalRead(Q7)); // read first
digitalWrite(CP, HIGH); // then clock
digitalWrite(CP, LOW);
}
Arduino's shiftIn(dataPin, clockPin, MSBFIRST) does not fit this chip. For each bit
it raises the clock first and reads the data pin second, so the first rising edge
shifts D7 away before it is read. With eight buttons on D0 to D7, pressing
button 0 reads as 00000010 and button 7 is never seen.
Properties
None.
What the model gets right
The load is asynchronous and continuous, as on the real chip: hold PL low and Q7
follows D7 live, and the clock does nothing. The clock and CE go through one OR
gate inside the chip, so a rising CE with CP low shifts too; the model does the
same. Propagation delays are the SN74HC165 data sheet's typicals at 4.5 V: 15 ns from
the clock to Q7, 20 ns from PL. A clock edge out of a floating or unknown level is
not trusted, and leaves the register unknown rather than guessing.
What it does not model
No setup, hold or minimum pulse-width checks. One delay for each path, with no spread with supply voltage or load. The register powers up cleared, where a real one powers up random (which does not matter, because you load it before you read it).
Common mistakes
Forgetting to pull PL low before reading, so the same old byte shifts out. Leaving
CE floating (tie it to GND). Reading after the clock instead of before it, which
loses D7 and reads a bit from DS at the end. shiftIn() makes exactly this mistake.
See it in action
Switch shifter loads an 8-way DIP switch into a 165 and clocks the byte round and round past an LED. Open it at /templates.