Merhaba arkadaşlar “MSP430′u ASM ile Programlama” yazımın devamı niteliğinde uygulama yazılarını paylaşacağım bu yazımda MSP430 ile 74hc595 ve kullanımı konusunda bilgiler verilecek programlama ASM ile yapıldı
Şimdi kaydırmalı kaydedici (shift register) entegresi olan 74hc595`i nasıl sürebileceğimizi anlatayım. Yapacağımız uygulama kısaca 8 adet ledin tek tek sola doğru kayarak sırayla yanması. (istenirse 2 adet 74hc595 kullanılarak 16 adet ledde sürülebilir) bu işlemi 5ms aralıklarla WDT kesmesini kullanarak yaptım Buton yardımıylada Paus/Play fonksiyonlarını kontrol edeceğiz yani led leri durdurup kaldığı yerden başlatacağız.
74HC595 Entegresi
74hc595 ve 74ls164 entegreleri shift regestirir olarak adlandırılırlar ve de port çoklamak amacıyla kullanılırlar minimum 2 maksimum 5 pini kullanılarak 8 bitlik veri çıktısı elde etmeye yarar. Pin sayısının yeterli olmadığı durumlarda kullanılırlar.
Q1-Q7 numaralı pinleri çıkış pinleridir entegreye göndrilen veri bu pinlerden gözlenir:
MR pini entegreninin restlenmesine yarayan pindir.
DS pini entegreye göndrilen verinin Rest(0) mi set(1) mi olduğunu ayarlayan pindir.
STCP pini gönderilen verilerin portlara yazdırılmasını sağlar.
SHCP pini DS pinindeki biti entegreye yazdırmaya yarar. her clock palsınde porttaki veriyi sola kaydırarak data pinnideki veriyi entegrenin 0. bitine yerleştirir.
OE çıkış portlarını(q0-q7 pinleri) aktif veya pasf yapmaya yarar.
74hc595 yerine 74164 entegreside kullanılablir aralarındaki tek fark ST_CP (Enablet) pinidir 74164 entegresinde bu pin yoktur. Kaydırma işlemi her Clock sinyalinde portlardan direk gözlenir. 74hc595 entegresinde ise kaydırma işlemin 8 bitlik veri gönderildikten sonra (enable) ST_CP pinine pals sinyali gönderildikten sonra portlardan gözlenir.
Uygulamaya ait video;
Kaynak kod;
#include "msp430g2231.h" ; #kulanılan mcu yu tanımlıyoruz ; place program in 'CODE' segment #define E_PIN BIT5;20h;00100000b; #define C_PIN 80h;10000000b;BIT7 #define D_PIN 40h;01000000b;BIT6 #define R_PIN 10h; BIT4 ;2231 entegresisin 128bitlik ram hafızası vardır bizde bu hafızadan ;3 bitlik yer ayırıyoruz bunları shift regestirisine veri göndermek için kullanıcaz. DATA1 EQU 0x0200;R5 ;shift regestiriye gönderilen veri bu değişkende ;tutulur ve bu değişkenini içindeki veri rla komutuyla sola ; kaydırılmak suretiyle fişft regestiriye yazdırılır. VERI EQU 0x0210;#define VERI 0x0210;R9 ;veri değişkeni ise şift regestiriye gönderilmek ; istenen bilgiyi temsil eder. CNT1 EQU 0x0202; #define CNT1 0x0202;şift regestiriye gönderilen veri 16 bit ;genişliğindedi bu değikene 16 sayısı yüklenerek DATA1 içerisindeki bilginin ;16 defa sola kaydırılarak tüm bitlerin yazdırılmasdını sağlayan değişkendir. ; EXTERN DATA1 ; EXTERN CNT1 ;DATA1 DS 1 ;CNT1 DS 2 NAME Mainloop ; module name PUBLIC Mainloop ; make the main label vissible RSEG CSTACK ; pre-declaration of segment RSEG CODE init: MOV #SFE(CSTACK), SP ; set up stack ; MOV.W #5A00H+0011000B,&WDTCTL ; watchdog timer 1000ms ayarla MOV.W #WDT_ADLY_250,&WDTCTL;WDT_ADLY_1000 WDT Yİ KULLANARAK 1000MS GECİKME YARATIR BIS.B #10001B,IE1 ;IE1 REGESTİRİSİ GENEL KESME KAYNAKLARINI KONTROL EDN REGESTİRİ ; BURDAN NMIIE VE WDTIE BAYRAKLARINI KURUYORUZ WDT KESMESİ OLUŞMASI İÇİN mov.b #11110111b,P1DIR ; P1 portunun 0 ve 6 bitleri çıkış gerisi giriş olarak ayarlandı mov.b #00001000b,P1IE ;P1 PORTUNUN HANGİ PİNİNDEN KESME OLUŞACAÐINI BLİERLER mov.b #00001000b,P1IES ; KESMENİN DÜŞEN KENARMI YOKSA YÜKSELEN KENARMI OLDUGUNU BELİRLER. mov.b #11100001b,P1OUT mov.b #00000001b,VERI ;Veri RAM Alanına 1 değerini yükle bu alan Şift Regestirriye gönderilecek olan veriyi tutar. mov.b #00000001b,DATA1 ;Data1 Ram alanında tanımlanmış olan 2 değişkenimizx bu alan ise şift regestiriye yazdırılacak olan verinin sırayla kaydırılmasında kullanılır. EINT ;Genel interput kaynaklarını etkinleşirir. call #SHIFTREG ;şift regestiriye ilk veriyi gönderrir bu DATA1 Değişkenindeki 1 değeridir. ;ve program ilk çalıştığında şift regestirinin 0. bitine bağlı led yanmaya başlar. Mainloop ;Ana program bloğu jmp Mainloop ;herhangibi bir kesme oluşana kadar sonsuz döngüye girer. SHIFTREG ;74595 regestiri bitleri yazdıracak gönderecek program CALL #SRESET ;Regestiriyi resetle( tüm bitleri sıfırla) mov.w #10h,CNT1 ;Sayac regestirisin 16 sayısını yükle SRG RLA DATA1 ;DATA1 deişkeninideki değeri bir sola kaydır.kaydırma işleminde Değişkenini 16. biti herzaman Status regestirisinin C (Caeryy)bitinde gösterilir. ; bizde bu özelliği kullanrak C floğındaki değere göre 74hc595 entegresindeki Data pininin değerini ayarlamak suretiyle bitlerin yazdırılmasıın sağlıyacağız. jc SETPIN ;SR nin C bitinin değeri Set(1) ise SETPIN etiketine git jnc CLRPIN ;SR nin C bitinin değeri reset(0) ise CLRPIN etiketine git SETPIN ;74595 entegresinin data(DS 14 nolu pini) değerini set(1) yap. BIS.B #40h,&P1OUT jmp CLOCK CLRPIN BIC.B #40h,&P1OUT ;74595 entegresinin data(DS 14 nolu pini) değerini reset(0) yap. CLOCK ; clock palsi göndererek data pinindeki değeri şift regestiriye yazdırır. ; clock işlemi portlardaki bitleri bir sola kaydırarak data(ds 14.)pinindeki değeri 0. bite yazdırarak 8bitlik veriyi portlara gönderir. BIC.B #80h,&P1OUT ;clock pinini resetle NOP ;bir saykıl bekle BIS.B #80h,&P1OUT ;clock pinini Set et. dec CNT1 ;göndrilen veriyi say 16 ya ulaştığında işlemi bitir. jnz SRG ;sayma işlemi 16 dan küçükse başa dön. E_ ;veri gönderme işlemi bitti ise gönderilen verileri 74595 entegresine yazdır ve işlem portlardan görünsün BIC.B #20h,&P1OUT NOP BIS.B #20h,&P1OUT ret ;veri gönderme prosödürü bitti. kaldığın yerden çalışmak için geri dön. SIFIRLA ; Veri Değişkeni 16 bit ama 74595 entegresi 8 bit 8 bitlik veriyi aştı ise başa dön. mov #81h,R8 ;r8 değişkenine 129 değerini yükle sub.w VERI,R8 ;VERİ değişkeniniden 129 değerini çıkar. jn S1 ;VERI<129 işlem yapma RET S1 mov #1h,VERI ;VERI>129 ise VERI değişkenine 1 değerini yükle ret SRESET ;74595 entegresinini reset pinine bir pals göndrir ve entegrenin resetlenerek portların değerini sıfırlar. BIC.B #10h,&P1OUT NOP BIS.B #10h,&P1OUT ret BTN_KESME ;buton kesmesi oluştuğunda WDT kesmesinin oluşması için gerekli(IE1 Reg. 0. biti) bitin değerini tersleyerek WDT kesmesinin durumunu değiştiri (AÇ/KaPA) xor.b #1h,IE1 ;Genel kesme ayarları için gerekli Regestirinin WDT kesmesi için ayrılmış bitinin durumunu tesrle BIC.B #WDTIFG,IFG1 ;kesme kaynaklarını gösteren regestirinin WDt ileilgili bitini sıfırla BIC.B #00001000b,P1IFG ;buton kesmesinin hangi butondan olluştuğunu göstren regestirirni ilgili bitin sıfırla. EINT ;genel kesme bayrağını etkinleştir (herhanigbi bir kesme oluştuğunda algıla) RETI ;kesmeden dön ve kaldığın yerden işlemlerin yapmaya devam et. WDT_KES ;WDT kesmesi oluştuğunda bu etikete dallan. CALL #SIFIRLA ;gönderilecek veriy kontrol et 128 den büyükse sıfırla mov.b VERI,DATA1 ; 74595 göndrilecek veriyi data1 değişkeinnie ata ve şift regestiriye göndrilmesini sağla call #SHIFTREG ;şift regestiriye veriyi yaz. RLA VERI ;Veri değişkeinnideki bitleri sola kaydır.sırayla yanması için. BIC.B #1H,IFG1 ;IFG1 REGESTİRİSİ OLUŞAN KESMENİNİ KAYNAÐINI GÖSTEREN rEGESTİRİDİR. ;WDTIFG (0 BİTİ) WDT KESME KAYNAÐINI GÖSTERİR. KESME OLUŞTUÐUNDA BU BAYRAK 1 OLUR YENİDEN WDT KURMAK İÇİN BU BAYRAÐIN SIFIRLANMASI GERKLİDİR. EINT ; (GIE) GENEL KESME BAYRAÐINI AKTİFLEŞTİRİR RETI COMMON INTVEC DINT ;GIE KESME BAYRAÐINI TEMİZLE (0 YAPAR) ORG WDT_VECTOR;0FFFEh WDT KESME VEKTÖRÜ DW WDT_KES ; KESME OLUŞUNCA BU ETİKETE DALLAN ORG RESET_VECTOR;0FFFEh; İLK ENERCİ GELDİÐİNDE VEYA RESET EDİLDİÐİNDE BU ETİKETE DALLAN DC16 init ORG PORT1_VECTOR;0xFFE4;buton kesme vektörü DW BTN_KESME;kesme butondan oluştuğunda gidilecek kesme etiketi END
Kodun Çalışması
Kullandığımız Shift Regestiriy 74hc595 entegresi 4 pin olarak sürüyoruz bu pinler data(14pin), clock(11pin), enablet(12pin) ve reset(10pin) pinleri. Mcu ve 74hc595 entegresini bağlantıları aşağıdaki tablodan göreblirsiniz.
Shift regestiriye veri gönderen kodumuz “SHIFTREG” bu kod adım adım açıklayalım ve 74hc595 entegresine nasıl veri gönderiliceğini kavrayalım.
SHIFTREG ;74595 entegreye veri göndermek için kullanılan kodların bulunduğu adresi belileyen etiket.
CALL #SRESET ;entegreyi resetle.tüm çıkışlarını sıfırla. Bu işlem için SRESET etiketine dallanır ve işi bitince bir alt satırdan çalışmaya devam eder.
mov.w #10h,CNT1 ;Sayac regestirisin 16 sayısını yükle. Msp430 16 bitlik mcu`dur gönderilecek verinin tamamını göndermek için sayıcı değişkenine 16 sayısı yüklenmeli eğer 8 değeri yüklenirse şift regestiriye göndermek istediğimiz verinin yarısını göndermiş oluruz, buda istedimiz sonucu alamıyacağız anlamına gelir.
SRG RLA DATA1 ;DATA1 deişkeninideki değeri bir sola kaydır. kaydırma işleminde Değişkenini 16. biti herzaman Status (SR) regestirisi’nin C (Caeryy) bitinde gösterilir.
bizde bu özelliği kullanrak C bitindeki değere göre 74hc595 entegresindeki Data pininin değerini ayarlamak suretiyle bitlerin yazdırılmasını sağlayacağız. Bu işlemi C bitinide ğerine göre kodu gerekli etiketlere dallandırılması suretiyel data pinin C bitine göre değer almasını sağlayarak yapacağız.
jc SETPIN ;SR nin C bitinin değeri Set(1) ise SETPIN etiketine git.
jnc CLRPIN ;SR nin C bitinin değeri reset(0) ise CLRPIN etiketine git
SETPIN ;74595 entegresinin data(DS 14 nolu pini) değerini set(1) yap.
BIS.B #40h,&P1OUT 74hc595 entegresisni data(14.pin)pinine bağlı pinin değerini 1Set etder. jmp CLOCK gönderilecek veriyi belirledikten sonra SH_CP(11.pin) pinine bir clock palsi gönderilir ve data pinnideki değer bir sola kaydırılır.
CLRPIN BIC.B #40h,&P1OUT ;74595 entegresinin data (DS 14 nolu pini) değerini reset(0) yap.
CLOCK ; Data Bacağındaki değeri 0/1 74595 yazdırmak için portlardki değeri bir sola kaydırarak data pinin değerini en sağa yazdırmaya yar.
BIC.B #80h,&P1OUT ;Clock (11)pinini 0 yap
NOP ;bir saykıl bekle
BIS.B #80h,&P1OUT ;clock pinini Set 1 yap.
dec CNT1 ;DCNT1 bir azalt. 0 değilse sıradaki biti göndermek için SRG etiketine dallan.
jnz SRG ;sayma işlemi 0 ise başa dön.
E_ ;veri gönderme işlemi bitti ise gönderilen verileri 74595 entegresine yazdır. gönderilen verinin Shift regestiride görülebilmesi için Enable pinine bir pals gönder.
BIC.B #20h,&P1OUT enable pinini 0 yap
NOP bir saykıl bekle
BIS.B #20h,&P1OUT Enable pinini 1 yap
ret Shift regestirye yazdırma işlemi sona erdi. Geri dön ve programa kaldığın yerden devam et.
istağe bağlı olarak 2 adet Shift regestiri kullanılarak 16 adet led çalıştırılabilir onun için gerekli bağlantı şeması aşağıdaki resimde gösterilmiştir.
Yayım tarihi: 2011/10/01 Etiketler: 74HC595, msp430 74hc595, msp430 asm, msp430 programlama, msp430 projeleri
Ardiuno’daki 74HC595 “pwm çoğaltma” ile ilgili bir sorunum var.
74HC595 entegresiyle kullanım için burada bir kütühane bulunuyor.
https://github.com/Simsso/ShiftRegister-PWM-Library
Kütüphane sahibine ait makale de burada
https://timodenk.com/blog/shiftregister-pwm-library
Ben buradaki şemaya göre bağlantıları yaptım. entegreye ardiuno’daki D1,D2 ve D9 pinini bağladım. verilen örnek kodu da kendime uyarladım.
Ama bir türlü istediğim sonuçları alamadım. Sizin makalenizi de inceledim.
Bu 74HC595 ile “pwm çıkışı” elde edilebiliyor mu?
benim yapmak istediğim uno’ya ait pwm çıkışları yetersiz geldiğinden bunları çoğaltmak.
yani entegre den “pwm” çıkışı almam gerekiyor ki “dc motor” sürücü kartında bulunan “enA” pinine bağlayabileyim.
Bu konu da yardımcı olabilirmisiniz?
evet pwm çoklanabiliyormuş kaynak kod ve videolu örnek http://forum.arduino.cc/index.php/topic,66988.0.html
D2, D3,D4 pinlerine bağladım. tercihli olarak pinleri değiştirmedim.
burada anlatıldığı gibi yaptım.
https://timodenk.com/blog/shiftregister-pwm-library
entegrenin ilk 3 ayağına 1 adet rgb led bağlamıştım.(rgb led 4 ayaklı, 3 ayağını entegreye bağladım.) entegredeki 4 ve 5nci pinleri de birbirinden ayrı 2 dc motorun enA pinleri olarak bağladım.
motorları hareket ettirip, durdurabiliyorum.
rgb led’de ise henüz istediğim rengi yakamadım.
motor ve rgb led için şöyle bir sorun var ki benim entegreye bağlantı yaptığım sırayı takip etmiyorlar.
sanırım bazen de pinlerin yeri değişiyor. ilginç ama led’e renk emri veriyorum bazen 2 motor birden hareket ediyor.
yine bir yerde yanlışlık yapıyorum galiba ama ardiunodan entegreye 2,3,4ncü pinleri bağladım bunlarda sorun yok. sadece nasıl çalışıyor onu anlamaya çalışıyorum.
iyi günler. rahatsız ediyorum ama bir konu da yardımcı olabilirmisiniz?
Ben 74HC595 ile “pwm” pinlerini çoğaltmak istiyorum. Bunun için şu kütühaneyi kullanıyorum:
https://github.com/Simsso/ShiftRegister-PWM-Library
Bu da bu kütüphaneye ait makale:
https://timodenk.com/blog/shiftregister-pwm-library/
Makaleye göre 74HC595 entegresinin “pwm” genişletme olarak kullanılması için şema:
https://timodenk.com/blog/wp-content/uploads/2017/10/single-sr_schem_screenshot-768×500.png
Bu da benim 2 dc motor enA pinleri ve 1 adet rgb led bağlantım.
https://cdn.pbrd.co/images/HAN8m3y.png
Bunlara göre yaptığım ardiuno da entegre komutlara hızlı cevap veriyor. yani performansda da bir sorun yok.
Sadece dc motorları 0 ile 255 aralığında değer vererek çalışmasını/hızlanmasını/durdurulması
sağlanırken, 0 ile durdurup, 255 ile de en hızlı şekilde hareket etmesini sağlıyor. yani 0 ile 255 aralığında bir değer verirsek bunu 0 gibi algılayıp, motoru durduruyor. yani bir nevi “digital pinlerde” olduğu gibi “HIGH/LOW” şeklinde yorumluyor. oysa “pwm pinlerinin” özelliği hızında istenilen seviyede ayarlanabilmesi ama bu olmuyor. nedendir bilmiyorum? yoksa gerisi gayet güzel çalışıyor.
sorunumu çözdüm sağolun.