Stairs.  Entry group.  Materials.  Doors.  Locks.  Design

Stairs. Entry group. Materials. Doors. Locks. Design

» Using shift registers in display devices. Shift Registers Latch Shift Register 4 Bit

Using shift registers in display devices. Shift Registers Latch Shift Register 4 Bit

According to the clock signal, the contents of each previous trigger are rewritten into the next trigger in order in the chain. The code stored in the register is shifted by one digit towards the higher digits or towards the lower digits with each clock cycle, which gives the name to registers of this type.

In connection with the name of the direction of shift in shift registers There is often confusion. There are two types of shift: to the right (the main mode that everyone has shift registers) and to the left (only some, reverse, have this mode shift registers). These names reflect the internal structure shift registers(Fig. 8.14) and rewriting signals sequentially along a chain of triggers. In this case, flip-flops, quite naturally, are numbered from left to right, for example, from 0 to 7 (or from 1 to 8) for 8-bit registers. As a result, shifting information by a register to the right is a shift towards bits with higher numbers, and shifting information by register to the left is a shift towards bits having lower numbers.

However, as you know, in any binary number the most significant bits are on the left, and the least significant bits are on the right. Therefore, shifting a binary number to the right will be a shift towards the low-order bits, and shifting to the left will be a shift towards the high-order bits. This is a contradiction, not someone’s malicious intent, it just happened historically, and the developer of digital equipment must remember this.


Rice. 8.14.

The standard series of digital microcircuits includes several types shift registers, differing in possible operating modes, write, read and shift modes, as well as the type of output stages (2C or 3C). Majority shift registers has eight digits. In Fig. 8.15 shows four types of microcircuits as an example shift registers.

The IR8 register is the simplest of shift registers. It is an 8-bit delay line, that is, it has only one information input, to which serial shifted information is supplied (more precisely, two inputs combined using the 2I function), and eight parallel outputs. The shift towards outputs with higher numbers is carried out along the leading edge clock signal C. There is also a reset input –R, upon a zero signal on which all register outputs are reset to zero. Truth table register IR8 is given in table. 8.5.


Rice. 8.15.Table 8.5. Truth table shift register IR8
Inputs Exits
-R C D1 D2 Q0 Q1 Q7
0 X X X 0 0 0
1 0 X X Don't change
1 1 X X Don't change
1 0 1 1 1 1 Q0 Q6
1 0 1 0 X 0 Q0 Q6
1 0 1 X 0 0 Q0 Q6

The IR9 register performs the inverse function of the IR8 register. If IR8 converts input serial information into output parallel, then register IR9 converts input parallel information into output serial information. However, the essence of the shift does not change, it’s just that in IR9 all internal triggers have parallel inputs, and only one, the last trigger, has an output (both direct and inverse). The input code is written to the register based on a zero signal at the -WR input. The shift is carried out on a positive edge on one of the two clock inputs C1 and C2, combined

1. Table of contents

2. Introduction ……………………………………………………………………………… 2

3. Review of literary sources ………………………………… 3

3.1. General information about registers ………………………………… 3

3.2. General information about triggers…………………………….…... 6

3.3. Shift registers…………………………………….. 12

3.4. Universal registers…………………………………….. 20

4. Development of a shift register circuit ………………………………… 24

4.1. Initial data ……………………………………………… 24

4.2. Procedure for developing a shift register…………………..……… 24

4.3. Development of a four-phase shift register…………………… 25

5. Conclusion……………………………………………………………. 27

6. List of references …………………………………. 28


2. Introduction

Registers– the most common components of digital devices. They operate on the many related variables that make up a word. A number of operations are performed on words: receiving, issuing, storing, shifting in the bit grid, bitwise logical operations.

Shift (sequential) registers are used for shifting n-bit numbers in one direction. In addition, they can be used to shift non-numeric information.

Shift registers are used as storage devices, as converters of serial code to parallel, as delay devices and pulse counters (however, the use of shift registers as counters is quite uneconomical).

3. Review of literature sources

3.1. General information about registers

Registers consist of bit circuits that contain flip-flops and, most often, also logic elements. They act as a single unit.

According to the number of variable transmission lines, registers are divided into single-phase and paraphase, and according to the synchronization system into single-cycle, push-pull and multi-cycle. However, the main classification feature is the method of receiving and issuing data. On this basis they distinguish parallel (static) registers, sequential (shifting) And parallel-serial .

In parallel registers, words are received and output in all bits simultaneously. They store words that can be subjected to bitwise logical transformations.

In sequential registers, words are received and output digit by digit. They are called shifting, since timing signals when inputting and outputting words move them in the bit grid. A shift register can be non-reversible (with unidirectional shifts) or reversible (with the ability to shift in both directions).

Serial-parallel registers have inputs and outputs of both serial and parallel types. There are options with serial input and parallel output (SIPO, Serial Input – Parallel Output), parallel input and serial output (PISO, Parallel Input – Serial Output), as well as options with the possibility of any combination of methods for receiving and issuing words.

In parallel (static) registers, bit circuits do not communicate with each other. Common to the bits are usually clock circuits, reset/set circuits, output or receive permission, that is, control circuits. An example circuit of a static register built on D-type flip-flops with direct dynamic inputs, having reset inputs R and third-state outputs controlled by the EZ signal, is shown in Figure 1 .

Picture 1. Diagram of a static register (a) and its conventional graphic designation (b)

Modern circuit technology is characterized by the construction of registers on D-type flip-flops, mainly with dynamic control. Many have outputs with a third state. Some registers are classified as buffer registers, that is, they are designed to work with large capacitive and/or low-resistance active loads. This ensures their operation directly on the highway (without additional interface circuits).

Static registers are used to create blocks of register memory—register files.

Main functions of registers:

1) Information storage,

2) Reception of information,

3) Providing information,

4) Information shift,

5) Code conversion,

6) Setting the desired number to zero or one,

7) Bitwise logical operations: disjunction, conjunction, addition modulo 2.

3.2. Understanding Triggers

Triggers – a large class of electrical devices that allow it to remain in one of two (or more) stable states for a long time and alternate them under the influence of external signals (as a result of the regenerative process (transient process in an electrical circuit covered by a PIC)).

A trigger is a pulse logical device with memory (memory element – ​​latch).

There are more than a dozen different integral triggers. Their classification is based on:

Functional sign

A method for writing information to a trigger.

Based on their functional characteristics, there are T-triggers, JK-triggers, RS-triggers, D-triggers, combined triggers (TV, DV, E, R), etc.

Based on the method of recording (receiving) information, they are distinguished:

8) Asynchronous triggers:

a) with internal delay;

b) controlled by the input pulse level;

9) Synchronous triggers (clocked):

a) with internal delay;

b) controlled by the level of the timing pulse:

Single-cycle action (single-stage);

Multiple action.

Information is written to clocked triggers only when an enabling clock pulse is applied. Such triggers are divided into level-controlled (a certain signal level is required for operation) and edge-controlled (do not depend on the signal level, its presence is important) of the timing pulse. Clock pulses are sometimes also called synchronizing, executive, or command signals (usually denoted in diagrams by the letter C - Clock).

Dynamic input can be direct or inverse. Direct dynamic control allows switching when the clock signal changes from zero to one (). Inverse dynamic control - changing the clock signal from one to zero (). Control of the edge of the timing pulse: Control of the fall of the timing pulse: Control of the upper level of the timing pulse:

Control of the lower level of the timing pulse:

Clocked triggers with an internal delay (triggered when the signal ends) are, as a rule, single-ended. Multi-cycle triggers fire after n-nogo impulse.

The RS trigger has two information inputs: S (Set) and R (Reset). Simultaneous application of S and R signals is not allowed. On Figure 2 shows a synchronous RS trigger triggered by the edge of the timing signal.

Figure 2. Synchronous RS trigger

In addition to inputs, the simplest RS trigger also has two outputs. Outputs indicate Q And

. Exit Q called direct, a - inverse. The voltage levels at both outputs are mutually inverse: if the signal Q= 1, then = 0, or if Q= 0, then = 1. It should also be noted that the state of the trigger in which Q= 1, a = 0, is called unit. When the trigger is zero Q= 0 and = 1. When signals arrive at the inputs of the trigger, depending on its state, either switching occurs or the original state is preserved.

Figure 3. - trigger: its conventional graphic designation and a circuit with two logical elements AND-NOT

Shift register- this is a set of sequentially connected triggers (usually there are 8 of them). Unlike standard registers, shift registers support right and left shift functions. (i.e., rewriting data from each previous trigger to the next one).

The functionality and purpose of shift registers is quite large. Today we will introduce one of them to Arduino (Great way to multiply Arduino outputs: borrow 3, get 8).

Probably the most popular microcircuit that represents such a register is 74HC595.

Works on the SPI interface: legs DS, ST_CP, SH_CP are control buses. Accordingly: data bus (MOSI), latch (SS) and clock line (SCK). We connect to any 3 Arduino pins (the SPI library will not be used in the code). For me these are 12, 10, 13 Arduino outputs (standard).

Legs Q0, Q1, ..., Q7 are register outputs (bits). In order to monitor the status of each of them, we will hang an LED on each terminal (with a resistor connected in series. Nominal value from 150 to 330 Ohms)

VCC and GND are power supply. Connect to +5v and GND.

We do not touch output Q7` (intended for serial connection of such registers)

MR is a reset. Connect to +5v (reset is not active).

Well, we attract OE to the ground (connect it to the GND contact).

It turns out this is the diagram:

You can place it on BreadBoard like this:

Now to the code:

As stated earlier, the SPI library will not be used. There is a convenient function shiftOut() .

To begin with, we name our pins (clock line - clock, data - data, latch - latch):

#define clock 13 #define data 12 #define latch 10

then in void setup() we designate them as outputs and immediately set the latch to a high level so that the register does not receive signals:

Void setup())( pinMode(clock, OUTPUT); pinMode(data, OUTPUT); pinMode(latch, OUTPUT); digitalWrite(latch, HIGH); )

now let's try to send something to the register:

First, set LOW on the latch (we begin data transfer. Now the register receives signals from the Arduino).

DigitalWrite(latch, LOW);

Then we send the data (that is, we send the byte in digital or binary form. In binary it is easier, since each of the 8 bits is responsible for its own bit in the register. It’s easier to navigate with your eyes):

First, let's send byte 0b10000000; (the first LED should light up):

ShiftOut(data, clock, LSBFIRST,0b10000000);

And at the end we set the latch to HIGH (we finish transmitting data).

DigitalWrite(latch, HIGH);

As a result, all our code:

#define clock 13 #define data 12 #define latch 10 void setup() ( pinMode(clock, OUTPUT); pinMode(data, OUTPUT); pinMode(latch, OUTPUT); digitalWrite(latch, HIGH); ) void loop() ( digitalWrite(latch, LOW); shiftOut(data, clock, LSBFIRST, 0b10000000); digitalWrite(latch, HIGH); )

Now we load it into the Arduino. The result should be like this (the first LED lights up):

(if not the first, but the last LED is lit, then in the shiftOut function change LSBFIRST to MSBFIRST and everything will fall into place).

So, it worked! I propose to create a function so as not to write these 3 LINES every time:

I'll call it: sendbyte;

Void sendbyte(byte value)( digitalWrite(latch, LOW); shiftOut(data, clock, LSBFIRST, value); digitalWrite(latch, HIGH); )

This function sends the status of all bits to the register at once. This will come in handy for (for example). But to use the register as a port expander, you need to control each bit individually (similar to the digitalWrite() function):

We can only send full bytes to the register (8 bits - 0b00000000). If you send not 8, but 5 bits (for example: 0b00000 000), then the register will wait for the missing 3 bits. This means that when we want to change the state of one bit of a register (turn it on or off), we must, in fact, send the previously sent byte, with a change of one bit.

(P.S.: Now there is a long and tedious explanation (for beginners), who are not interested, go down a little lower :);

So, first we create the so-called (by me) database, which will store the state of each bit (on (HIGH) or off (LOW)). type: boolean:

Boolean states;

Each variable in this array denotes its own digit (zero (counting) will store the state of the 1st digit, the second - the 3rd, etc.)

Now let's write a function (I'll call it: sendpin). It will take 2 values: the digit number, and the level that we need to assign to this digit: high (HIGH) or low (LOW).

Void sendpin(int pin, boolean state)( pin--; states=state; byte value = 0; byte add = 1; for(int i=0; i<8; i++){ if(states[i]==HIGH) value+=add; add*=2; } digitalWrite(latch, LOW); shiftOut(data, clock, LSBFIRST, value); digitalWrite(latch, HIGH); }

Due to the fact that counting starts from zero, we will have to call the first pin zero. To fix this (we will write it as it is (the first one means the first one), and Arduino itself will write more than one), I wrote:

Then we mark the changes in the database:

States=state;

Now we need to form a byte from 8 bits and send it to the register.

First, let's create variables:

value is the byte that we will send. (by default it should be set to zero):

Byte value = 0;

add is a variable that will store the byte of the current digit. for the first bit this is byte 1 (0b10000000);

Byte add = 1;

Now we need to scroll through all 8 variables in the database and form a byte (we will do this using a for() loop:

For(int i=0; i<8; i++){ }

So, each time we check the next digit in the database. If it should have a high level, then we add add to value and move to the next digit in the chain (as if we were shifting one digit higher (to the left). That is, in binary code everything is simple: it was like this: 0b01000000; shifted one to the left and it turned out like this: 0b10000000. But in digital form, everything is different. Shifting to the left is similar to multiplying by 2 (and to the right, by the way, is dividing by 2)). It turns out something like this:

If(states[i]==HIGH) value+=add; add*=2;

Now all that remains is to send value to the register:

DigitalWrite(latch, LOW); shiftOut(data, clock, LSBFIRST, value); digitalWrite(latch, HIGH);

In principle, if you understand, everything is very simple.

So, let's try to turn on 2, 4, 6, and 8 digits separately (we'll write our function in a loop 4 times):

Sendpin(2, HIGH); sendpin(4, HIGH); sendpin(6, HIGH); sendpin(8, HIGH);

And by the way, in setup-e you need to clear the register (send 0).

You can even create a function like this:

Void cleanreg())( for(int i=0; i<8; i++) states[i]=LOW; digitalWrite(latch, LOW); shiftOut(data, clock, LSBFIRST, 0); digitalWrite(latch, HIGH); }

In general the result is:

List of radioelements

Designation Type Denomination Quantity NoteShopMy notepad
Arduino board

Arduino Uno

1

At some point in time, you will inevitably run into the problem of not having enough pins on your Arduino to meet the needs of your project or prototype. The solution to this problem? Shift register, or rather Arduino shift register 74hc595.

Anyone who has done Arduino projects where they use a lot of LEDs has realized that they are largely limited by the Arduino pins and cannot create huge projects that require a large number of pins. In our particular project, 16 LEDs are controlled by just three Arduino pins. The key element is the Arduino 74hc595 shift register. Each 74HC595 shift register can accept up to 8 LEDs, and using sequential chains of registers, you can increase the board contacts from a conventional 3 to an infinite number.

Before we start connecting the chip, let's look at how the process works.

The first thing to clear up is the concept of "bits" for those of you who are not familiar with binary code. When we talk about “bits,” we mean one of the numbers that makes up a binary value. Unlike ordinary numbers, we usually consider the first bit to be the largest. So, if we take the binary value 10100010, the first bit is actually 0 and the eighth bit is 1. It should also be noted, unless it was implied, each bit can only be 0 or 1.

The chip contains eight pins that we can use for output, each pin associated with a bit in a register. In the case of the 74HC595 shift register, we look at them from QA to QH.

To write these outputs through Arduino we have to send a binary value to the shift register and from that number the shift register can determine which outputs to use. For example, if we sent the binary value 10100010, the contacts highlighted in green in the image above will be active and those highlighted in red will be inactive.

This means that the rightmost bit is mapped to QH and the leftmost bit is mapped to QA. An output is considered active when the bit associated with it is set to 1. It's important to remember this because otherwise you'll have a very hard time knowing which pins you're using.

Now that we have a basic understanding of how we use bit offset to specify which pins to use, we can start connecting it to our Arduino.

We start with 8 LEDs

For the first part of the lesson we will need the following components:

  • Arduino Uno
  • Bread board
  • Arduino shift register 74HC595
  • 8 LEDs
  • 8 resistors - 220 ohms should be enough
  • Wires/jumpers

Start by placing the shift register on your layout, ensuring that each side is on a separate side of the layout, as shown below.

With the lettering facing up, pins 1-8 on the left side from top to bottom and 16 - 9 on the right side from top to bottom, as shown in the picture below.

Assembling the circuit

First, connect pins 16 (VCC) and 10 (SRCLR) to the 5v output on the Arduino and connect pins 8 (GND) and 13 (OE) to the Gnd pin on the Arduino. Pin 13 (OE) is used to enable the outputs as it is an active low pin which we can connect directly to ground.

Next we need to connect three pins that we will use to control the shift register:

  • Pin 11 (SRCLK) of the 74HC595 shift register to pin 11 on the Arduino - this will be called the "sync pin"
  • Pin 12 (RCLK) of the shift register to pin 12 on the Arduino - this will be referred to as the "latch pin"
  • Pin 14 (SER) of the shift register to pin 13 on the Arduino - this will be called the "data pin"

All three of these pins are used to perform the bit shifting mentioned earlier in this tutorial. Luckily, Arduino provides a helper function specifically for shift registers called shiftOut that will handle almost everything for us, but we'll come back to that as we review the code.

Now we just need to connect all the output pins to our LEDs, ensuring that a resistor is placed in front of the LEDs to reduce the current and that the cathodes of the LEDs are pointed towards ground.

To keep wire clutter to a minimum, we placed the resistors and LEDs on a separate breadboard, however, you can use a single breadboard.

When placing the LEDs, make sure they are connected in order so that QA is connected to the first LED and QH is connected to the last LED, otherwise our code will not turn on the LEDs in the correct order. When you're finished, you should have something like this:

Sketch for Arduino

Now we are ready to upload the code. Connect your Arduino to your computer and download the following sketch for 74hc595 Arduino to it:

Int latchPin = 12; int clockPin = 11; int dataPin = 13; byte leds = 0; int currentLED = 0; void setup() ( pinMode(latchPin, OUTPUT); pinMode(dataPin, OUTPUT); pinMode(clockPin, OUTPUT); leds = 0; ) void loop() ( leds = 0; if (currentLED == 7) ( currentLED = 0; ) else ( currentLED++; ) bitSet(leds, currentLED); digitalWrite(latchPin, LOW); shiftOut(dataPin, clockPin, LSBFIRST, leds); digitalWrite(latchPin, HIGH); delay(250); )

First, let's define the following at the top of the sketch:

  • Pin locations: synchronizer, latch and data
  • A byte that will store the bits that tell the shift register which pin to use
  • A variable that will keep track of which LED we should turn on

In method setup we simply initialize the pin modes and LED variable.

In method loop(loop) we clear the bits in the variable leds at the beginning of each iteration, so all bits are set to 0 since we only want to turn on one LED at a time. After this we increment or restart the current variable currentLED to then turn on the correct LED again.

After these two operations, we move on to the more important part - bit shifting. First we start by calling the method bitSet. We pass to the method bitSet a byte that stores bits, and a variable currentLED.

This method allows us to set individual bits of a byte by specifying their position. For example, if we want to manually set a byte to 10010 , we could use the following calls since the bits we need to set to 1 are the second from the right (which is position 1 when we start at position 0) and the fifth from the right, which is at position 4:

BitSet(leds, 1); bitSet(leds, 4);

So every time we increment the current variable currentLED and pass it to the method bitSet, we set the bit to the left of the previous one to 1 each time and thus tell the shift register to activate the output to the left of the previous one.

After setting the bits, we write to the latch pin to indicate to the shift register that we are going to send data to it. Once we do this we call the method shiftOut, which is Arduino. This method is designed specifically to use shift registers and allows you to simply shift bits in a single call. To do this, we pass data and synchronization as the first two parameters, then we pass a constant LSBFIRST, which tells the method that the first bit should be the least significant bit, and then we go through the byte containing the bits we actually want to move into the shift register.

Once we've finished shifting the bits, we access the latch pin again (using HIGH this time) to indicate that we've sent all the data. Once the write operation is complete, the corresponding LED will light up and then delay for 250 milliseconds before repeating the process.

16 LEDs

Now let's move on to a more complex circuit using a 74hc595 Arduino for 16 LEDs.

Details

By and large, in this case we double the number of all components, except, of course, Arduino Uno:

  • Arduino UNO (x1)
  • 74HC595 shift register (x2)
  • LEDs (x16)
  • 220 ohm resistors (x16)
  • Wires/jumpers
  • Two development boards (one with 400 pins, the second with 830 pins)
  • Potentiometer to control brightness (optional)

Connection diagram

The connection diagram is already larger than with 8 LEDs and one 74HC595 shift register.

Assemble the circuit as in the figure above and connect the first shift register as follows:

  • GND (pin 8) to ground
  • Vcc (pin 16) - 5V
  • OE (pin 13) to ground (GND)
  • MR (pin 10) - 5 V
  • DS (pin 14) - pin 11 of Arduino
  • SH_CP (pin 11) to Arduino pin 12
  • ST_CP (pin 12) to pin 8 of Arduino

Connect the second shift register in the same way, but connect DS (pin 14) to the first pin 9 of the register. After this, connect pins 1, 2, 3, 4, 5, 6, 7 and 15 from both registers and LEDs. This connection makes all pins always active and addressable, however, when you turn on the Arduino, some of the LEDs may be turned on. The solution for this is to connect MR (pin 10) and OE (pin 13) to the Arduino directly, but this way you have to sacrifice 2 pins of the arduino.

To add more shift registers, connect them together as a second register. Always connect the MR and OE pins directly to the Arduino pin and the DS pin to the previous register. If you want to adjust the brightness of the LEDs, please connect a potentiometer as shown in the picture above to control the resistance for all the LEDs. However, this is optional and you can do without it.

Sketch for Arduino

Sketch variants are usually designed for a limited number of shift registers, because There is no universal function/method for this. The code below has been reworked so that you can use an unlimited number of shift registers:

int latchPin = 8; int clockPin = 12; int dataPin = 11; int numOfRegisters = 2; byte* registerState; long effectId = 0; long prevEffect = 0; long effectRepeat = 0; long effectSpeed ​​= 30; void setup() ( //Initialize array registerState = new byte; for (size_t i = 0; i< numOfRegisters; i++) { registerState[i] = 0; } //set pins to output so you can control the shift register pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); } void loop() { do{ effectId = random(6); } while (effectId == prevEffect); prevEffect = effectId; switch (effectId) { case 0: effectRepeat = random(1, 2); break; case 1: effectRepeat = random(1, 2); break; case 3: effectRepeat = random(1, 5); break; case 4: effectRepeat = random(1, 2); break; case 5: effectRepeat = random(1, 2); break; } for (int i = 0; i < effectRepeat; i++) { effectSpeed = random(10, 90); switch (effectId) { case 0: effectA(effectSpeed); break; case 1: effectB(effectSpeed); break; case 3: effectC(effectSpeed); break; case 4: effectD(effectSpeed); break; case 6: effectE(effectSpeed); break; } } } void effectA(int speed){ for (int i = 0; i < 16; i++){ for (int k = i; k < 16; k++){ regWrite(k, HIGH); delay(speed); regWrite(k, LOW); } regWrite(i, HIGH); } } void effectB(int speed){ for (int i = 15; i > < i; k++){ regWrite(k, HIGH); delay(speed); regWrite(k, LOW); } regWrite(i, HIGH); } } void effectC(int speed){ int prevI = 0; for (int i = 0; i < 16; i++){ regWrite(prevI, LOW); regWrite(i, HIGH); prevI = i; delay(speed); } for (int i = 15; i >= 0; i--)( regWrite(prevI, LOW); regWrite(i, HIGH); prevI = i; delay(speed); ) ) void effectD(int speed)( for (int i = 0; i< 8; i++){ for (int k = i; k < 8; k++) { regWrite(k, HIGH); regWrite(15 - k, HIGH); delay(speed); regWrite(k, LOW); regWrite(15 - k, LOW); } regWrite(i, HIGH); regWrite(15 - i, HIGH); } } void effectE(int speed){ for (int i = 7; i >= 0; i--)( for (int k = 0; k<= i; k++) { regWrite(k, HIGH); regWrite(15 - k, HIGH); delay(speed); regWrite(k, LOW); regWrite(15 - k, LOW); } regWrite(i, HIGH); regWrite(15 - i, HIGH); } } void regWrite(int pin, bool state){ //Determines register int reg = pin / 8; //Determines pin for actual register int actualPin = pin - (8 * reg); //Begin session digitalWrite(latchPin, LOW); for (int i = 0; i < numOfRegisters; i++){ //Get actual states for register byte* states = ®isterState[i]; //Update state if (i == reg){ bitWrite(*states, actualPin, state); } //Write shiftOut(dataPin, clockPin, MSBFIRST, *states); } //End session digitalWrite(latchPin, HIGH); }

The code adds several effects for these 16 LEDs. If you want to add more LEDs, connect more shift registers like above and change the value numOfRegisters in the code.

You can also use this code for more than just LEDs, if you just need more pins for your Arduino, use the regWrite(int pin, bool state) function to write the state of any pin. And there is no limit to how many shift registers you use, just change the value of numOfRegisters and the rest is already automated.

This review is dedicated, in fact, to novice Arduino users or those who want to get involved in this business. We will talk about increasing the number of microcontroller outputs using a shift register, and this does not require large expenses (compared to buying an Arduino Mega, for example). The simplest application is to blink the LEDs, so let's try this in practice.

When I started getting acquainted with microcontrollers (in fact, I still continue to “begin to get acquainted”), one of the first questions was: how can you control the same hundred, thousand LEDs with only a dozen outputs on the controller? Yes, you can use signal multiplexing, counter-connection and many other tricks, but still the maximum number of connected LEDs is limited, and it is necessary to look for another solution. And they suggested one of the options to me - “take one, two, ten shift register chips and have fun.” It was decided to immediately order them, and in the future even assemble an LED cube using them. I really had to abandon the latter; I found a simpler option, but this is the topic of another review.
I ordered 20 pieces of 74HC595N at once, fortunately they cost mere pennies. The letter N at the end of the marking means that the microcircuit is in a DIP-16 package, very convenient for experiments on a breadboard; you don’t even need to solder anything. It looks like this:




What is this microcircuit? It is an eight-bit serial-in, serial-out, or parallel-out shift register with a latch flip-flop and three-state output.
Simply put, using just 3 controller outputs you can control 8 shift register outputs. And if the microcircuits are connected in series one after another, then the number of controlled outputs can be increased to any reasonable limit (I haven’t found a maximum number, but hundreds seem to be combined without problems; if anyone knows what the maximum number of microcircuits included in a cascade depends on, it would be interesting find out in the comments).
Data is transmitted to the chip serially. Bits 0 and 1 are transferred to the register one after another, the bits are read when a clock pulse arrives. Transmitted 8 bits - received 8 output states at the register outputs. When the 74HC595 is cascaded (if 16, 24, etc. outputs are required), the data from the first register is transferred to the next.
The register output can not only be in a logical 0 or 1 state, but also be in a high impedance state when the output is disconnected from the circuit. Only all outputs can be transferred to this state at once. This is rarely used, but can be useful when switching control to another controller, for example.

Input/output pinout

Q0…Q7 – register outputs, can be in state 0, 1 or high impedance
GND – ground
Q7′ – output for serial connection of registers.
MR – register reset
SH_CP – clock input
ST_CP – data latching input
OE – input converting outputs from high impedance to operating state
DS – data input
VCC – power supply 2-6 volts

All that remains is to check the work; to do this, we will assemble a circuit that is popular among beginners. GND (pin 8) is connected to ground, Vcc (pin 16) to 5V power supply, OE (pin 13) to ground, MR (pin 10) to 5V power supply. The shift register is now powered up and all outputs are active. Now it’s time to connect the microcircuit to the Arduino: connect the DS data input (pin 14) to the 9th digital output of the Arduino, the SH_CP clock input (pin 11) to the 10th digital output, the ST_CP latch input (pin 12) to the 8th Arduino pin. It is recommended to place a 0.1 µF capacitor between ground and the latch to minimize noise.
It remains to connect the LEDs - through 150-300 Ohm resistors we connect them from the register outputs to ground. That's all. Here is a diagram I found for those who like visual materials (please note that the pinout of the real microcircuit and the schematic image on this diagram are different!)


I assembled the circuit on a breadboard, and it turned out like this.

assembled circuit








In Arduino, it is convenient to use the shiftOut() function, which outputs a byte of information to the input/output port sequentially (bit by bit). . We load the test code into Arduino and get a counter from 0 to 255 in binary form:
int latchPin = 8; //ST_CP int clockPin = 10; //SH_CP int dataPin = 9; //DS void setup() ( pinMode(latchPin, OUTPUT); pinMode(clockPin, OUTPUT); pinMode(dataPin, OUTPUT); ) void loop() ( for (int numberToDisplay = 0; numberToDisplay< 256; numberToDisplay++) { // установка синхронизации "защелки" на LOW digitalWrite(latchPin, LOW); // передаем последовательно на вход данных shiftOut(dataPin, clockPin, MSBFIRST, numberToDisplay); //"защелкиваем" регистр, устанавливаем значения на выходах digitalWrite(latchPin, HIGH); delay(500); } }
This is how it happened for me, everything works as expected:


Thus, with minimal use of controller pins, you can control a large number of LEDs (or something else). Everything would be fine, but I’ll also tell you about the shortcomings. As you can see, the current for each LED must be limited by a resistor, and when building large LED matrices this becomes quite labor-intensive. There is a more interesting solution for controlling LEDs - the DM13A driver, which is a shift register and also limits the current at each output. I’ll tell you about it next time, and as a bonus - my very first LED cube, 5x5x5, assembled on a simplified element base, without the use of 74HC595.

I'm planning to buy +37 Add to favorites I liked the review +35 +61