Sunteți pe pagina 1din 7

How to drive 595 shift registers with AVR hardware SPI | Jumptuck

10/28/2013

Home

AVR/Electronics Tutorials

Programming Tutorials

Books

About Me

Contact

Posted on November 3, 2011 by Mike Szczys

Previous Next

How to drive 595 shift registers with AVR hardware SPI

Driving a shift register using an AVR chips built-in hardware is really quite easy. Most of their offerings have an SPI module, or Serial Peripheral Interface. A shift register is exactly that, a peripheral device that communicates via a serial line. All we need to do is hook up our connections and use a few pieces of simple code. Join me after the break to see how thats done. Just want to know how shift registers work? Check in on my other post on that topic. Schematic

http://jumptuck.com/2011/11/03/how-to-drive-595-shift-registers-with-avr-hardware-spi/#more-455

1/7

How to drive 595 shift registers with AVR hardware SPI | Jumptuck

10/28/2013

The first thing to consider is that it may not be necessary to connect the Clear and Enable pins to the microcontroller. If there are relatively few shift registers being used together it may be easier to shift in all zeros and latch them to the registers. But if timing is a big issue you may want this capability. For this example I have just connected the SCLR pin to VCC and the enable pin to GND. This leaves three control pins: SI, SCK, and RCK. It is possible to drive SCK and RCK from the same signal, but thats for another tutorial. My test hardware, the ATmega168, has pins meant to drive each of these controls. Note that the serial and storage clocks (SCK and RCK) for both shift register chips are hooked together on two data buses. The Serial In of the first chip (SI) is connected to the microcontroller. The QH prime pin of this first chip is connected to the SI pin of the second chip to cascade the data from one to the next.

Test hardware. The ATmega is connected via the ribbon cable.

Using the AVR SPI hardware Accessing the SPI hardware is pretty simple. Theres only a few things that need to happen to get it running: 1. 2. 3. 4. 5. Define which pins were using and set them to outputs Enable SPI and set it to Master mode pull the SS pin low Write our data to the SPDR, it will automatically be strobed into the shift registers Toggle the latch to display the data on the LEDs

The definitions are easy enough. I cant just choose any pins, the SPI outputs are specific pins which can be looked up in the datasheet:
1 2 3 #define SHIFT_REGISTER DDRB #define SHIFT_PORT PORTB #define DATA (1<<PB3)

//MOSI (SI)
2/7

http://jumptuck.com/2011/11/03/how-to-drive-595-shift-registers-with-avr-hardware-spi/#more-455

How to drive 595 shift registers with AVR hardware SPI | Jumptuck

10/28/2013

4 5 1 2

#define LATCH (1<<PB2) #define CLOCK (1<<PB5)

//SS (RCK) //SCK (SCK) //Set control pins as outputs //Set control pins low

SHIFT_REGISTER |= (DATA | LATCH | CLOCK); SHIFT_PORT &= ~(DATA | LATCH | CLOCK);

Enabling SPI in Master mode is a one-liner. But there are other clock prescaling options that you can choose from if you need to. Ill leave that up to you to explore:
1 SPCR = (1<<SPE) | (1<<MSTR); //Start SPI as Master

The SS pin can be pulled low as normal. What I find interesting is that Atmels example code in the ATmega168 datasheet doesnt include this step. You have to really read the SPI section to get at the important nugget: When configured as a Master, the SPI interface has no automatic control of the SS line. This must be handled by user software before communication can start.. We can handle that:
1 2 //Pull LATCH low (Important: this is necessary to start the SPI transfer!) SHIFT_PORT &= ~LATCH;

Now we write our byte to the SPI Data Register. The chips hardware takes it from here. You want to make sure its done shifting out data before sending any more so we use a while loop to check a flag which will be set when the hardware has finished:
1 2 3 4 //Shift in some data SPDR = 0b01010101; //This should light alternating LEDs //Wait for SPI process to finish while(!(SPSR & (1<<SPIF)));

Finally, the LEDs wont light up until the data is latched into the storage register:
1 2 3 //Toggle latch to copy data to the storage register SHIFT_PORT |= LATCH; SHIFT_PORT &= ~LATCH;

The finished program looks like this:


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 #include <avr/io.h> #define #define #define #define #define SHIFT_REGISTER DDRB SHIFT_PORT PORTB DATA (1<<PB3) //MOSI (SI) LATCH (1<<PB2) //SS (RCK) CLOCK (1<<PB5) //SCK (SCK)

int main(void) { //Setup IO SHIFT_REGISTER |= (DATA | LATCH | CLOCK); //Set control pins as outputs SHIFT_PORT &= ~(DATA | LATCH | CLOCK); //Set control pins low //Setup SPI SPCR = (1<<SPE) | (1<<MSTR); //Start SPI as Master //Pull LATCH low (Important: this is necessary to start the SPI transfer!) SHIFT_PORT &= ~LATCH; //Shift in some data SPDR = 0b01010101; //This should light alternating LEDs //Wait for SPI process to finish while(!(SPSR & (1<<SPIF))); //Shift in some more data since I have two shift registers hooked up SPDR = 0b01010101; //This should light alternating LEDs //Wait for SPI process to finish while(!(SPSR & (1<<SPIF))); //Toggle latch to copy data to the storage register SHIFT_PORT |= LATCH; SHIFT_PORT &= ~LATCH; while(1) { //Loop forever } }

And heres what my hardware looks like once I flash it to the chip:

http://jumptuck.com/2011/11/03/how-to-drive-595-shift-registers-with-avr-hardware-spi/#more-455

3/7

How to drive 595 shift registers with AVR hardware SPI | Jumptuck

10/28/2013

Moving beyond

This video shows the result of my hardware setup used as a binary counter. I moved all of the useful commands into functions, set up a delay in the loop, and typecast an Int that gets incremented during each loop in order to shift it out to the registers. Check out my Github repository to see how that was done. It gives you a bit of an idea of where you can go from here. For me, this was just a stopping point before I move my Larson Scanner to an expandable shift-register design and transition away from PWM for a more efficient BCM. Check back soon for that post! Follow Me @szczys
This entry w as posted in Tutorials and tagged atmega168 , AVR , binary counter, led , shift register, spi by Mike Szczys. Bookmark the permalink.

Bank Foreclosure Listings


www.ForeclosureSearch.ca Search Over 6721 Foreclosure Properties By City Or Province!

GDpicture.com CastleOS Home


http://jumptuck.com/2011/11/03/how-to-drive-595-shift-registers-with-avr-hardware-spi/#more-455 4/7

How to drive 595 shift registers with AVR hardware SPI | Jumptuck

10/28/2013

Automation
11 THOUGHTS ON HOW TO DRIVE 595 SHIFT REGISTERS WITH AVR HARDWARE SPI

Randall on November 5, 2011 at 12:53 pm said:

Im new to AVR. I have a atmega32 and my ss pin is !ss, will that make a difference? Log in to Reply

Mike Szczys on November 5, 2011 at 6:34 pm said:

No, Im pretty sure that will work the same way. One thing to be careful of is that you look up register names for your chip. The SPI register (like SPDR) might be slightly different between chips. Log in to Reply

Phil on August 4, 2012 at 11:54 am said:

This is because the SPI interface is also used the other way to actually program the chip (serial interface). So the chip pinout only wants to show the SS pin is active low, like it is often the case with chip select pins on various ICs. They call it Slave Select (SS) because it is used like this when the ATmega is in slave mode. Otherwise its just a standard pin like all the others no need to worry. Log in to Reply

Arup on November 8, 2011 at 11:11 am said:

Nice tut. Off topic, but I want to know how you entered codes like in forum in a WordPress blog. One tip: Though symmetrical, but try to implement same thing in schematics and real breadboarding. In schematics there is resistors between LED and IC pins and LED is connected to power lines. In breadboard I am seeing IC pins goto LED directly and then to power rail via resistor. Though no problem as both are symmetric. Log in to Reply

Mike Szczys on November 8, 2011 at 11:58 am said:

Hi Arup, Thanks for the suggestion about matching up the hardware to the schematic exactly. Youre right, that would cause less confusion! Electrically having the resistor on either side of the LED has the same effect, but assembly may be confusing for the beginner because of this. As far as the source code snippets, I use a plugin for wordpress called SyntaxHighlighter Evolved, which works just
http://jumptuck.com/2011/11/03/how-to-drive-595-shift-registers-with-avr-hardware-spi/#more-455 5/7

How to drive 595 shift registers with AVR hardware SPI | Jumptuck

10/28/2013

like the shortcodes for WordPress.com do. -Mike Log in to Reply

Mikey Sklar on November 8, 2011 at 4:58 pm said:

Good job on documenting this. I had not seen a good tutorial on using AVRs, SPI and shift registers. There are plenty of tutorials without SPI. Is it a typo that you are using PD3 for your DATA line. Your schematic clearly shows PB3 being used. Log in to Reply

Mike Szczys on November 8, 2011 at 6:00 pm said:

Thanks for the compliment. Yes, thats a bad typo good eye. I fixed it in the post and Im off to check Git to see if the error is there too. Log in to Reply

Mike Szczys on November 8, 2011 at 6:02 pm said:

Holy cow, that typo is in the code it must not be very important that you setup the MOSI pin correctly. Yikes! Log in to Reply

Luke on March 29, 2012 at 7:27 am said:

Nice tutorial One question: why toggle the latch instead of just make it high again after youre done sending? Youre making it low again anyway next time you send. Log in to Reply

Luke on March 29, 2012 at 7:31 am said:

also, pin names, are just defines (PB0 = 0, PB1 = 1) so it really doesnt matter if you set PORTB |= (1<<PC1) | (1<<PD2) | (1<<PA3); it will work just as well as PORTB |= (1<<PB1) | (1<<PB2) | (1<<PB3); Log in to Reply

http://jumptuck.com/2011/11/03/how-to-drive-595-shift-registers-with-avr-hardware-spi/#more-455

6/7

How to drive 595 shift registers with AVR hardware SPI | Jumptuck

10/28/2013

zaphodikus on June 11, 2012 at 9:35 am said:

I have shamelessly used your most excellent explanation notes to get 4 595s attached to an Atmega368 running 16Mhz with the SPI port double-speed clocked and additionally added PWM to drive the enable pin on the 595s. This gives me rudimentary dimming, the whole shebang I would not have gotten working without your diagrams. Can you upload the visio file to the github? I am driving my project from a serial port, and using some Windows Powershell all of which I hope to publish and link to your page. I just need a decent diagram to go with it. So I can like to steal yours, do you do paypal beer-money Mike? Log in to Reply

Leave a Reply
You must be logged in to post a comment.

Proudly powered by WordPress

http://jumptuck.com/2011/11/03/how-to-drive-595-shift-registers-with-avr-hardware-spi/#more-455

7/7

S-ar putea să vă placă și