4
\$\begingroup\$

When sharing a SPI data line between several ICs and an Arduino, what exactly are the frequency constrains of the CS pin? Can I use a shift register to multiplex the CS pins (thus only requiring one I/O pin, the Shift Register CS, out of the Arduino)? Or does CS must be synced carefully with SCK (in order to avoid garbage if CS is pulled high too "late")

\$\endgroup\$
1
  • 2
    \$\begingroup\$ As long as you put in a small delay after sending CS low before clocking I am sure you will be fine. Are you using a ring counter? \$\endgroup\$
    – Tim M
    Jun 19, 2014 at 9:34

3 Answers 3

3
\$\begingroup\$

Data sheets are usually pretty clear on the timing issues related to chip select lines so I urge you to use the relevant data sheet for the device. Some devices can be activated at the same point at which the data is sent to them; other devices need clear space between CS going low and the SPI data being applied.

Yes, you can use a shift register to select just one particular device but this shift register may need flushing regularly to ensure that over time it hasn't "accumulated" an extra low that could cause two chips o be selected simultaneously. In the main I'd use either a 3 to 8 line decoder for chip selects or individual GPIO lines for each peripheral chip.

\$\endgroup\$
2
\$\begingroup\$

It isn't quite that simple. Think about the sequence of what happens:

  • Assert the CS to the shift register
  • Clock the device CS into the shift register
  • Negate the CS to the shift register
  • Clock the data to the device
  • Assert the CS to the shift register
  • Clock the new device CS data into the shift register
  • ...

That last step is a potential problem. Since the CS for the first device is still asserted while this is going on, it's going to try to interpret the "new device CS data" as data intended for it.

So, while you can use a shift register to select among an arbitrary number of device CS lines, you'll still need a separate "device CS" signal from the Arduino to actually assert (and negate) the selected line(s).

\$\endgroup\$
0
\$\begingroup\$

If you want to use a single GPIO to control all the CS lines you can use a straight ring counter. It has a single clock input and n outputs (depending on the size). Of the n outputs, only one is high at any one time, depending on whether the CS are active low or high use NOT gates accordingly.

All you have to do is keep count of how many times you have clocked the ring counter. If you want to be able to program the chips in any order that's fine as well, because on most IC's if there are not the correct number of clocks before the CS line is deactivated then the input buffers are cleared.

So all you do:

Clock ring counter x times to activate required CS

Clock in data

Clock Ring counter once to deactivate current CS

Rinse. Repeat.

I suggest getting a ring counter with at least one more state that you need so that you have a state where no CS is active, after each data transfer, just clock the ring counter to that position.

As regards your original question, just make sure you put a small delay between clocking the ring counter and starting the data transfer.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.