- •Practical embedded system programming
- •Void setup() {
- •In this firmware can be activated address bus a0, a1, a2 and a3
- •Void setup() {
- •Void setup() {
- •Void setup()
- •Void setup()
- •Void setup()
- •Void setup()
- •Void setup()
- •Void setup() {
- •Void setup(){
- •Void setup(){
- •Void setup()
- •Void setup()
- •Void setup()
- •Void setup()
- •Void setup()
- •Void setup() {
- •Void setup() {
- •Void setup(){
- •Void setup() {
- •Void setup() {
- •Void setup()
- •Void setup()
- •Void setup() {
- •Void setup() {
- •Void setup() {
- •Void setup() {
- •Void setup()
- •Void setup()
- •Void setup()
- •Void setup() {
- •Void setup() {
- •Void setup() {
- •Void setup() {
- •Void setup() {
- •Void setup() {
Void setup()
{
pinMode(dataPin, OUTPUT); //Configure each IO Pin
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
void loop()
{
//Main program loop as required to go here
}
Example 1 - Single Shift Register - Binary Counter
The first example will simply create a binary counter, and show this incrementing on the LEDs.
To do this, we must first add a variable to the initialisation section which will store the counter, and then add a standard for loop to do the incrementing in the main program loop method. As this is the first example, I will show the complete program, so you can see where the variables and the loop need to be added.
int dataPin = 2; //Define which pins will be used for the Shift Register control
int latchPin = 3;
int clockPin = 4;
int counter = 0; //The counter for storing the byte value
Void setup()
{
pinMode(dataPin, OUTPUT); //Configure each IO Pin
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
void loop()
{
for (counter = 0; counter < 256; counter++)
{
digitalWrite(latchPin, LOW); //Pull latch LOW to start sending data
shiftOut(dataPin, clockPin, MSBFIRST, counter); //Send the data
digitalWrite(latchPin, HIGH); //Pull latch HIGH to stop sending data
delay(500);
}
}
As you can see in the main program loop, a simple for loop increments the counter byte. When we are ready to send the new byte value to the shift register, we must first pull the latchPin LOW. We then send out the data to the shift register (in the correct bit orientation). Once the data has been sent, we pull the latchPin HIGH again to signal that we are finished. The delay instruction simply allows us to control how quickly we write out the bytes to the register, in this case, we are waiting 500milliseconds between increments.
Example 2 - Single Shift Register - LED Sweep
No article involving LEDs and shift registers would be complete unless it includes the trusty Knight Rider KITT Light sweep!
To do this, first we need to set up a byte array to store each of the values in the sweep. If you think about what is happening, all we are doing is turning each bit on and off in sequence, so it would be 10000000, 01000000, 00100000, 00010000, etc. etc. These values are then in turn written out to the shift register.
int dataPin = 2; //Define which pins will be used for the Shift Register control
int latchPin = 3;
int clockPin = 4;
int seq[14] = {1,2,4,8,16,32,64,128,64,32,16,8,4,2}; //The byte sequence
Void setup()
{
pinMode(dataPin, OUTPUT); //Configure each IO Pin
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
}
void loop()
{
for (int n = 0; n < 14; n++)
{
digitalWrite(latchPin, LOW); //Pull latch LOW to start sending data
shiftOut(dataPin, clockPin, MSBFIRST, seq[n]); //Send the data
digitalWrite(latchPin, HIGH); //Pull latch HIGH to stop sending data
delay(75);
}
}
Moving On - Dual Shift Registers
One of the nice features about the Shift Registers is they have a pin called Overflow, and what this basically allows us to do is write more data to the first shift register than it can handle, and it will overflow this excess to this pin. So to extend the chain, we simply connect the first shift registers Overflow to the second shift registers Data pin. This way, if we write out 2 bytes to the first shift register, the first byte is passed onto the second shift register, and the second byte is retained within the first shift register. The schematic below shows how this cascade is connected up, I have also added 3 additional LEDs so we can monitor the DATA, CLOCK and OVERFLOW pins.
For the dual shift register setup, the code is almost identical, the only difference is that we add a second byte array variable and an additional line to write the second byte. To demonstrate this, we will extend the binary counter example from 8 to 16 Bit.
Example 3 - Dual Shift Register - 16Bit Binary Increment
int dataPin = 2; //Define which pins will be used for the Shift Register control
int latchPin = 3;
int clockPin = 4;
int byte1 = 0; //The counter for storing the byte #1 value
int byte2 = 0; //The counter for storing the byte #2 value
