Reading from an 165-series shift register with an SPI peripheral

There's something I don't quite understand about interacting with this shift register.
Let's say I want to use it to capture the state of switches/encoders and periodically read the captured value via SPI.

After reading the datasheet for SN74HC165, I'd want to do this.

  • Q or Q# is MISO.
  • Keep CLK INH low.
  • Initially, set SH/LD# low.
  • Have idle clock high and capture on first (i.e., falling) edge.
  • To read the state of the register, set SH/LD# high and start an SPI transfer.
  • This way, when reading the first bit, we will read Q during the initial falling edge and then the register will shift with the first rising edge.
  • After the transfer, return SH/LD# to low.

CLK in red, MISO in blue. With the last rising edge, MISO goes to 1 (whatever SER was), but later returns to 0, when SH/LD# goes to 0. So far so good; the values are what I expected to read.

It made sense, until I read the remark in the datasheet for CD74HC165, which does not exist in the SN datasheet.

Also, CLK and CLK INH should be LOW before the LOW-to-HIGH transition of SH/LD to prevent shifting the data when SH/LD# goes HIGH.

Ok, it sounds somewhat reasonable, maybe the part was designed to work with idle clock low. But then what is the right thing to do?

  • Assume that the remark does not apply to the SN part? Sounds too optimistic, no?
  • Just change clock polarity to low and hope the SPI peripheral will read the current value of Q before the register shifts? It does seem to work, but also sounds too optimistic (looking how close are those red and blue edges).
  • Set clock polarity to low, capture on the falling edge but also read the initial value of Q/Q# (which the SPI peripheral will miss) before the SPI transfer. Sounds like the right way to go, but also like I'm missing something.
  • Conclude that 165 is not the right choice and use another part? For example, 166. It requires to cycle the clock for parallel read, but maybe it's not more complex in the end.

Posting an annotated schematic would help us help you. You would need to show al connections, power, ground, power sources etc. Here is a link that may help: Interfacing 74HC165 Shift Register with Arduino - Electronics 360 It uses a UNO), no idea what you are using. It appears to follow the timing on page 12 of this data sheet: https://www.ti.com/lit/ds/symlink/sn74hc165.pdf

You miss to specify initial SER and all parallel inputs.

I have a non-Arduino MCU, but I don't think the exact chip matters at this level. The schematic is pretty much this; SH/LD# is connected to a GPIO pin; CLK and Q# to the SPI peripheral pins; and the input pins on the register - to switches and encoders.

SER is shorted to ground, and I'm reading Q#; if you're asking why MISO in the graph becomes high in the end. Parallel inputs are connected to switches and encoders; the values in the graph are what I expected to read.

The best way to understand the functions of the pins of the 165 is to operate it using Arduino UNOR3 (#2) and then operate the chip using SPI Port of Arduino UNOR3.

Convert the following Timing Diagram (Fig-1) of 74LS165 into programming codes. CLK INH must not be tied to GND; rather, it should be pulsed as per Fig-1 before you execute: byte y = SPI.transfer(0x00);. I would recommend to acquire QH and NOT QH/ via MISO line.


Figure-1:

Sample Codes for UNOR3 (untested)

#include<SPI.h>

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

  pinMode(CLK_INH, OUTPUT);
  pinMode(SER, OUTPUT);
  pinMode(SH_LD, OUTPUT);

  digitalWrite(SER, LOW);
}

void loop()
{
  digitalWrite(SH_LD, LOW);
  delayMicroseconds(100);
  digitalWrite(SH_LD, HIGH);
  delay(1);

  digitalWrite(CLK_INH, LOW);

  byte y = SPI.transfer(0x00); //8 SCK pulses are generated

  Serial.println(y, BIN);//should show stutus of input data/swtches

  digitalWrite(CLK_INH, HIGH);
  delay(1000);
}

That does not answer my question :frowning:

If you connect MISO to /Qh then of course you'll read 1 after the last shift, the inverse of initial SER (0).

Will OP not read the exact inverse of QH (Fig-1 of #7) amountig to 8-bit in response to 8 CLK (SCK) pulses?

After 8 CLK pulses the 9th bit (initial SER input) is present at Qh

My study (Fig-1) shows that --

  1. SH/LD pulse will load the 8 input signals into thier target latches.
  2. When byte y = SPI.transfer(0x00); is executed, only then the 8 SCK pulses are genertaed.
  3. The 8 SCK pulses of Step-2 will clock out 8 signals from the internal latches as shown in Fig-1.


Figure-1A:


Figure-1B:

With the highest bit immediately occurring at Qh.

Thank you for taking time to write down the example; it once again illustrates my question. In your example, you pulse SH/LD# while CLK_INH is high, which is similar to what I was going to do initially (having SPI idle clock high and pulsing SH/LD# between SPI transfers). The datasheet even shows this in an example.

The issue I have with this is that CD...165 datasheets (and I think I saw another instance, but I cannot find it now) explicitly ask to not do this.

From CD...165.

Also, CLK and CLK INH should be LOW before the LOW-to-HIGH transition of SH/LD# to prevent shifting the data when SH/LD# goes HIGH.

So my question is whether it's something that affects only some chips or whether it's something that always needs a workaround.

If using SPI Port of UNOR3, SCK is LOW at idle. SCK is only generated when
byte y = SPI.transfer(0x00); is executed. You can see Fig-1A of #11; where, I have modified the data sheet's timing diagram to show the idle condition of SCK.

The best way is: you connect a 74LS165 with UNOR3 and test it with known input signals. Currently, I have no IC to test for you.

Note: 74LS165 is a SPI pheripheral. So, your title may stand as:
Reading from 165-series shift register by SPI Port.

Ok, I found an older HC165 Nexperia datasheet that gives the opposite recommendation.

Either the CP or the CE# should be HIGH before the LOW-to-HIGH transition of PL# to prevent shifting the data when PL# is activated.

What to conclude from this? That 165 chips are in fact not interchangeable? That 165 are supposed to be interchangeable, and these paragraphs just document rare behaviours (bugs?) in specific chip models?

All xxx165 chips should behave exactly as identical. The signal signatures may be different; but, they carry identical meanings.

Do you own a 165 chip, UNOR3, Breadboard, and few male-male jumpers? If yes, make the connection now and post the result. The result will make the conclusion.

Well, this is what I hoped for; I just don't like that some datasheets have additional remarks about the interaction between the clocks and SH/LD#.

I have an SN74HC165 and it behaves as one would expect (see graph in the first post, it's captured from its CLK and Q#), but I'm looking for the "right" way to do things, not what works with my particular chip.

Do you have testing gears -- 165 chip, UNOR3, Breadboard, and few male-male jumpers?

If yes, test the chip and post the output of the Serial Monitor along with the logic values of the input signals.

That remark applies to all chips. It was found worth to mention only after the first document version. Check the document "Errata" section.

Can you pls point me to the "Errata"? I just cannot find it in either datasheet.