Jump to content
Sign in to follow this  
gatesphere

Quick and dirty 74HC595 shift register demo

Recommended Posts

Hi all.

 

In an effort to prototype the shiftOut() function for my MSPhere library, I went ahead and threw together a quick and dirty binary LED counter using the LaunchPad, 8 LEDs, 8 1k resistors (not ideal, but they're the lowest value I had on hand, the rest are packed up to go to campus with me on Sunday), and of course, a 74HC595 shift register.

 

Basically, you set up the circuit as follows: (all pin numbers are in regards to the '595 chip, information available at http://www.msarnoff.org/chipdb/74595)

Q0-Q7 (pins 15, 1-7): LED to ground, with suitable resistor in series.

GND (pin 8): ground, obviously.

Vcc (pin 16): Vcc, obviously :P

MR (pin 10): Vcc.

OE (pin 13): ground.

DS (pin 14): P1.0 on the LaunchPad

RCK (pin 12): P1.1 on the LaunchPad

SCK (pin 11): P1.2 on the LaunchPad

 

What the code does is count from 0 to 255, with each count setting the latch pin (RCK, P1.1) low to prevent flashing of the LEDs while shifting bits, and then calls shiftOut(), which breaks the value down into bits, writing them out to DS one at a time, while pulsing SCK low-high in the process to allow the bits to be shifted out. After that, the RCK is brought high again, allowing the LEDs to light in unison. Then there is a delay of 25000 clock cycles to allow the count to be followed by the human eye.

 

Here's my code:

// LaunchPad 74HC595 Test
// uses a 74HC595 chip to make a binary counter which counts from 0 to 255 and then resets

// written by gatesphere/suspended-chord (http://suspended-chord.info/)
// 27 August 2010
// placed into the public domain

#define __MSP430G2231__
//#define MSBFIRST  //uncomment this line to shift bits out in reverse (most significant bit to least significant bit)
#include 

// pins:
// P1.0 -> data pin DS (pin 14)
// P1.1 -> latch pin RCK (pin 12)
// P1.2 -> clock pin SCK (pin 11)

#define DATAPIN BIT0
#define CLOCKPIN BIT2
#define LATCHPIN BIT1

void shiftOut(char data);

void main() {
 WDTCTL = WDTPW + WDTHOLD;   // kill WDT
 P1OUT = 0x00;
 P1DIR = DATAPIN + CLOCKPIN + LATCHPIN;


 while(1) {
   volatile unsigned char i = 0;
   volatile unsigned int j;
   while (i < 256) {
     P1OUT &= ~LATCHPIN;           // take latch low
     shiftOut(i);                  // push out i
     P1OUT |= LATCHPIN;            // enable LEDs
     i++;
     for (j = 0; j < 25000; j++);  // delay 25000 cycles
   }
 }
}

void shiftOut(char data) {
 volatile int i;
 char temp, temp2;
#ifdef MSBFIRST // reverse order of the bits
 for (i = 0; i < 8; i++) {
   temp = (0x01 & data);
   data = data >> 1;
   temp2 = (temp2 << 1) + temp;
 }
 data = temp2;
#endif
 for (i = 0; i < 8; i++) {         // 8 bits to a char
   char bittowrite = (0x01 & data); // get bit
   data = data >> 1; // shift data left
   if (bittowrite == 1) {  // send bit
     P1OUT |= DATAPIN;
   } else {
     P1OUT &= ~DATAPIN;
   }
   // pulse clockpin
   P1DIR |= CLOCKPIN;
   P1DIR &= ~CLOCKPIN;
 }
}

Share this post


Link to post
Share on other sites

Sorry for the double post, but I just thought I'd offer a bit of a comparison between standard MSP430 C and MSPhere C code. Here is the exact same example, written using my current version of the MSPhere framework. I'm nearing a release, by the way. I just want to get a few more important functions working before I put it out.

 

Anyways, here's the same binary counter using a 74HC595 as before.

// 74HC595 demo - MSPhere version
#include "msphere.h" // include the MSPhere core library
#include "msphere_digital_io.h" // include digital i/o functions - for pinMode() and digitalWrite()
#include "msphere_advanced_io.h" // include advanced i/o functions - for shiftOut()

#define CLOCKPIN 2
#define DATAPIN 0
#define LATCHPIN 1

void setup() {
 WDTCTL = WDTPW + WDTHOLD;     // kill WDT
 pinMode(DATAPIN, OUTPUT);
 pinMode(LATCHPIN, OUTPUT);
 pinMode(CLOCKPIN, OUTPUT);
}

void loop() {
 volatile unsigned int i, j;
 for (i = 0; i < 256; i++) {
   digitalWrite(LATCHPIN, LOW);
   shiftOut(DATAPIN, CLOCKPIN, MSBLAST, i);
   digitalWrite(LATCHPIN, HIGH);
   for (j = 0; j < 25000; j++);
 }
}

 

This clocks in at 25 lines, including whitespace and comments. Much more concise and readable, I think, and a bit more manageable. Anyways, that's just my two cents.

Share this post


Link to post
Share on other sites
Do you think I could use the 74VHC164 chips I have knocking around my parts bin?

 

you should be able to. Looks like they do the same thing. 8-bit serial in, parallel out.

Share this post


Link to post
Share on other sites

The data for that IC (which I'm unfamiliar with) is available here: http://www.msarnoff.org/chipdb/74164

 

According to the data sheet, pins 1 and 2 act as the input for that chip, and the logical AND of those two pins is shifted into the register when the clock pin, 8, is pulsed from low to high. To use my code, pins 1 and 2 either have to be tied together, or pin 2 has to be tied to Vcc. There is no latch pin for this IC. So, I'm guessing the circuit would be:

Pin 1 - P1.0 on the LaunchPad (data A)

Pin 2 - Either Vcc or P1.0 as well (data B)

Pin 7 - Gnd

Pin 8 - P1.2 on the LaunchPad (clock)

Pin 9 - Vcc (reset, active low)

Pin 14 - Vcc

Pins 3-6, 10-13 - LEDs with resistor in series.

 

Then, take my code and remove all the stuff about latch pins. It should work then. Actually, it should work anyways, because with that circuit, nothing will be attached to P1.1 on the LaunchPad. But it's bad habit to get into to leave useless code in your projects. At the very least, I'd comment it out.

 

Please do try it, and let me know if it works! I don't have any other SPI chips at the moment, so I would love some feedback on if my shiftOut() function works with other chips.

Share this post


Link to post
Share on other sites

Great, now that I have a use for them, I can't find them. I have the data sheet, so I had them at some point.

 

If I find them, I'll try them out and let you know.

 

-Doc

Share this post


Link to post
Share on other sites

The only problem is that 164 doesn't have output latch which means your data will be shifting each time you send it to 164 and your output will be unreliable. This might be fine if you are using it for display purposes and you are shifting fast enough, but if you are planning to control relays for example, 164 is a bad choice.

Share this post


Link to post
Share on other sites

I was planning on using them with a character LCD module. The LCD has a clock pin, so it will ignore inputs (from the 164) until the clock pin switches. In this case, the latch on the 595 would be redundant. That said, the 595 is more common in parts bins, so I am trying to design to use it.

Share this post


Link to post
Share on other sites
I was planning on using them with a character LCD module. The LCD has a clock pin, so it will ignore inputs (from the 164) until the clock pin switches. In this case, the latch on the 595 would be redundant. That said, the 595 is more common in parts bins, so I am trying to design to use it.

Instead of using a 164 or 595, you could use a CD4094, or two 374's, one 374 connected with its registers in series, the other with its registers coming off the first one's. You would then have a serial in/serial or parallel out shift register, from common components. I had once designed an 8-bit serial/parallel in, serial/parallel out shift register, from two LS244's and one LS374.

I have the schematic if you want it.

 

A new user,

 

Nuetron

Share this post


Link to post
Share on other sites
Instead of using a 164 or 595, you could use a CD4094, or two 374's, one 374 connected with its registers in series, the other with its registers coming off the first one's. You would then have a serial in/serial or parallel out shift register, from common components. I had once designed an 8-bit serial/parallel in, serial/parallel out shift register, from two LS244's and one LS374.

I have the schematic if you want it.

:shock: I'm just a noob hobyist... I don't think I'm ready to take the training wheels off yet. ;)

 

Thanks, though. This falls in my "When I get some round tuits" category. :)

Share this post


Link to post
Share on other sites

Hi gatesphere,

 

I am using Embedded Workbench 6.0 Kickstart. When I compile your MSPhere 74HC595 shift register demo, I get this error:

Error[e46]: Undefined external "main" referred in ?cstart ( C:\Program Files\IAR Systems\Embedded Workbench 6.0 Kickstart\430\LIB\CLIB\cl430f.r43 )

 

Do you know what's wrong?

Share this post


Link to post
Share on other sites
The only problem is that 164 doesn't have output latch which means your data will be shifting each time you send it to 164 and your output will be unreliable.

Coupled with a bit of a thread hijacking, I've been meaning to ask this for a while: with the '595, when latching the storage register out to the pins, is there any transient on those pins that do not change? (I would think no, but never hurts to ask...)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×