7.5 Shift registar
Svaki pin na pločici na kraju bude zauzet. Ovaj projekt pokazuje kako dobiti više izlaza nego što imaš pinova: 74HC595 shift registar pretvara tri pina u osam, a četiri od njih koristimo da sagradimo brojač koji broji od 0 do 15 u binarnom, kako to radi računalo.
U ovoj dokumentaciji naučit ćeš:
- Kako 74HC595 shift registar pretvara tri pina u osam izlaza
- Što znače pomicanje (shifting) i zaključavanje (latching), i zašto se sve LED-ice mijenjaju u istom trenutku
- Kako napisati vlastiti
shift_out()pomoću operatora pomaka bita i bitovnog I - Kako postaviti čip sa 16 pinova na breadboard a da ga ne okreneš naopako
- Kako pročitati binarni broj s reda LED-ica
Potreban hardver
- 1x Soldered NULA MINI pločica
- 1x Breadboard
- 1x 74HC595 shift registar
- 4x LED-ice
- 4x otpornika od 330 Ω
- 14x Jumper žice
- 1x USB-C kabel
Spajanje komponenti
Ovaj sklop ima više spojeva od svega drugoga u kitu, pa vrijedi ići polako. Svaka fotografija ispod prikazuje pločicu nakon što je unutra otišla još jedna stvar, dvadeset i jedan korak ukupno: četrnaest jumper žica, četiri otpornika, četiri LED-ice i čip.
1. Umetni pločicu i sagradi vodilicu mase
Utisni NULA MINI u jedan kraj breadboarda tako da zauzme redove 25 do 30, pa prije svega drugoga sagradi dijeljenu masu. To je prvi primjer kojem masa treba na obje strane pločice, a dvije plave − vodilice duž rubova nisu spojene međusobno unutar breadboarda.
Također su previše daleko jedna od druge da bi ih se doseglo jednom jumper žicom, pa se spoj pravi u skokovima, koristeći red 1 kao kamen za prelaz:
j30(GND) do donje plave−vodilice- donja plava
−vodilica doj1 e1dof1, prelazeći središnji kanala1do gornje plave−vodilice
Nakon tih četiriju jumper žica, obje vodilice i obje polovice reda 1 su jedna jedina masa.

2. Utisni 74HC595
Čip premošćuje središnji kanal i zauzima redove 14 do 21, s polumjesečastim zarezom okrenutim prema redu 14, dalje od pločice. Jedan red pinova sleti u stupac e, drugi u stupac f.
Sa zarezom kod reda 14, pinovi sjede ovako:
| Red | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 |
|---|---|---|---|---|---|---|---|---|
| a–e strana | 1 · Q1 | 2 · Q2 | 3 · Q3 | 4 · Q4 | 5 · Q5 | 6 · Q6 | 7 · Q7 | 8 · GND |
| f–j strana | 16 · VCC | 15 · Q0 | 14 · DS | 13 · OE | 12 · ST_CP | 11 · SH_CP | 10 · MR | 9 · Q7' |

3. Spoji čip na masu
Kratka plava jumper žica vodi pin 8 iz a21 do gornje plave − vodilice.

4. Daj čipu napajanje
Bijela žica nosi 3V3 iz j29 u j14, VCC pin čipa. Vodi u petlji ispod pločice umjesto da prelazi ravno preko, jer je to dužina žice koja je bila pri ruci. Ispod nije ništa spojeno.
VCC pina pločice. VCC je 5 V koji dolazi preko USB-a, a 74HC595 napojen na 5 V treba 3.5 V da prepozna visoko stanje, više nego što 3.3 V pinovi pločice mogu proizvesti. Radilo bi na stolu a padalo bi negdje drugdje.
5. Veži Master Reset na visoko
Crvena žica ide i20 u i14, pin 10 (MR) do pina 16 (VCC). MR briše cijeli registar kad god je nisko, pa se mora držati na visokom, a najbliže visoko je pin napajanja koji si upravo spojio.

6. Omogući izlaze
Druga kratka plava jumper žica vodi j17 (pin 13, OE) dolje do donje plave − vodilice. Output Enable odspaja svih osam izlaza kad god je visoko, pa se mora držati na niskom.

7. Spoji liniju podataka
Tamnozelena žica ide j25 (IO2) u j16, pin 14, DS. To je pin preko kojeg sami bitovi putuju, jedan za drugim.

8. Spoji zaključavanje
Tamnoplava žica ide j26 (IO3) u h18, pin 12, ST_CP. To je ona koja tjera svih osam izlaza da se promijene zajedno umjesto da trepere kroz svaki korak.

9. Spoji takt
Tirkizna žica ide j27 (IO4) u g19, pin 11, SH_CP. Kao i žica napajanja ide dugim putem ispod pločice.
Time je spajanje čipa dovršeno:
| Žica | Iz | U | Pin čipa | Zašto |
|---|---|---|---|---|
| Plava (kratka) | a21 | gornja − vodilica | 8 · GND | Masa čipa |
| Bijela | j29 (3V3) | j14 | 16 · VCC | Napajanje čipa |
| Crvena | i20 | i14 | 10 · MR na VCC | Master Reset držan visoko |
| Plava (kratka) | j17 | donja − vodilica | 13 · OE | Output Enable držan nisko |
| Tamnozelena | j25 (IO2) | j16 | 14 · DS | Podaci |
| Tamnoplava | j26 (IO3) | h18 | 12 · ST_CP | Zaključavanje |
| Tirkizna | j27 (IO4) | g19 | 11 · SH_CP | Takt |

a16 i c16 su ista električna točka, i tako otpornik u sljedećem koraku doseže pin čipa bez žice.10. Prvi otpornik od 330 Ω
Sada izlazi. Prvi lanac počinje na Q3, pin 3, na a–e strani u redu 16. Otpornik doseže pin čipa direktno, pa je taj lanac jedini kojem ne treba dovodna žica: jedna nožica u c16, druga u c11.

11. Prva LED-ica, bit 3
Duga nožica (anoda) ide u a11, red u kojem otpornik završava. Stupac a je krajnji, pa je nožica vodilici najbliže što može biti. Kratka nožica (katoda) savija se direktno u gornju plavu − vodilicu, čime se u ovom sklopu na svakoj LED-ici izbjegava jumper žica.

12. Dovodna žica za bit 2
Q2 je pin 2, na a15. Njegova LED-ica ide s druge strane kanala, pa narančasta žica izlaz prenosi preko u h11.

13. Drugi otpornik od 330 Ω
Iz i11 u i8, nastavljajući lanac na f–j strani.

14. Druga LED-ica, bit 2
Anoda u j8, katoda ovaj put savijena u donju plavu − vodilicu, jer ovaj lanac živi na f–j strani.

15. Dovodna žica za bit 1
Druga narančasta žica vodi Q1 iz a14 u d8, ostajući na a–e strani.

16. Treći otpornik od 330 Ω
Iz c8 u c5.

17. Treća LED-ica, bit 1
Anoda u a5, katoda u gornju plavu − vodilicu.

18. Dovodna žica za bit 0
Q0 je pin 15, na f–j strani u j15, jedini izlaz na toj strani čipa. Bijela žica vodi ga duž do h5.

19. Četvrti otpornik od 330 Ω
Iz i5 u i2, posljednji.

20. Četvrta LED-ica, bit 0
Anoda u j2, katoda u donju plavu − vodilicu. Sva četiri lanca sada su na mjestu:
| Bit | Broji | Pin čipa | Dovodna žica | 330 Ω | Anoda LED-ice | Katoda |
|---|---|---|---|---|---|---|
| 3 | 8 | 3 · Q3 (a16) | ne treba | c16 do c11 | a11 | gornja − vodilica |
| 2 | 4 | 2 · Q2 (a15) | a15 do h11 | i11 do i8 | j8 | donja − vodilica |
| 1 | 2 | 1 · Q1 (a14) | a14 do d8 | c8 do c5 | a5 | gornja − vodilica |
| 0 | 1 | 15 · Q0 (j15) | j15 do h5 | i5 do i2 | j2 | donja − vodilica |

21. Utisni USB-C kabel

Kako tri pina postaju osam
Shift registar je red od osam memorijskih ćelija s vratima na jednom kraju. DS su vrata. Svaki put kada pin takta ode gore, ono što sjedi na DS pomiče se u prvu ćeliju a svaka ćelija svoj sadržaj predaje sljedećoj. Osam impulsa takta, osam spremljenih bitova.
Kada bi se izlazi mijenjali dok se to događa, gledao bi kako bitovi jure preko LED-ica na putu do svojih mjesta. Ne mijenjaju se, zbog trećeg pina. ST_CP, zaključavanje, drži privatnu kopiju: izlazi nastavljaju prikazivati prethodnih osam bitova dok ne podigneš zaključavanje, a onda se svih osam promijeni u istom trenutku.
To je cijeli trik, i zato skripta svaki krug radi te iste tri stvari:
- Povuci zaključavanje nisko da se izlazi prestanu mijenjati
- Pozovi
shift_out()da pošalje osam bitova, taktirajući svaki od njih unutra - Povuci zaključavanje visoko da ih prikaže sve odjednom
Još dvama pinovima treba reći kako se ponašati, a to su oni koje ljudi zaboravljaju. MR (Master Reset) briše registar kad god je nisko, pa je vezan na visoko. OE (Output Enable) odspaja izlaze kad god je visoko, pa je vezan na nisko. Nijedan nije neobavezan: CMOS ulaz ostavljen da lebdi hvata kakav god električni šum je u blizini i radi kako mu se prohtije.
Vlastito pisanje shift_out()
Arduino ima gotov shiftOut(). MicroPython ne, pa skripta uključuje vlastiti, i vrijedi ga pročitati, jer je to najjasniji pogled na manipulaciju bitovima u cijelom kitu:
def shift_out(value):
for i in range(7, -1, -1):
bit = (value >> i) & 1
data_pin.value(bit)
clock_pin.value(1)
clock_pin.value(0)
Tri ideje rade sav posao:
range(7, -1, -1)broji prema dolje: 7, 6, 5, … 1, 0. Tri broja su početak, kraj i korak, a kraj nikada nije uključen, i zato završava na-1da bi dosegnuo 0. Brojanje prema dolje je ono što šalje najznačajniji bit prvi, a to je redoslijed koji 74HC595 očekuje.value >> ije pomak udesno: pomiče svaki bit brojaimjesta udesno, pa bit koji nas zanima završi na dnu.& 1je bitovni I s1, koji zadržava samo taj donji bit i odbacuje sve iznad njega.
Zajedno, (value >> i) & 1 čita bit broj i te vrijednosti, sam za sebe, kao 0 ili 1. Postavljanje data_pin na njega i zatim pulsiranje takta gore i dolje je jedan dostavljen bit.
Zašto samo četiri LED-ice? Čip ima osam izlaza, ali counter & 0x0F drži vrijednost unutar četiri bita, pa su Q4 do Q7 uvijek nula. 0x0F je 15, što je u binarnom 1111; spajanje bilo kojeg broja s 1111 na ovaj način zadržava njegova najniža četiri bita a ostalo odbacuje. Pin 9 (Q7') je rezervni bit koji ispada s dalekog kraja. To je ono što bi spojio na DS drugog čipa da nalančaš dva registra u šesnaest izlaza.
counter = (counter + 1) % 16 je isti trik obilaženja koji budilica koristi za sate i minute. % daje ostatak, pa 16 postaje 0 i brojač počinje ponovno.Kod
from machine import Pin
import time
# Ovo je varijabla kojoj predajemo broj pina na koji smo spojili pin podataka shift registra,
# na čipu označen s DS. To je pin preko kojeg sami bitovi putuju, jedan za drugim.
#
# Zapamti da svakoj od četiri LED-ice na izlazima shift registra treba vlastiti otpornik od 330 ohma u seriji s njom,
# točno kao da je spojena direktno na pločicu.
DATA_PIN = 2
# Ovo je varijabla kojoj predajemo broj pina na koji smo spojili pin zaključavanja shift registra.
# Na čipu 74HC595 taj pin je označen s ST_CP. Zaključavanje je ono što čipu govori "podaci koje sam ti poslao su potpuni,
# prikaži ih sada", i zato se LED-ice mijenjaju sve odjednom umjesto da trepere kroz svaki korak.
LATCH_PIN = 3
# Ovo je varijabla kojoj predajemo broj pina na koji smo spojili pin takta shift registra,
# na čipu označen s SH_CP. Takt je pin koji prebacujemo gore i dolje, i svaki put kada ode gore čip prima jedan
# bit više.
CLOCK_PIN = 4
# Ovdje stvaramo naša tri Pin objekta. Pin.OUT govori pločici da ovi pinovi treba pisati vrijednost umjesto da je
# čitaju, jer sva tri šalju informaciju čipu.
data_pin = Pin(DATA_PIN, Pin.OUT)
latch_pin = Pin(LATCH_PIN, Pin.OUT)
clock_pin = Pin(CLOCK_PIN, Pin.OUT)
# Počni sa sva tri pina u niskom stanju, da čip počne iz poznatog stanja.
data_pin.value(0)
latch_pin.value(0)
clock_pin.value(0)
# Ova varijabla drži vrijednost našeg brojača. U svakom prolazu kroz petlju raste za jedan, a nakon 15 počinje
# iznova od nule.
counter = 0
def shift_out(value):
# Ovo je funkcija koju smo napisali sami, jer ne postoji gotova funkcija za pomicanje bajta van.
# Šalje jedan bajt preko pina podataka, bit po bit, pulsirajući pin takta nakon svakog bita.
# range(7, -1, -1) broji prema dolje od 7 do 0, pa počinjemo s najznačajnijim bitom, dakle onim krajnje lijevim,
# a to je redoslijed koji 74HC595 očekuje.
# Pomicanje vrijednosti udesno za i mjesta i spajanje s 1 pomoću bitovnog I ("&") je način na koji izdvajamo
# pojedini bit koji želimo poslati.
for i in range(7, -1, -1):
bit = (value >> i) & 1
data_pin.value(bit)
clock_pin.value(1)
clock_pin.value(0)
while True:
# Ovdje naš brojač držimo unutar četiri bita. "&" je bitovni I, a 0x0F je heksadekadski način zapisa
# broja 15, koji je u binarnom 1111. Spajanje broja s 1111 na ovaj način zadržava samo njegova najniža četiri bita.
value = counter & 0x0F
# Povlačenje pina zaključavanja u nisko stanje govori čipu da ćemo poslati nove podatke i da svoje izlaze ne bi
# trebao još mijenjati. Bez toga bi LED-ice vidljivo treperile dok bitovi još dolaze.
latch_pin.value(0)
# Pošalji osam bitova naše vrijednosti čipu, koristeći našu funkciju iznad.
shift_out(value)
# Povlačenje pina zaključavanja natrag u visoko stanje govori čipu da su podaci potpuni. Tek se sada izlazi mijenjaju, i
# svih osam mijenja se zajedno.
latch_pin.value(1)
# Ispiši i vrijednost, da broj možeš usporediti s uzorkom upaljenih LED-ica.
print(value)
# Nabroji jedan gore, i počni iznova od nule kada prijeđemo 15, jer četiri LED-ice ne mogu prikazati nikakav broj veći od
# toga. Operator "%" daje ostatak dijeljenja, a to je kratak način obilaženja brojača.
counter = (counter + 1) % 16
# time.sleep() započinje pauzu u kodu, zadanu u sekundama. Pola sekunde je dovoljno sporo da brojanje pratiš
# očima. Slobodno eksperimentiraj s ovom vrijednošću.
time.sleep(0.5)
Što bi trebao vidjeti
Četiri LED-ice broje od 0 do 15 i počinju iznova. Svaki broj drži se pola sekunde, pa jedan cijeli krug traje osam sekundi.
Čitanje broja s LED-ica je pitanje sabiranja onih koje su upaljene. Duž pločice, dalje od čipa, četiri vrijede 8, 4, 2 i 1. Tako je jedna LED-ica sama na dalekom kraju 1; dvije najbliže čipu zajedno su 8 + 4 = 12; kad su sve četiri upaljene to je 15, najveći broj koji četiri LED-ice mogu prikazati, a sljedeći korak nakon toga je natrag na 0.
Za razliku od Arduino verzije ovog projekta, skripta također ispisuje svaki broj kako ga prikazuje, pa možeš provjeriti LED-ice u odnosu na brojanje:
0
1
2
3
4
5
Gledaj LED-icu 1 neko vrijeme i vidjet ćeš uzorak koji binarno brojanje čini funkcionalnim: mijenja se svaki pojedini korak. 2 se mijenja upola rjeđe, 4 ponovno upola rjeđe, a 8 samo dvaput u cijelom krugu. Svaka LED-ica preokreće se točno upola brzine od one prije nje. Ispisana kolona pokazuje istu stvar u brojevima.
Ako se ništa uopće ne pali, iskopčaj USB kabel i provjeri prvo zarez na čipu. 74HC595 postavljen naopako daleko je najčešći uzrok, i vrijedi to brzo uloviti: okretanje čipa s kraja na kraj zamjenjuje redove 14 i 21 preko kanala, pa žica 3V3 sleti na pin 8 (GND) a jumper žica mase sleti na pin 16 (VCC). Čip tada ima napajanje obrnuto, a ne odsutno, što propusno polarizira diodu unutar njega koja je normalno nepropusno polarizirana. Neće raditi, može se osjetno zagrijati, i može se trajno oštetiti, pa ga ne ostavljaj napojenog dok tražiš u čemu je problem. Ako su LED-ice upaljene ali se nikada ne mijenjaju, žica takta ili zaključavanja je u pogrešnom redu; konzola koja broji gore dok LED-ice mirno stoje dokazuje da je greška u spajanju a ne u kodu. Ako se jedna LED-ica nikada ne upali, njezin vlastiti lanac nije u redu, a druge tri dokazuju da je čip u redu.
Cijeli primjer
Pogledaj cijeli kod primjera na linku ispod:
7.5_Shift_Register.py
Projekt koji pokazuje kako pomoću 74HC595 shift registra upravljati četirima LED-icama kao 4-bitnim binarnim brojačem koristeći samo tri pina NULA MINI.