Atmega8 ile 74HC595 Zincirleme Bağlama
Bu içerik, Atmega8 74HC595 zincirleme bağlama yani yalnızca 3 kontrol hattı ile 16 LED’i nasıl kontrol edeceğinizi gösterir. Bunu, 74HC595 kaydırma yazmaçlarını(shift register) zincirleme yaparak yapıyoruz. Daha önce 74HC595 kullanım hakkında oluşturduğumuz içeriğimize bakmanızı öneririz.
74HC595 kaydırma yazmacı, 8 bitlik bir depolama kaydına ve bir 8 bit kaydırma kaydına sahiptir. Veriler, kaydırma kaydına(shift) seri olarak yazılır, ardından depolama(storage) kaydına kilitlenir. Depolama kaydı daha sonra 8 çıktı satırını kontrol eder. Ayrıca buradan 74HC595 entegersinin veri sayfasına bakabilirsiniz.
Aşağıdaki şekil 74HC595 pin çıkışını göstermektedir.
Pin 14 (DS) Veri pinidir. Bazı veri sayfalarında “SER” olarak anılır.
Pin 11 (bazı veri sayfalarında SH_CP veya SRCLK) Düşük’ten Yüksek’e gittiğinde, DS’nin değeri kaydırma yazmacında saklanır ve yeni bit için yer açmak için kaydın mevcut değerleri kaydırılır.
Pin 12 (bazı veri sayfalarında ST_CP veya RCLK), veriler kaydırma yazmacına yazılırken düşük tutulur. Yüksek olduğunda, kaydırma yazmacının değerleri depolama kaydına takılır ve bunlar daha sonra Q0-Q7 pinlerine gönderilir.
Aşağıdaki zamanlama şeması, 00000000 başlangıç değerlerini varsayarak Q0-Q7 çıkış pinlerini 11000011’e nasıl ayarlayacağınızı gösterir.
Devre Şeması
Tek 74HC595’i 8 farklı LED ile kullanmak için bu kodu kullanabilirsiniz, devreyi kurup kodu Atmega8’e yüklediğinizde “knight rider” yani kara şimşek devresi elde edeceksiniz.
Ayrıca buradan Arduino ile yaptığımız kara şimşek devresine göz atabilirsiniz.
Tek 74HC595 Kullanan Atmega8 Kodu
#include <avr/io.h> #include <util/delay.h> #define DS_PORT PORTC #define DS_PIN 0 #define ST_CP_PORT PORTC #define ST_CP_PIN 1 #define SH_CP_PORT PORTC #define SH_CP_PIN 2 #define DS_low() DS_PORT&=~_BV(DS_PIN) #define DS_high() DS_PORT|=_BV(DS_PIN) #define ST_CP_low() ST_CP_PORT&=~_BV(ST_CP_PIN) #define ST_CP_high() ST_CP_PORT|=_BV(ST_CP_PIN) #define SH_CP_low() SH_CP_PORT&=~_BV(SH_CP_PIN) #define SH_CP_high() SH_CP_PORT|=_BV(SH_CP_PIN) //====================== void ioinit(void); void output_led_state(unsigned char __led_state); //====================== int main (void) { ioinit(); while(1) { /* Kara şimşek LED sıralaması 10000000 01000000 00100000 00010000 00001000 00000100 00000010 00000001 00000010 00000100 00001000 00010000 00100000 01000000 */ for (int i=7;i>=0;i--) { output_led_state(_BV(i)); _delay_ms(100); } for (int i=1;i<7;i++) { output_led_state(_BV(i)); _delay_ms(100); } } } void ioinit (void) { DDRC = 0b00000111; //1 = output, 0 = input PORTC = 0b00000000; } void output_led_state(unsigned char __led_state) { SH_CP_low(); ST_CP_low(); for (int i=0;i<8;i++) { if (bit_is_set(__led_state, i)) DS_high(); else DS_low(); SH_CP_high(); SH_CP_low(); } ST_CP_high(); }
Şuana kadar yaptığımız etkileyici ama 16 LED’i kontrol ettiğimizi söylememiş miydik? Bunu yapmak için başka bir 74HC595 kaydırma yazmacı, daha fazla LED, daha fazla direnç ve daha fazla kablo eklememiz gerekiyor.
Kaydırma yazmaçlarını birbirine zincirlemek için Q7′ pinini kullanıyoruz.
Değiştirilen devre aşağıda gösterilmiştir.
Devre şemasına eklemeyi yaptıktan sonra breadboard üzerinde de değişiklikleri yapalım:
İki 74HC595 Kullanan Atmega8 Kodu
#include <avr/io.h> #include <util/delay.h> #define DS_PORT PORTC #define DS_PIN 0 #define ST_CP_PORT PORTC #define ST_CP_PIN 1 #define SH_CP_PORT PORTC #define SH_CP_PIN 2 #define DS_low() DS_PORT&=~_BV(DS_PIN) #define DS_high() DS_PORT|=_BV(DS_PIN) #define ST_CP_low() ST_CP_PORT&=~_BV(ST_CP_PIN) #define ST_CP_high() ST_CP_PORT|=_BV(ST_CP_PIN) #define SH_CP_low() SH_CP_PORT&=~_BV(SH_CP_PIN) #define SH_CP_high() SH_CP_PORT|=_BV(SH_CP_PIN) //=============================================== void ioinit(void); void output_led_state(unsigned int __led_state); //=============================================== int main (void) { ioinit(); while(1) { for (int i=15;i>=0;i--) { output_led_state(_BV(i)); _delay_ms(50); } for (int i=1;i<15;i++) { output_led_state(_BV(i)); _delay_ms(50); } } } void ioinit (void) { DDRC = 0b00000111; //1 = output, 0 = input PORTC = 0b00000000; } void output_led_state(unsigned int __led_state) { SH_CP_low(); ST_CP_low(); for (int i=0;i<16;i++) { if ((_BV(i) & __led_state) == _BV(i)) DS_high(); else DS_low(); SH_CP_high(); SH_CP_low(); } ST_CP_high(); }
Az önce 16 LED’i çalıştırarak hedefimize ulaştık, ancak daha fazla shift register zincirlemeye devam edebiliriz. Bu teknik elbette sadece LED’lerle sınırlı değildir ve diğer birçok türde cihazı çalıştırmak için çıkış portlarını çoğaltmak için kullanabiliriz.
Bu teknikle ilgili bir uyarı. Devreyi açtığınızda, çıkış hatları rastgele bir değere ayarlanır. Bunları istediğiniz değerlere ayarlamak bir mikrosaniyeden daha kısa sürüyor, ancak bu bazı devreler için sorunlara neden olabilir. Bu durumda depolama kayıtlarını sıfırlamak için MR ve OE pinlerini kullanabilirsiniz.
Yorum yapma özelliği, forum tarafından gelen istek sebebiyle kapatılmıştır. Lütfen tartışmalar ve sorularınız için topluluk forumumuza katılın.