Wednesday, January 28, 2009

Shift Registers on the Arduino

Well, I got my shfit registers and some more apt LEDs (that aren't 10mm blue LEDs) to play with. This is a step toward the Arduino flash programmer. I also have the ZIF socket I need and the stuff to make a shield, so really I'm all set to build it. But first, the shift registers.

From Arduino Shift Registers


The Arduino doesn't have all that many output pins. There are 13 digital pins, plus 6 analog pins that can be used as digital pins, but that's really not that many when you're trying to interface with parallel flash chips. First, pins 0 and 1 will be used for serial communications, so you're down to 18 pins. Then you realize the flash chip you want to program has 18 address pins, 8 data pins and 3 control pins. Hmm... not going to fit. You need to use a little external circuitry to extend your pins.

Grumpy_Mike on the Arduino forums recommend that I use an I2C extender chip called the MCP23016. I looked at this, but it was a little to complicated. And by that, I mean I've never used I2C, don't have this chip and didn't immediately understand how to use it. However, it's a better general solution as the 2 8-bit ports it provides are bi-directional, but since I'm only using this to reach the address pins, it's not a problem here.

Shift registers are much simpler. They're a chain of 8 flip-flops in a chip. You clock data into them, 1 bit at a time. Then, you pulse the latch pin on the chip and it saves the state of those 8 flip-flops into 8 other flip-flops that drive the output pins. It's as simple as you can imagine, but to explain it better and visualize this (and even play with a simulation of this), check out www.play-hookey.com. Of interest are the pages on Digital Logic, the D-Type Flip-Flop and of course the Shift Registers. These pages are amazing, they explain everything and give you interactive examples to play with. Really, check them out.

Shift registers can be chained or cascaded. The output of the last flip-flop is exposed on a pin, so it can be used as the input to the first flip-flop on the next pin. For just 3 pins on the Arduino, you can extend your Arduino's reach by any number of output pins. The first pin goes to the input of the first flip-flop, the second goes to the clock input of both flip-flops, and the third goes to the latch pin on both flip-flops. For just 3 pins and 2 external chips, I can reach 16 address lines on the flash chip. The remaining two, I can reach with pins on the Arduino.

For a more detailed account of using shift registers on the Arduino, see this tutorial on ShiftOut and shift registers. I even used the same chips as this (or close enough, I have 74HCT595's), only didn't find this until I encountered a problem hooking them up and started googling. My problem was simple, I just had a jumper in the wrong place. The ShiftOut function is easy to use, and can shift out bits in both bit orders.

There are disadvantages to using shift registers though. First, it takes time to shift out data. The shift registers I have only operate at 1MHz. This means my Arduino (which runs at 16MHz) has to sit in a wait cycle while shifting out bits. As opposed to having 16 digital pins (which are more or less instant), I have to wait to shift out all 16 bits. That might not be an issue with just 16 bits, but it limits the number of shift registers you can chain. It's not an issue here though, so I'm not worried about it.

Anyway, here's a few more pics. Oh, and the code is on pastie.

From Arduino Shift Registers


From Arduino Shift Registers

2 comments:

Anonymous said...

I read your comment about the speed of the shift register. Will a counter help? If you program a sequence of address you can load a counter with your shift registers and then use the counter to increment address which is much faster than shifting in a new address. Just a thought.

UziMonkey said...

Thanks for the comment. I replied on the forums as well, so I'll just copy and paste here.

I had considered using a counter for my flash chip programmer, but it just wasn't necessary. Too slow is OK, and the shift registers are simple. Though now that I think about it, I only ever increment the address, so a counter would have worked.

I was just talking about one limitation of the shift registers, that they're not drop in replacement for more io pins. I wasn't referring to any problem I was actually having.