2 tane 74hc595?

Başlatan Maxim, 10 Temmuz 2013, 13:39:06

Maxim

ilk defa deneme yaptım

ete hocam sizin 8. dersteki örneği kullanarak 1 adet 595 kullandım, sorun yok
fakat benim 12 led sürmem lazım
yani 2 adet 595 kullanmam lazım

biraz bakındım
1. entegrenin Q7 çıkışını 2. nin DS ucuna vermek gerekiyor
st_cp ve sh_cp pinleri paralel

peki yazılımda değişiklik gerekiyormu bunun için?
zira 1. led yanıyor, sonra 2. led yanıyor bu anda 2. entegrenin 1. ledi de yanıyor



_MeRKeZ_

#1
74595'in çalışma mantığını şu şekilde ifade edebiliriz.

Diyelim ki 16 tane lambamız var ve bunların 11111111 ve 11001100 şeklinde yanmasını istiyoruz.
SH_CP, ST_CP, MR, OE bacakları ortak.  MR=1 ve OE=0 olarak belirlenir.

Birinci 74595'in Q7' bacağını ikincinin veri bacağına bağladık.

En sağdaki değerden başlayarak verilerimizi yolluyoruz. Veri yazdırırken şu yolu kullanıyoruz.

Veri değeri: 0 olarak ayarlanır.
SH_CP 1 ve 0 yapılır.
ST_CP  0 ve 1 yapılır.

Böylece ilk değerimizi girmiş olduk akabinde tekrar 0 değerini giriyoruz

Sırada 1 değeri var.

Veri değeri: 1 olarak ayarlanır.
SH_CP 1 ve 0 yapılır
ST_CP  0 ve 1 yapılır

Bu şekilde diğer değerler de girilir. Asıl göz önünde bulundurulması gereken durum, değer girmeye sağdan başlamak gerektiği. Bu mantık bilindiği müddetçe de istenildiği kadar 74595 sürülebilir.

Aşağıda uygulama dosyası da mevcut.


Ekleme: Girdiğimiz değerler ilk olarak en başta gözükecek, biz değerleri girmeye devam ettikçe bir sağa kayacak böylece en sonunda istediğimiz değere sahip olacağız.

ete

Merkez in anlatmaya çalıştığı tam shift register mantığıdır. Tek bir high datasının nasıl en baştan en sona kaydırıldığını açıklar. Shiftout komutu bu işlemi 8 bit bazında yapar.
Her bir 595 için ayrı bir değişken kullanırsan birinci değişken 8 adet led i , ikinci değişken ise geriye kalan 4 (aslında ilave 8 ledi kontrol edebilir) ledi kontrol eder.
Komut verilirken. Shiftout dta, clk ,1 ,[gurup2, gurup1] şeklinde bilgi yollanır ve yollanan bilginin çıkışa verilmesi için, 1 adet puls kilit pinine verilir. ( pulsout kilit,1)

Ete

Maxim

teşekkürler

ete hocam aynen dediğiniz gibi bende protonun help dosyasını incelerken fark ettimki komutta virgul kullanmam gerekiyor..
Shiftout dta, clk ,1 ,[gurup2, gurup1] dediğiniz gibi
sonrası çorap söküğü gibi geldi

protonda bu iş için shout komutu kullanılıyor

bu 1. led komutu
SHOut DTA,CLK,1,[0,1]
High AKTAR:DelayUS 5:Low AKTAR

bu 8. led komutu
SHOut DTA,CLK,1,[0,255]
High AKTAR:DelayUS 5:Low AKTAR

bu 12.led komutu
SHOut DTA,CLK,1,[15,255]
High AKTAR:DelayUS 5:Low AKTAR

ete

High AKTAR:DelayUS 5:Low AKTAR
satırı yerine ;
PULSOUT AKTAR,1         kullan, hafızada daha az yer tutar sanırım.
BU komut 10us lik bir puls uygular. Protonda da aynı şekilde kullanılıyor olması gerekir.

Ete


Maxim

ete usta dediğiniz doğru ama benim komple yeni bir algoritma yapmam gerekiyor sanırım.

şu anki program şöyle
her led için 2 satır var
1-shout satırı
2-aktar satırı

dediğiniz gibi denedim evet faydası oldu

sonra aktar satırını tek olarak ayırdım ve her yerden oraya gosub yaptım
kullanılan hafıza bayaa düştü

ama sonra aklıma tablo yapmak geldi
eğer onu yaparsam 12 adet shout satırı kullanmam gerekmeyecek


ete

Ben olsam şöyle yapardım.

Led var WORD şeklinde bütün ledleri kapsayan bir led değişkeni kullanırdım.
Birde YAN VAR BYTE isimli değişken kullanırdım bu da yanacak ledleri belirlemiş olacaktır.

Şimdi bir şekilde program içinde YAN=10 olduğunu varsayalım.
Led=LED  ^ (DCD YAN)   bu komut ile önceki LED değeri  (DCD YAN) sonucu ile bit bazında XOR işlemine tabi tutulur.
DCD YAN komutu ilgili biti set etmek için kullanılır. Diyelimki YAN=10 yani (aslında 11 ci ledi yakmak istiyoruz) Ama önceki yanmışlarada dokunmayacağız. O halde LED=LED ^ (DCD YAN)  yani LED=LED ^(DCD 10) bize LED=%010000000000
sonucunu verecektir.
Sonra SHOUT DTA,CLK,[LED.byte1,LED.Byte0]
Gosub AKTAR
şeklinde işlem hallolmuş olur.

Yanmış ledleri yine aynı komutla söndürebilirsin.
Zira Bit10 =0 ise ,
LED=LED ^ (DCD 10)  komutu ile Bit10=1 olur. 
Bit10=1 ise
LED=LED ^ (DCD 10) komutu ile Bit10=0 olur.

Hepsi bu kadar.
Ben örnekleri PBP bazında verdim ama aynı komutların Proton karşılığı var bulmak da sana düşüyor.
Ete

Maxim

ete hocam
önerdiğiniz algoritmayı deniyorum.

Led var WORD
YAN VAR BYTE
dediğiniz değişkenleri kullanıyorum ve

Led=LED  ^ (DCD YAN)
SHOUT DTA,CLK,[LED.byte1,LED.Byte0]
High AKTAR:DelayUS 5:Low AKTAR
komutu ile aktarım yapıyorum..

şöyle sorun oluyor.

12 adet led var
diyelim sayımız 9, yani 1-2-3-4-5-6-7-8 ve 9. led yanması lazım

xor komutundan sonra led değişkeni 512 değerini alıyor
shout komutundan sonra ise sadece 10. led yanmış oluyor

devam edip 2. tur döngüye geldiğimizde (YAN sayımız hala 9)
xor komutu sonrası led değişkenimiz 0 oluyor
yani 10. led de sönüyor

sonra tekrar 10. led yanıyor, sonra sönüyor

ete

Aşağıdaki deneme programını yazdım ve ben bir sorun görmedim. İsis de (LCD ekranda bit bazında) gördüğüm kadarı ile güzel çalışıyor.
YAN var byte
LED VAR WORD

SYMBOL TUS=PORTA.0

LCDOUT $FE,1," erol"
pause 300

clear
YAN=0
BASLA:

LED=LED ^ (DCD YAN)

lcdout $fe,$80,bin12 led
lcdout $fe,$c0,"led= ",dec led,"  "

pause 500
yan=yan+1
if yan=12 then
  yan=0
  led=0
endif 
goto basla

Adım adım ilerlersek.;
- Yanacak led 0 nolu led (aslında birinci led oluyor ama sıfırdan başlıyoruz DCD komutunun özelliği nedeni ile)
- Led=0 ile başlıyoruz. Yanacak led=0 iken DCD 0 komutu 1 sayısını buluyor ve Led=0 XOR 1=1 oluyor
- Led=1 XOR (DCD 1)  , DCD 1 bize 2 sayısını veriyor ve Led= 1 XOR 2=3 sayısını buluyor
- Led=3 XOR (DCD 2)  , DCD 2 bize 4 sayısını veriyor ve Led=3 XOR 4=7 olarak hesaplanıyor
- Led=7 XOR (DCD 3) = 15
- Led=15 XOR (DCD 4) = 31
- Led=31 XOR (DCD 5) = 63
- Led=63 XOR (DCD 6) = 127
- Led=127 XOR (DCD 7)= 255
- Led=255 XOR (DCD 8)= 511
- Led=511 XOR (DCD 9)= 1023
- Led=1023 XOR (DCD 10)= 2047
- Led= 2047 XOR (DCD 11)= 4095
şeklinde değerler alıyor.
Sonra tatmin olmadım ve 595 li devreyi kurup onuda denedim. Sırası ile ledler yanıp yanık kalarak ilerliyor. Sonuçta 12 led yandıktan sonra yeniden başa dönüyor.
XOR komutu kullandığımız için aynı komutu iki defa verirsen yanmış olan led sönecektir. Sen nasıl kullanmak istiyorsan gereken değişikliği yapmalısın. Yada ne olmasını istiyor isen açıkla ben yardımcı olayım.

Ete

Maxim

ete usta kusura bakma seni uğraştırdım.

deminden beri bakıyorum, aynı kodları kullanıyorum olmuyor.
sonunda nedenini buldum.

sen sayıları hep sıralı düşünerek algoritma oluşturdun
1 den sonra 2 sonra 3 gelecek
o zaman tamam

ama benim sayılarım rastgele
power ver, ilk sayı 8 olabilir mesela
sonra 1 olabilir..

o yüzden xor algoritması sanırım suya düştü
halbuki kodun hafızada kapladığı yer neredeyse yarıya düşmüştü :)


ete

Anladığım kadarı ile sıralı değil rastgele çalışmak istiyorsun.
İşin daha kolay o zaman.
aşağıdakileri dene;

BASLA:

LED=(DCD YAN)-1

shiftout DTA,CLK,1,[Led.byte1,led.byte0]:pulsout KIL,1


YAN değişkeni gerçek yanacak led adedini belirliyor. Diyelimki toplamda 10 adet led yanacak.
DCD 10=1024 dür. Bir çıkartırsak 1023 olacaktır bu rakam ise toplam 10 adet ledi yakacak sayıdır.

Ete

Maxim

ete usta dediğinizi yaptım
mükemmel oldu, 10 numara
teşekkürler

acemdiyarı

#12
Alıntı yapılan: ete - 17 Temmuz 2013, 21:37:07
Anladığım kadarı ile sıralı değil rastgele çalışmak istiyorsun.
İşin daha kolay o zaman.
aşağıdakileri dene;

BASLA:

LED=(DCD YAN)-1

shiftout DTA,CLK,1,[Led.byte1,led.byte0]:pulsout KIL,1


YAN değişkeni gerçek yanacak led adedini belirliyor. Diyelimki toplamda 10 adet led yanacak.
DCD 10=1024 dür. Bir çıkartırsak 1023 olacaktır bu rakam ise toplam 10 adet ledi yakacak sayıdır.

Ete

Merhaba ete hocam 2 taneden fazla 74hc595 leri arka arkaya bağlamak için 4 tane mesela o zaman
Led.byte3,led.byte2,Led.byte1,led.byte0 şeklindemi olmalı? yoksa başka bir işlemmi uygulanmalı.?
Help te 2 kısıma  ayrılmış çünki.
BYTE0 or LOWBYTE
Create alias to low byte of word
BYTE1 or HIGHBYTE
Create alias to high byte of word

ete

Değişkenleri çok iyi tanımadığını anlıyorum. Kısaca açıklayayım.
Bit değişkeni yalnızca bir bit saklar. Alacağı değer ya sıfır yada  olur.
Byte değişkeni 8 bitlik değerleri saklar. Alacağı değer 0-255 arasında olabilir.
Word değişkeni 16 bitlik (2x8 bit) değerleri saklar. Saklarken 2 byte halinde ayrılabilir. Byte0 kısmı Low baytı, Byte1 kısmı ise high byte kısmını saklar. Alacağı değer 0-65535 arasında değişir.
Bizim kullandıklarımız bunlar. Bunlara ilave olarak birde LONG değişkeni vardırki buda 32 bitlikdir. 4 x 8 bitlik hafızadan oluşur.
Bu değişken Byt0-Byte1-Byte2 ve Byte3 şeklinde 8 er bitlik bölümlere ayrılabilir.

Şimdi gelelim Shift Komutuna ve 74HC595 ilişkisine. 74HC595 8 bitlik bir shift registerdir. Devremizde 1 adet 595 var ise 1 adet byte değişkeni ile ona bilgi aktarabiliriz. Devremizde 2 adet 595 var ise 2 adet 8 bitlik (2 byte) bilgi aktarmamız gerekir. Birisi birinci 595'e diğer ise ikinci 595'e yerleşir.
Devremizde 3 adet 595 seri bağlı ise 3 adet 8 bitlik veri yollamak gerekir. Her biri bir 595'e yerleşir.
Devremizde 4 adet 595 seri bağlı ise 4 adet 8 bitlik veri yollamak gerekir. Bunu 2 adet word değişkeni ile yapabileceğimiz gibi 4 ayrı byte değişkeni kullanarak da yapabiliriz.  Örnekle açıklamak gerekir ise, elimizde 4 adet seri bağlı 595 var. Birincide %11011010 bilgisini (desimal 218) ,ikincide %10010010 (desimal 146) üçüncüde %10110110 (desimal 182) ve sonuncuda ise %10001001 (desimal 137) bilgisini görmek isteyeceğimizi varsayalım. Bu işi bir kaç farklı şekilde yapabilirim.
1. Shiftout DTA,CLK,1,[218,146,182,137]  bu sistemde değişken yerine direk sayıların kendilerini kullandık.
2. A=218:B=146:C=182:D=137  : Shiftout DTA,CLK,1,[A,B,C,D]   Sayıları değişkenlere verdik ve komutta  değişkenleri kullandık
3. X1=$DA92 : Y1=$B689 : Shiftout DTA,CLK,1,[X1.Byte1,X1.Byte0,Y1.Byte1,Y1.Byte0]  veya şöylede yazılabilirdi
    X1=55954 : Y1=46729 : Shiftout DTA,CLK,1,[X1.Byte1,X1.Byte0,Y1.Byte1,Y1.Byte0] 
    X1 ve Y1 değişkenleri word tipinden dir.
4. Bir adet LONG değişkeni kullanarak da halledilebilir. WW=$DA92B689 :
    Shiftout DTA,CLK,1,[WW.Byte3, WW.Byte2, WW.Byte1 , WW.Byte0]
Bu 4 farklı kullanım şekli aynı sonucu verir.
LONG tipi değişkenler yalnızca 18F serisinde kullanılabilmektedir. Kullanıldığı zaman derleyicide PBPL seçeneği seçilmiş olmalıdır.  (MCS de View menüsü, Program & Compiler seçeneğinde Compiler kısmında PBPL kutusu işaretli olmalı ve Assembler seçeneğinde MPASM seçilmiş olması gerekir. )

Umarım konu anlaşılmıştır.

Ete


İYLLC

MAXIM

Eger işini görürse ete beyle tanışmadan önce ccs c ile hazırlamış olduğum 16f877a ile 74LS138 ile yapılmış isis de çalışan bir devre paylaşıyorum (işine yarayana açık kodunuda gönderebilirim) 32 led kullanabilirsin.çok basit bir devre ve kodu var.

Kolay gelsin.
KULA BELA GELMEZ HAK YAZMADIKÇA HAK BELA YAZMAZ KUL AZMADIKCA

Powered by EzPortal