Parçalar · 13 dk okuma

74HC595 Arduino Kullanımı: Shift Register ile 3 Pinden 8+ LED

74HC595 Arduino kullanımı: pin dizilimi, shiftOut() ve bit sırası, entegre zincirleme, yürüyen LED ve 7 segment, SPI ile hızlı sürme, ESP32 ve Pico kodu.

74HC595, Arduino'nun yalnızca 3 dijital pinini kullanarak 8 ayrı çıkışı kontrol etmeni sağlayan, 16 bacaklı ucuz bir kaydırmalı yazmaç (shift register) entegresidir. Arduino Uno'da 20 kullanılabilir pin vardır; 16 LED'li bir karaşimşek, iki haneli bir skor tabelası ya da 8 kanallı bir röle kartı yapmaya kalktığında bu pinler hızla tükenir. 74HC595 bu sorunu veriyi tek bir hattan bit bit göndererek çözer: entegre gelen bitleri sırayla içine alır, sen hazır olduğunu söylediğinde sekiz çıkışına aynı anda aktarır. Birden fazla entegreyi zincirlediğinde aynı 3 pinle 16, 24, hatta 80 çıkışı yönetebilirsin.

Bu yazıda 74HC595'in pin dizilimini (DS, SH_CP, ST_CP, OE, MR ve Q7'), seri veriyi paralele çeviren iç yapısını, Arduino'nun shiftOut() fonksiyonunu ve MSBFIRST ile LSBFIRST bit sırası farkını öğreneceksin. Ardından ikilik sayaç, yürüyen LED, 16 LED'li zincir ve 7 segment display örneklerini kuracak, aynı devreyi donanım SPI'siyle onlarca kat hızlı süreceksin. Son bölümlerde ESP32 ve Raspberry Pi Pico (MicroPython) kodlarını, entegrenin akım sınırlarını ve en sık yapılan latch hatalarının çözümlerini bulacaksın.

74HC595 nedir, nasıl çalışır?

Entegrenin içinde art arda bağlanmış iki adet 8 bitlik yazmaç vardır. Birincisi kaydırma yazmacıdır: SH_CP (saat) pinine her yükselen kenar geldiğinde DS pinindeki 0 ya da 1 değeri ilk hücreye girer, içerideki bitler ise birer basamak ileri kayar. Sekiz saat darbesinden sonra gönderdiğin sekiz bitin tamamı içeridedir. İkincisi depolama yazmacıdır (latch): ST_CP pinine bir yükselen kenar geldiğinde kaydırma yazmacındaki sekiz bit tek seferde bu yazmaca kopyalanır ve Q0–Q7 çıkışlarında görünür. Bu iki aşamalı yapı sayesinde bitler kayarken LED'ler titremez; çıkışlar yalnızca sen latch pinini tetiklediğinde değişir.

Bunu bir tren istasyonuna benzetebilirsin: vagonlar (bitler) tek bir raydan sırayla perona girer, ama kapılar ancak tren tamamen durduğunda açılır ve yolcuların hepsi aynı anda iner. Kapıları açma işini latch pini yapar. Veri entegreye seri girip paralel çıktığı için 74HC595'e SIPO (serial-in, parallel-out) yazmaç da denir. Tersini yapan, yani 8 butonu tek hattan okumanı sağlayan kardeşi ise 74HC165'tir (PISO). Her iki entegre de 74 serisi lojik ailesindendir; bu ailedeki kapıları ve entegre numaralarını Mantık kapıları aracında görebilirsin.

ÖzellikDeğer
Tür8 bit seri giriş, paralel çıkış (SIPO) kaydırmalı yazmaç + 8 bit depolama yazmacı
Besleme gerilimi (VCC)2–6 V (74HCT595: 4,5–5,5 V)
KılıfDIP-16 (breadboard'a uyar), SOIC-16, TSSOP-16
Çıkış akımıÇıkış başına yaklaşık 6 mA (4,5 V'ta veri sayfası test değeri)
Mutlak sınırlarÇıkış başına ±35 mA; VCC ya da GND pininden toplam ±70 mA
En yüksek saat frekansı4,5 V beslemede 25 MHz'e kadar garanti, 2 V'ta 5 MHz
HIGH giriş eşiği (VIH)4,5 V beslemede en az 3,15 V (yaklaşık 0,7 × VCC)
Çıkış türüÜç durumlu (3-state); OE HIGH olunca Q0–Q7 boşta kalır

74HC595 pin dizilimi (pinout)

Entegrenin üzerindeki yarım ay şeklindeki çentik ya da küçük nokta 1. pini gösterir. Çentik yukarıdayken entegreye üstten baktığında sol sırada yukarıdan aşağıya 1–8, sağ sırada aşağıdan yukarıya 9–16 numaralı pinler bulunur. Üreticiler pinlere farklı adlar verir: NXP ve Arduino kaynaklarının çoğu DS, SH_CP ve ST_CP adlarını, Texas Instruments ise SER, SRCLK ve RCLK adlarını kullanır. Aşağıdaki tabloda ikisini de bulabilirsin. OE ve MR aktif LOW girişlerdir; yani görevlerini LOW olduklarında yaparlar ve veri sayfalarında adlarının üzerinde bir çizgiyle gösterilirler.

PinNXP adıTI adıGöreviNereye bağlanır?
15, 1–7Q0, Q1–Q7QA, QB–QHParalel çıkışlar (Q0 15. pinde, Q1–Q7 1–7. pinlerde)Dirençler üzerinden LED'lere
8GNDGNDToprakGND
9Q7'QH'Seri çıkış: kaydırma yazmacının son bitiSonraki 74HC595'in DS pinine (zincir)
10MRSRCLRKaydırma yazmacını sıfırlar (aktif LOW)VCC
11SH_CPSRCLKKaydırma saati; yükselen kenarda 1 bit içeri alınırArduino D13 (SCK)
12ST_CPRCLKLatch; yükselen kenarda veriyi çıkışlara aktarırArduino D10
13OEOEÇıkışları etkinleştirir (aktif LOW)GND (ya da parlaklık için bir PWM pini)
14DSSERSeri veri girişiArduino D11 (MOSI)
16VCCVCCBesleme5V (ESP32 ve Pico'da 3,3 V)
Q0 çıkışı diğer çıkışların yanında değil, karşı sıradaki 15 numaralı pindedir; Q1–Q7 ise 1–7 numaralı pinlerdedir. Yeni başlayanların en sık yaptığı hata, LED'leri 1. pinden başlayarak sırayla dizip Q0'ı unutmak ya da 15. pindeki LED'i en sona koymaktır. Sonuçta yürüyen ışık bir yerde sıçrar ve kodda hata aranır, oysa sorun kablodadır.

Arduino Uno, ESP32 ve Pico bağlantısı

Bu yazıdaki bütün Arduino örnekleri aynı devreyi kullanır. Veri ve saat hatları için donanım SPI pinlerini (D11 ve D13) baştan seçmek, kodu daha sonra SPI'ye geçirirken tek bir kabloyu bile değiştirmemeni sağlar. Her LED'in uzun bacağı (anot) bir çıkışa, kısa bacağı (katot) bir direnç üzerinden GND'ye bağlanır. Entegrenin VCC ve GND pinleri arasına, entegreye olabildiğince yakın bir 100 nF seramik kondansatör koymayı unutma; LED'ler aynı anda yanıp sönerken oluşan kısa gerilim düşüşlerini bastırır ve rastgele hataları önler. Kartının SPI pinlerini Pinout aracından da kontrol edebilirsin.

74HC595 piniArduino UnoESP32Raspberry Pi Pico
DS (14)D11GPIO 23GP19
SH_CP (11)D13GPIO 18GP18
ST_CP (12)D10GPIO 5GP17
OE (13)GNDGNDGND
MR (10)5V3V33V3(OUT)
VCC (16)5V3V33V3(OUT)
GND (8)GNDGNDGND
Q0–Q7LED + 470 ΩLED + 220 ΩLED + 220 Ω
74HC595 güçlü bir sürücü değildir. Veri sayfasına göre tek bir çıkıştan en fazla 35 mA, entegrenin VCC ya da GND pininden toplamda en fazla 70 mA geçebilir. Derslerde sık görülen 220 Ω'luk dirençlerle 5 V'ta her LED 10–13 mA çeker; sekiz LED birden yandığında toplam 80–100 mA olur, entegre ısınır, çıkış gerilimi düşer ve entegre zamanla bozulabilir. 5 V'ta 470 Ω kullanırsan LED başına yaklaşık 6 mA, sekizi birden yandığında 50 mA civarında kalırsın; günümüzün LED'leri bu akımda da rahatça görünür. Değeri kendin hesaplamak için LED direnci aracını kullanabilirsin.

shiftOut() fonksiyonu ve bit sırası (MSBFIRST / LSBFIRST)

Arduino'da 74HC595'e veri göndermenin en kolay yolu yerleşik shiftOut(dataPin, clockPin, bitOrder, value) fonksiyonudur. Fonksiyon value baytının sekiz bitini sırayla veri pinine yazar ve her bitten sonra saat pinini önce HIGH, sonra LOW yapar; 74HC595 de biti tam bu yükselen kenarda içeri alır. shiftOut() latch pinine dokunmaz. Bu yüzden göndermeden önce ST_CP'yi LOW yapman, gönderdikten sonra HIGH yapman gerekir. Fonksiyon yükselen kenarla çalıştığı için saat pininin çağrıdan önce LOW durumda olması da önemlidir; aksi halde ilk bit kaçabilir.

bitOrder parametresi bitlerin hangi uçtan başlayarak gönderileceğini belirler. İlk gönderilen bit sekiz kaydırmadan sonra en uca, yani Q7'ye ulaşır; son gönderilen bit ise Q0'da kalır. MSBFIRST ile önce en anlamlı bit (bit 7) gittiği için baytın her biti aynı numaralı çıkışa düşer: bit 0 Q0'a, bit 7 Q7'ye. LSBFIRST ile sıra tam tersine döner ve bit 0 Q7'de, bit 7 Q0'da görünür. Bu yazıdaki örneklerin hepsi MSBFIRST kullanır; böylece koddaki sayının bitleri ile LED numaraları birebir örtüşür. İkilik sayıların ve 0b ile başlayan yazımın mantığını tazelemek istersen sayı sistemleri ve bit işlemleri yazısına göz at.

Gönderilen değerMSBFIRST ile yanan çıkışlarLSBFIRST ile yanan çıkışlar
0b00000001 (1)Q0Q7
0b10000000 (128)Q7Q0
0b00001111 (15)Q0, Q1, Q2, Q3Q4, Q5, Q6, Q7
0b10100101 (165)Q0, Q2, Q5, Q7Q0, Q2, Q5, Q7 (desen simetrik)

Adım adım ilk devre: 8 LED ile ikilik sayaç

  1. 74HC595'i breadboard'un ortasındaki boşluğun üzerine, iki sıra bacak ayrı tarafa düşecek şekilde yerleştir. Breadboard'un iç bağlantılarını bilmiyorsan önce Breadboard Nedir? yazısına göz at.
  2. 16 numaralı VCC ve 10 numaralı MR pinlerini 5V'a, 8 numaralı GND ve 13 numaralı OE pinlerini GND'ye bağla. VCC ile GND arasına 100 nF kondansatörü tak.
  3. DS (14) pinini D11'e, SH_CP (11) pinini D13'e, ST_CP (12) pinini D10'a bağla.
  4. Sekiz LED'in uzun bacaklarını Q0–Q7 çıkışlarına, kısa bacaklarını 470 Ω dirençlerle GND'ye bağla. Q0'ın 15 numaralı pin olduğunu unutma.
  5. Aşağıdaki kodu yükle. LED'ler 0'dan 255'e kadar ikilik sayı sisteminde saymalı; Q0'daki LED en hızlı, Q7'deki en yavaş yanıp sönmelidir.
Arduino (C++)
1// 74HC595 ile 8 LED'de ikilik sayaç / Binary counter on 8 LEDs with a 74HC595
2const int DATA_PIN = 11;   // DS (14)
3const int CLOCK_PIN = 13;  // SH_CP (11)
4const int LATCH_PIN = 10;  // ST_CP (12)
5
6void write595(byte value) {
7  digitalWrite(LATCH_PIN, LOW);                    // latch'i indir / pull the latch low
8  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, value);  // 8 biti kaydır / shift the 8 bits in
9  digitalWrite(LATCH_PIN, HIGH);                   // yükselen kenar: çıkışlara aktar / rising edge: copy to the outputs
10}
11
12void setup() {
13  pinMode(DATA_PIN, OUTPUT);
14  pinMode(CLOCK_PIN, OUTPUT);
15  pinMode(LATCH_PIN, OUTPUT);
16  digitalWrite(CLOCK_PIN, LOW);                    // saat LOW başlamalı / the clock must start low
17  write595(0);                                     // açılışta hepsi sönük / all off at startup
18}
19
20void loop() {
21  for (int n = 0; n < 256; n++) {
22    write595(n);                                   // n'in bitleri Q0–Q7'de / the bits of n on Q0–Q7
23    delay(200);
24  }
25}

Kodun kalbi write595() fonksiyonudur: latch'i LOW yapar, shiftOut() ile sekiz biti gönderir ve latch'i HIGH yaparak hepsini aynı anda çıkışlara aktarır. LED'lerin neden titremediğinin cevabı da burada: kaydırma sürerken çıkışlar eski değeri korur. n sayısı 5 olduğunda (0b00000101) Q0 ve Q2'deki LED'ler, 200 olduğunda (0b11001000) Q3, Q6 ve Q7'deki LED'ler yanar. Uno'da D13'e bağlı dahili L LED'inin saat sinyaliyle hafifçe kıpırdadığını görebilirsin; bu normaldir ve devreyi etkilemez.

Yürüyen LED ve karaşimşek efekti

Arduino projelerinde kullanılan LED'ler
74HC595'in her çıkışına bir LED ve o LED'in kendi direnci bağlanır: uzun bacak (anot) çıkışa, kısa bacak direnç üzerinden GND'ye.

Yürüyen ışık için her adımda yalnızca tek bir biti 1 yapman yeterlidir. Arduino'nun bit(i) makrosu, yalnızca i numaralı biti 1 olan sayıyı üretir: bit(0) 1'e, bit(3) 8'e, bit(7) 128'e eşittir. Aşağıdaki kod üç efekti art arda oynatır: Q0'dan Q7'ye yürüyen tek LED, git-gel yapan karaşimşek ve gittikçe dolan bir çubuk. Doğrudan pinlere bağlanan klasik sürümüyle karşılaştırmak istersen Arduino Karaşimşek ve Yürüyen LED yazısına bakabilirsin; orada her LED için ayrı bir pin harcanır, burada ise toplam 3 pin yeter.

Arduino (C++)
1// Yürüyen LED, karaşimşek ve dolan çubuk / Running light, Knight Rider and filling bar
2const int DATA_PIN = 11;   // DS
3const int CLOCK_PIN = 13;  // SH_CP
4const int LATCH_PIN = 10;  // ST_CP
5const int STEP_MS = 80;    // adım süresi (ms) / step time (ms)
6
7void write595(byte value) {
8  digitalWrite(LATCH_PIN, LOW);
9  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, value);
10  digitalWrite(LATCH_PIN, HIGH);
11}
12
13void setup() {
14  pinMode(DATA_PIN, OUTPUT);
15  pinMode(CLOCK_PIN, OUTPUT);
16  pinMode(LATCH_PIN, OUTPUT);
17  digitalWrite(CLOCK_PIN, LOW);
18  write595(0);
19}
20
21void loop() {
22  // 1) Yürüyen LED: Q0'dan Q7'ye / running light: Q0 to Q7
23  for (int i = 0; i < 8; i++) {
24    write595(bit(i));               // yalnızca i. bit 1 / only bit i is 1
25    delay(STEP_MS);
26  }
27
28  // 2) Karaşimşek: git-gel, 3 tur / Knight Rider: back and forth, 3 rounds
29  for (int r = 0; r < 3; r++) {
30    for (int i = 0; i < 7; i++) { write595(bit(i)); delay(STEP_MS); }
31    for (int i = 7; i > 0; i--) { write595(bit(i)); delay(STEP_MS); }
32  }
33
34  // 3) Dolan çubuk / filling bar
35  byte bar = 0;
36  for (int i = 0; i < 8; i++) {
37    bar |= bit(i);                  // bir LED daha ekle / add one more LED
38    write595(bar);
39    delay(STEP_MS * 2);
40  }
41  write595(0);
42  delay(300);
43}

Karaşimşek bölümünde ileri döngü 0–6, geri döngü 7–1 aralığında döner; böylece uçtaki LED'ler iki kez üst üste yanmaz ve hareket akıcı görünür. Dolan çubukta |= (bit düzeyinde VEYA) işlemi önceki LED'leri yanık bırakırken bir yenisini ekler; bu, bir potansiyometrenin ya da sensörün değerini gösteren LED bar göstergenin temelidir. Kodda delay() kullanıldığı için efekt çalışırken Arduino başka iş yapamaz. Efekt sürerken buton okumak ya da hızı canlı değiştirmek istersen zamanlamayı millis() ile kur; yöntemi millis() ve delay() yazısında bulabilirsin.

Birden fazla 74HC595'i zincirleme (Q7')

Entegrenin 9 numaralı Q7' (QH') pini, kaydırma yazmacından taşan biti dışarı verir. Bu pini ikinci bir 74HC595'in DS girişine bağladığında iki entegre tek bir 16 bitlik yazmaç gibi davranır. SH_CP ve ST_CP hatları bütün entegrelerde ortaktır; yani zincirde üç entegre de olsa on entegre de olsa Arduino'dan yine yalnızca 3 kablo çıkar. Her yeni bayt gönderildiğinde önceki bayt bir sonraki entegreye itilir. Bu yüzden ilk gönderdiğin bayt zincirin en sonundaki entegreye, son gönderdiğin bayt ise Arduino'ya bağlı ilk entegreye yerleşir. Latch tetiklendiğinde bütün entegrelerin çıkışları aynı anda güncellenir.

Bağlantı1. entegre2. entegre
DS (14)Arduino D111. entegrenin Q7' (9) pini
SH_CP (11)Arduino D13Arduino D13 (ortak)
ST_CP (12)Arduino D10Arduino D10 (ortak)
Q7' (9)2. entegrenin DS pinineBoş ya da 3. entegrenin DS pinine
OE (13) / MR (10)GND / 5VGND / 5V
ÇıkışlarLED 0–7LED 8–15
Arduino (C++)
1// İki zincirli 74HC595 ile 16 LED / 16 LEDs on two daisy-chained 74HC595s
2const int DATA_PIN = 11;   // 1. entegrenin DS'si / DS of chip 1
3const int CLOCK_PIN = 13;  // iki entegrede ortak SH_CP / shared SH_CP
4const int LATCH_PIN = 10;  // iki entegrede ortak ST_CP / shared ST_CP
5
6void write16(uint16_t value) {
7  digitalWrite(LATCH_PIN, LOW);
8  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, highByte(value));  // önce uzaktaki entegre (LED 8–15) / far chip first (LEDs 8–15)
9  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, lowByte(value));   // sonra yakındaki (LED 0–7) / then the near chip (LEDs 0–7)
10  digitalWrite(LATCH_PIN, HIGH);                             // 16 çıkış aynı anda değişir / all 16 outputs change at once
11}
12
13void setup() {
14  pinMode(DATA_PIN, OUTPUT);
15  pinMode(CLOCK_PIN, OUTPUT);
16  pinMode(LATCH_PIN, OUTPUT);
17  digitalWrite(CLOCK_PIN, LOW);
18  write16(0);
19}
20
21void loop() {
22  for (int i = 0; i < 16; i++) {    // ileri / forward
23    write16(bit(i));
24    delay(50);
25  }
26  for (int i = 14; i > 0; i--) {    // geri / backward
27    write16(bit(i));
28    delay(50);
29  }
30}

highByte() ve lowByte() 16 bitlik sayıyı iki bayta böler. Yüksek bayt önce gönderildiği için zincirin sonundaki entegreye gider ve LED 8–15'i kontrol eder; düşük bayt ise ilk entegrede kalır. Üçüncü bir entegre eklemek istersen bir bayt daha göndermen ve yine en uzaktaki entegreden başlaman yeterlidir; çok sayıda entegrede baytları bir dizide tutup döngüyle göndermek daha düzenlidir. Zincirin teorik bir sınırı yoktur, ama her entegre güncelleme süresini uzatır ve ortak saat hattının yükünü artırır. Uzun zincirlerde her entegreye kendi 100 nF kondansatörünü koy, saat ve latch kablolarını kısa tut ve hat çok uzarsa saati 74HC244 gibi bir tampon entegreyle güçlendir.

74HC595 ile 7 segment display sürmek

Tek haneli 7 segment display
Tek haneli 7 segment display: a–g segmentleri ve nokta (dp) ile tam 8 LED vardır; bu da bir 74HC595'in 8 çıkışına birebir uyar.

Tek haneli bir 7 segment display'de a'dan g'ye yedi segment ve bir nokta (dp) olmak üzere tam sekiz LED bulunur; yani bir 74HC595'in sekiz çıkışı bir haneye birebir yeter. Q0'ı a segmentine, Q1'i b'ye bağlayıp bu şekilde devam edersen Q6 g'ye, Q7 de dp'ye gelir; böylece baytın bit 0'ı a, bit 6'sı g segmentini temsil eder. Aşağıdaki tablo yaygın 10 pinli, ortak katotlu display için bağlantıyı gösterir. Ortak pinler (3 ve 8) GND'ye gider ve her segmente ayrı bir 470 Ω direnç takılır. Segment harflerinin düzenini ve ortak anot ile ortak katot farkını 7 Segment Display Kullanımı yazısında ayrıntılı bulabilirsin.

74HC595 çıkışıSegmentDisplay pini
Q0 (15)a7
Q1 (1)b6
Q2 (2)c4
Q3 (3)d2
Q4 (4)e1
Q5 (5)f9
Q6 (6)g10
Q7 (7)dp5
Arduino (C++)
1// 74HC595 ile tek haneli 7 segment: 0–9 sayacı / Single-digit 7-segment 0–9 counter with a 74HC595
2const int DATA_PIN = 11;
3const int CLOCK_PIN = 13;
4const int LATCH_PIN = 10;
5const bool COMMON_ANODE = false;    // ortak anotsa true / true for common anode
6
7// bit 0 = a ... bit 6 = g, bit 7 = dp (1 = yanar / 1 = on)
8const byte DIGITS[10] = {
9  0b00111111, // 0
10  0b00000110, // 1
11  0b01011011, // 2
12  0b01001111, // 3
13  0b01100110, // 4
14  0b01101101, // 5
15  0b01111101, // 6
16  0b00000111, // 7
17  0b01111111, // 8
18  0b01101111  // 9
19};
20
21void write595(byte value) {
22  if (COMMON_ANODE) value = ~value;   // ortak anotta LOW yakar / LOW lights a common-anode segment
23  digitalWrite(LATCH_PIN, LOW);
24  shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, value);
25  digitalWrite(LATCH_PIN, HIGH);
26}
27
28void setup() {
29  pinMode(DATA_PIN, OUTPUT);
30  pinMode(CLOCK_PIN, OUTPUT);
31  pinMode(LATCH_PIN, OUTPUT);
32  digitalWrite(CLOCK_PIN, LOW);
33}
34
35void loop() {
36  for (int n = 0; n < 10; n++) {
37    byte pattern = DIGITS[n];
38    if (n % 2 == 1) pattern |= 0b10000000;   // tek sayılarda nokta yanar / dot on for odd numbers
39    write595(pattern);
40    delay(800);
41  }
42}

Ortak anotlu bir display'de ortak pinler 5V'a bağlanır ve segment, çıkış LOW olduğunda yanar. Koddaki COMMON_ANODE değerini true yaptığında ~ işlemi bütün bitleri ters çevirir ve aynı tablo çalışmaya devam eder. İki haneli bir sayaç için ikinci bir 74HC595'i zincire ekleyip önce uzaktaki hanenin, sonra Arduino'ya yakın hanenin desenini göndermen yeterlidir. Bu yöntemde her hanenin kendi entegresi olduğu için çoklama (multiplexing) gerekmez, display hiç titremez ve loop() içinde delay() kullanman sorun olmaz. Dört ya da daha fazla hane için ise iki 74HC595 ile çoklama yapabilir ya da tarama işini kendi başına yapan TM1637 veya MAX7219 sürücülerine geçebilirsin.

SPI ile hızlı sürme

shiftOut() her biti digitalWrite() ile tek tek yazdığı için yavaştır: Arduino Uno'da bir baytı göndermek yaklaşık 100 µs sürer. Birkaç LED için bu fark edilmez, ama 10 entegrelik bir zinciri saniyede binlerce kez güncellemek, LED'lerin parlaklığını yazılımla ayarlamak ya da çoklamalı bir LED küpü taramak istediğinde yetersiz kalır. İyi haber şu ki 74HC595'in protokolü aslında SPI'nin ta kendisidir: DS MOSI'ye, SH_CP SCK'ye, ST_CP ise seçme (CS) pinine karşılık gelir. Uno'nun donanım SPI birimi 8 MHz'de bir baytı yaklaşık 1 µs'de gönderir; fonksiyon çağrılarının yükü eklense bile shiftOut()'tan onlarca kat hızlıdır. SPI'nin çalışma mantığını SPI nedir? yazısında bulabilirsin.

Arduino (C++)
1// 74HC595'i donanım SPI ile sürmek (Arduino Uno) / Driving a 74HC595 over hardware SPI (Arduino Uno)
2#include <SPI.h>
3
4const int LATCH_PIN = 10;   // ST_CP; D11 (MOSI) = DS, D13 (SCK) = SH_CP
5
6void write595(byte value) {
7  SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));  // 8 MHz, mod 0 / 8 MHz, mode 0
8  digitalWrite(LATCH_PIN, LOW);
9  SPI.transfer(value);              // 8 bit yaklaşık 1 µs'de / 8 bits in about 1 µs
10  digitalWrite(LATCH_PIN, HIGH);    // çıkışlara aktar / copy to the outputs
11  SPI.endTransaction();
12}
13
14void setup() {
15  pinMode(LATCH_PIN, OUTPUT);
16  SPI.begin();                      // D11 ve D13 SPI'ye geçer / D11 and D13 switch to SPI
17  write595(0);
18}
19
20void loop() {
21  static byte pattern = 0b00000001;
22  write595(pattern);
23  pattern = (pattern << 1) | (pattern >> 7);   // sola döndür / rotate left
24  delay(100);
25}

SPI_MODE0'da veri saatin yükselen kenarında örneklenir; bu, 74HC595'in çalışma şekliyle birebir aynıdır. MSBFIRST yine bit 7'yi Q7'ye gönderir, bu yüzden önceki örneklerdeki desenler değişmeden çalışır. Uno'da donanım SPI'sinin ana (master) modda kalması için D10'un çıkış olması gerekir; SPI.begin() bunu zaten ayarlar ve latch için en uygun pinin D10 olmasının nedeni de budur. Zincirde birden fazla entegre varsa latch LOW ve HIGH arasında SPI.transfer() fonksiyonunu entegre sayısı kadar çağırman yeterlidir. MISO (D12) bu devrede kullanılmaz ve başka bir SPI cihazı için boş kalır.

OE ile parlaklık ayarı ve MR ile temizleme

OE (output enable) pini, bütün çıkışları tek seferde açıp kapatan bir anahtardır. Bu pini GND yerine Uno'nun PWM pinlerinden birine, örneğin D9'a bağlarsan bütün LED'lerin parlaklığını PWM ile birlikte ayarlayabilirsin. OE aktif LOW olduğu için mantık terstir: analogWrite(9, 0) en parlak, analogWrite(9, 255) tamamen sönük demektir. Bu yüzden kodda analogWrite(9, 255 - parlaklik) yazmak işini kolaylaştırır. Bu yöntem bütün LED'leri aynı oranda etkiler; LED'lerin her birinin parlaklığını ayrı ayrı değiştirmek istersen bunu yazılımla, hızlı SPI güncellemeleriyle yapman ya da WS2812B gibi adreslenebilir LED'lere geçmen gerekir.

MR (master reset) pini LOW yapıldığında kaydırma yazmacındaki bütün bitler sıfırlanır, ama çıkışlar hemen sönmez; depolama yazmacı eski değeri korur. Çıkışların da sönmesi için MR LOW iken latch pinine bir yükselen kenar göndermen gerekir. Pratikte MR'ı doğrudan VCC'ye bağlayıp temizlemeyi write595(0) ile yazılımdan yapmak hem bir pin hem bir kablo kazandırır. Bir de açılış meselesi var: güç verildiğinde depolama yazmacı rastgele bir değerle başlar ve LED'ler bir anlığına karışık yanabilir. Bu bir röle kartında tehlikeli olabilir; önlemek için OE'yi 10 kΩ ile VCC'ye çek, setup() içinde önce write595(0) çağır, ardından OE pinini LOW yap.

ESP32 ile 74HC595: 3,3 V ve SPI

ESP32'nin pinleri 3,3 V verir. 74HC595'i 5 V ile beslersen girişin HIGH sayılması için yaklaşık 0,7 × VCC, yani 3,5 V gerekir; 3,3 V bu sınırın altında kalır ve çalışma kararsızlaşır. En temiz çözüm entegreyi de ESP32'nin 3V3 pininden beslemektir, çünkü 74HC595 2 V'tan itibaren çalışır. Entegreyi mutlaka 5 V ile beslemen gerekiyorsa girişleri 2 V'u bile HIGH sayan 74HCT595'i kullan ya da araya bir lojik seviye dönüştürücü ekle. 3,3 V'ta kırmızı, sarı ve yeşil LED'ler için 220 Ω uygundur; ileri gerilimi 3 V civarında olan mavi ve beyaz LED'ler ise 3,3 V'ta çok sönük yanar.

Aşağıdaki örnek, ESP32'nin VSPI pinleriyle (SCK GPIO 18, MOSI GPIO 23) iki zincirli 74HC595'e bağlı 16 LED'de karaşimşek efekti oynatır; latch için GPIO 5 kullanılır. SPI hızı 4 MHz'e ayarlandı, çünkü 74HC595'in hız sınırı besleme gerilimiyle birlikte düşer ve 3,3 V'ta 4 MHz geniş bir güvenlik payı bırakır. ESP32'de shiftOut() da çalışır ve 240 MHz'lik işlemci sayesinde Uno'dakinden çok daha hızlıdır; yine de SPI kullanmak işlemciyi Wi-Fi gibi işler için serbest bırakır. Kart ve güvenli pin seçimi için ESP32 Nedir? yazısına bakabilirsin.

Arduino (C++)
1// ESP32 + iki 74HC595 (SPI) ile 16 LED karaşimşek / 16-LED Knight Rider on ESP32 with two 74HC595s (SPI)
2#include <SPI.h>
3
4const int SCK_PIN = 18;    // SH_CP
5const int MOSI_PIN = 23;   // DS
6const int LATCH_PIN = 5;   // ST_CP
7
8void write16(uint16_t value) {
9  SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));  // 3,3 V için 4 MHz yeterli / 4 MHz is plenty at 3.3 V
10  digitalWrite(LATCH_PIN, LOW);
11  SPI.transfer(highByte(value));    // önce uzaktaki entegre / far chip first
12  SPI.transfer(lowByte(value));     // sonra yakındaki / then the near chip
13  digitalWrite(LATCH_PIN, HIGH);
14  SPI.endTransaction();
15}
16
17void setup() {
18  pinMode(LATCH_PIN, OUTPUT);
19  SPI.begin(SCK_PIN, -1, MOSI_PIN, -1);   // MISO ve SS kullanılmıyor / MISO and SS unused
20  write16(0);
21}
22
23void loop() {
24  for (int i = 0; i < 16; i++) { write16(bit(i)); delay(40); }   // ileri / forward
25  for (int i = 14; i > 0; i--) { write16(bit(i)); delay(40); }   // geri / backward
26}

Raspberry Pi Pico ve MicroPython ile 74HC595

Pico'da da 74HC595'i 3V3(OUT) pininden besle. MicroPython'da Arduino'daki shiftOut()'un hazır bir karşılığı yoktur, ama donanım SPI'si bu işi fazlasıyla görür: SPI0 biriminin GP18 (SCK) ve GP19 (MOSI) pinleri kullanılır, latch için herhangi bir GPIO seçilebilir; burada GP17 seçildi. MicroPython, SPI0'ın MISO pinini (GP16) de SPI'ye ayırır; bu pini başka bir işe bağlama. spi.write() fonksiyonuna birden fazla bayt verirsen zincirdeki bütün entegreleri tek seferde güncellersin ve yine ilk bayt en uzaktaki entegreye gider. Kurulum ve ilk adımlar için Raspberry Pi Pico Nedir? yazısına bakabilirsin.

MicroPython
1# Pico + 74HC595: yürüyen LED ve ikilik sayaç (SPI) / Pico + 74HC595: running light and binary counter (SPI)
2from machine import Pin, SPI
3import time
4
5# GP18 = SCK -> SH_CP, GP19 = MOSI -> DS; GP16 (MISO) boş kalır / GP16 (MISO) stays unconnected
6spi = SPI(0, baudrate=4000000, polarity=0, phase=0, sck=Pin(18), mosi=Pin(19))
7latch = Pin(17, Pin.OUT, value=1)    # ST_CP
8
9def write595(*values):
10    # birden çok bayt = zincirdeki entegreler, ilk bayt en uzaktakine
11    # several bytes = chained chips, the first byte goes to the far chip
12    latch.value(0)
13    spi.write(bytes(values))
14    latch.value(1)                   # yükselen kenar: çıkışlara aktar / rising edge: copy to the outputs
15
16write595(0)
17while True:
18    for i in range(8):               # yürüyen LED / running light
19        write595(1 << i)
20        time.sleep_ms(80)
21    for n in range(256):             # ikilik sayaç / binary counter
22        write595(n)
23        time.sleep_ms(20)

Daha büyük yükler: transistör, ULN2803 ve TPIC6B595

74HC595'in çıkışları yalnızca küçük LED akımları için uygundur. Röle bobini (70–90 mA), küçük motor, birkaç buzzer ya da 12 V LED şerit gibi yükleri doğrudan bağlama. Her çıkışın arkasına bir NPN transistör koyabilir ya da sekiz Darlington transistörü tek kılıfta toplayan ULN2803'ü kullanabilirsin: kanal başına 500 mA'e kadar akımı GND tarafından anahtarlar ve bobinli yükler için koruma diyotları içindedir; diyotların işe yaraması için COM pinini yükün beslemesine bağlarsın. Daha derli toplu bir çözüm ise 74HC595 ile aynı şekilde programlanan, ama açık drenli güçlü çıkışlara sahip TPIC6B595'tir: çıkış başına sürekli 150 mA taşır ve 50 V'a kadar yükleri anahtarlayabilir. 20 pinli olduğu için pin dizilimi farklıdır; yükleri artı ile çıkış arasına bağlarsın.

74HC595 mi, MAX7219 mu, TM1637 mi?

Özellik74HC595MAX7219TM1637WS2812B
Kontrol pini3 (DS, SH_CP, ST_CP)3 (DIN, CLK, CS)2 (CLK, DIO)1 (DIN)
Çıkış sayısıEntegre başına 8, zincirlenebilir64 LED (8 hane ya da 8x8 matris)4–6 haneli 7 segmentHer LED kendi adresiyle
Akım sınırlamaHer LED'e ayrı dirençTek dirençle (RSET) bütün LED'lerModülde hazırLED'in içinde
ParlaklıkOE ile toplu PWM16 kademe, yazılımla8 kademeRenk kanalı başına 256 kademe
En uygun kullanımLED çubuk, röle kartı, genel amaçlı çıkışLED matris, çok haneli displaySaat, sayaçRenkli efektler, şeritler

Basit bir LED çubuğu, 8 kanallı bir röle kartı ya da her biri ayrı bir işe yarayan dijital çıkışlar gerekiyorsa 74HC595 en ucuz ve en esnek seçenektir. 8x8 LED matris ya da çok haneli display'lerde ise çoklamayı kendisi yapan MAX7219 işini çok kolaylaştırır. Renkli ve tek tek kontrol edilen ışıklar istiyorsan WS2812B NeoPixel LED'ler tek bir veri piniyle çalışır.

74HC595 ile proje fikirleri

  • 16 LED'li karaşimşek: İki zincirli entegreyle git-gel efektini kur ve hızını bir potansiyometreyle ayarla.
  • LED bar seviye göstergesi: Bir sensörün ya da ses seviyesinin değerini 8–16 LED'lik bir çubukta göster.
  • Park sensörü: HC-SR04 ile ölçülen mesafe azaldıkça yeşilden kırmızıya doğru daha çok LED yak.
  • İki haneli skor tabelası: İki 7 segment display ve iki zincirli entegreyle butonlu, titremeyen bir sayaç yap.
  • İkilik (binary) saat: Saati, dakikayı ve saniyeyi LED sütunlarında ikilik sayı olarak göster; zamanı bir RTC saat modülünden al.
  • 3x3x3 LED küp: Katmanları transistörlerle, sütunları 74HC595'lerle sürerek üç boyutlu animasyonlar oluştur; ayrıntılar Arduino LED küp yazısında.
  • 8 kanallı röle kartı: ULN2803 ya da TPIC6B595 ile 3 pinden sekiz röleyi kontrol et.

Sık yapılan hatalar ve çözümleri

BelirtiOlası nedenÇözüm
Hiçbir LED yanmıyorOE boşta ya da HIGH, MR LOW'da kalmışOE'yi GND'ye, MR'ı VCC'ye bağla
LED'ler hiç değişmiyorLatch (ST_CP) tetiklenmiyor ya da yanlış pine bağlıshiftOut()'tan sonra latch'i LOW'dan HIGH'a çek, pin numarasını kontrol et
Kaydırma sırasında LED'ler titriyor ya da desen bir bit kaymışSH_CP ile ST_CP aynı pine bağlı; bu durumda kaydırma yazmacı depolama yazmacından hep bir saat önde olurLatch için ayrı bir pin kullan, yalnızca bütün baytlar gönderildikten sonra HIGH yap
Yanan LED'ler ters sıradaBit sırası karışmış ya da Q0 yanlış yerdeMSBFIRST ile LSBFIRST'ü değiştir, Q0'ın 15. pinde olduğunu kontrol et
Zincirdeki entegreler yer değiştirmiş ya da biri bir adım geriden geliyorBaytların sırası ters ya da 2. entegrenin DS'si Q7' yerine Q7'ye (7. pin) bağlıÖnce uzaktaki entegrenin baytını gönder, DS'yi 9. pine bağla
Çok LED yanınca hepsi sönükleşiyor, entegre ısınıyorToplam akım 70 mA sınırını aşıyorDirençleri 470 Ω–1 kΩ yap ya da ULN2803 / TPIC6B595 kullan
LED'ler rastgele yanıp sönüyor, kablolara dokununca değişiyorKondansatör yok, kablolar uzun ya da bir giriş boştaVCC–GND arasına 100 nF koy, kabloları kısalt, OE ve MR'ı asla boşta bırakma
ESP32 ya da Pico ile kararsız çalışıyorEntegre 5 V ile beslenmiş, 3,3 V sinyal HIGH sayılmıyorEntegreyi 3V3'ten besle ya da 74HCT595 kullan
Devre çalışmadığında kodu en basit hale getir: write595(0b10101010) gönder ve hangi LED'lerin yandığına bak. MSBFIRST ile Q1, Q3, Q5 ve Q7'deki LED'ler yanıyorsa bağlantı ve bit sırası doğrudur. Hiçbiri yanmıyorsa multimetreyle 16. pinde besleme gerilimini, 13. pinde 0 V'u ve 10. pinde yine besleme gerilimini ölç; bu üç değerden biri yanlışsa sorun kablolamadadır.

74HC595, pin sıkıntısını çözmenin en ucuz ve en öğretici yoludur. Kaydırma ve latch mantığını bir kez kavradığında aynı fikri SPI cihazlarında, LED matris sürücülerinde, display modüllerinde ve 74HC165 ile buton okurken de tanırsın. Önce 8 LED'li sayaçla başla, ardından zinciri büyüt ve SPI'ye geç. BlueGrays uygulamasında yürüyen LED, karaşimşek, hız ayarlı efektler ve 7 segment sayaç projelerini Arduino, ESP32 ve Raspberry Pi Pico için devre şemaları ve kodlarıyla adım adım bulabilirsin.

Sıkça sorulan sorular

74HC595 ne işe yarar?

74HC595, mikrodenetleyiciden seri olarak gelen veriyi 8 paralel çıkışa çeviren bir kaydırmalı yazmaçtır. Arduino'nun yalnızca 3 pinini kullanarak 8 LED'i, bir 7 segment display'i ya da transistörler üzerinden röleleri kontrol etmeni sağlar. Entegreleri zincirleyerek aynı 3 pinle 16, 24 ya da daha fazla çıkış elde edebilirsin.

Kaç tane 74HC595 zincirlenebilir?

Teorik bir sınır yoktur: her entegrenin Q7' çıkışı bir sonrakinin DS girişine bağlanır, saat ve latch hatları ortak kullanılır. Pratikte sınırı güncelleme süresi ve ortak saat hattının yükü belirler; Uno'da shiftOut() her entegre için yaklaşık 100 µs ekler, SPI ile bu süre birkaç mikrosaniyeye iner. Uzun zincirlerde her entegreye 100 nF kondansatör koy ve kabloları kısa tut.

74HC595 bir çıkıştan kaç mA verir?

Veri sayfası çıkış gerilimlerini çıkış başına 6 mA'de garanti eder; mutlak sınır çıkış başına 35 mA, VCC ya da GND pininden toplam 70 mA'dir. Sekiz LED'in aynı anda yanabileceğini düşünerek LED başına 6–8 mA hedeflemek güvenlidir. 5 V'ta bu, yaklaşık 470 Ω'luk dirence karşılık gelir.

74HC595 ESP32 ile 3,3 V'ta çalışır mı?

Evet. 74HC595 2–6 V arasında çalıştığı için ESP32 ya da Pico'nun 3V3 pininden beslenebilir ve 3,3 V'luk sinyalleri sorunsuz tanır. Entegreyi 5 V ile beslersen 3,3 V'luk sinyaller HIGH eşiğinin altında kalabilir; bu durumda 74HCT595 ya da bir lojik seviye dönüştürücü kullan.

74HC595'te latch pini ne işe yarar?

Latch (ST_CP ya da RCLK) pini, kaydırma yazmacına gönderdiğin bitleri çıkışlara aktaran tetiktir. Bitler kayarken çıkışlar eski değerini korur; latch pinine yükselen kenar geldiğinde sekiz çıkış aynı anda güncellenir. Bu sayede LED'ler veri gönderilirken titremez ve zincirdeki bütün entegreler aynı anda değişir.

74HC595 ile röle ya da motor sürülebilir mi?

Doğrudan sürülemez; çıkışlar yalnızca birkaç miliamperlik LED akımları için uygundur. Röle, motor ya da LED şerit için her çıkışa bir transistör ekle ya da kanal başına 500 mA'e kadar anahtarlayabilen ULN2803'ü kullan. Aynı şekilde programlanan TPIC6B595 ise çıkış başına 150 mA taşıyabilen güçlü bir alternatiftir.

Tüm projeleri gör
Yürüyen Led
#5Orta

Yürüyen Led

6 LED'i sırayla yakarak yürüyen ışık efekti oluşturan proje. Dizi (array) kullanımı ve for döngüsüyle çoklu pin kontrolünü öğretir.

4.6(83)
192
Karaşimşek Led
#6Orta

Karaşimşek Led

6 LED'i ileri-geri sırayla yakarak Knight Rider tarzı karaşimşek efekti oluşturan proje. Çift yönlü döngü mantığını öğretir.

4.8(104)
189
Hız Ayarlı Yürüyen Led
#7Orta

Hız Ayarlı Yürüyen Led

Potansiyometre ile LED yürüme hızını gerçek zamanlı olarak ayarlayabilen proje. analogRead ile potansiyometre değerini okuyarak delay süresini dinamik kontrol etmeyi öğretir.

4.6(71)
134
Hız Ayarlı Karaşimşek Led
#8Orta

Hız Ayarlı Karaşimşek Led

Potansiyometre ile karaşimşek LED animasyonunun hızını gerçek zamanlı olarak ayarlayabilen proje. Analog giriş ve çift yönlü döngü kontrolünü birleştirir.

4.5(59)
115
ESP32 Yürüyen LED
#108Başlangıç
Premium

ESP32 Yürüyen LED

6 LED'in sırayla soldan sağa, sağdan sola hareket etmesi (Knight Rider tarzı). For döngüsü ve dizi (array) kullanımının temel örneği. Yön değişimi mantığını öğretir.

4.5(19)
32
Raspberry Pi Pico Yürüyen LED / Chasing LED (6 LED, GP14 → GP9)
#153Başlangıç
Premium

Raspberry Pi Pico Yürüyen LED / Chasing LED (6 LED, GP14 → GP9)

Pico ile klasik "yürüyen LED" animasyonu — 6 LED versiyonu! 6 LED soldan sağa sırayla yanıp sönüyor, sanki ışık dizi boyunca yürüyor. Bu proje ile **Python list yapısı** (`LED_PINS = [14, 13, 12, 11, 10, 9]`), **list comprehension** (`[Pin(p, Pin.OUT) for p in LED_PINS]`), **for döngüsü ile pin kontrolü** ve **enumerate()** kavramlarını öğreneceksin. GP9-GP14 pinlerine 6 LED, her birinde 220Ω akım sınırlama direnci. Kod çok temiz: 6 LED'i tek tek tanımlamak yerine liste ile toplu tanımlıyoruz

0.0(0)
8
7 Segment Display İle 0-9 Sayı Yazdırma
#41Orta
Premium

7 Segment Display İle 0-9 Sayı Yazdırma

7 segment display üzerinde 0'dan 9'a kadar sayıları sırayla gösteren proje. Segment pinlerini kontrol ederek rakam oluşturma mantığını öğretir.

4.5(30)
42
7 Segment Display İle 0-99 Sayı Yazdırma
#42İleri
Premium

7 Segment Display İle 0-99 Sayı Yazdırma

Çift haneli 7 segment display ile 0'dan 99'a kadar sayıları gösteren proje. Bit işlemleri (bitRead) ve birler-onlar basamağı ayrıştırma mantığını öğretir.

4.5(27)
35