PIC ILE GECIKME VE DÖNGÜLER Döngü nedir? pic ile programlama yapmaya niyetlendiyseniz en azından aklınıza bu takılıyor ise, az veya çok programlama konusunda bilginiz vardır. döngüler bildiğiniz gibi program içersinde bir dizi işlemin belli sayıda yapılması yada bir şartın gerçekleşmesine kadar belli bir işin yapılması veya zaman gecikmesi gibi amaçlar için kullanılan alt yordamlardır. örneğin visual basic de 1 den 10 a kadar olan sayıların toplanması işlemi şöyle yapılır; -------------------- toplam=0 for sayi=1 to 10 toplam=toplam+1 next ----------------- sonuçta Toplam=10 olacaktır. 4 satırla işi hallettik. ama assembler a gelince iş değişiyo, çünkü orda for next kullanma gibi bir lüksümüz yok. assembler iile bu işlemleri yapmak için etiketlerden ve yönlendirme komutu olan GOTO komutundan çok faydalanıyoruz. konunun tepesine çıkmadan hemen küçük bir örnek verelim; --------------------------- dongubasi goto dongubasi ------------------------------ 2 satırlık bu program, pic için assembler da yapabileceğimiz en küçük döngüdür ve bir kısır döngüdür. hemen ledler ile ilgili bir örnek verelim; aşağıdaki kodlar ile portB nin birinci pin'ine (Sıfırıncı bit) bağlı olan led yakılıp söndürülür. --------------------------- dongubasi bsf portb,0 bcf portb,0 goto dongubasi ------------------------------ bakın şimdi konuyu biraz dağıtıp burda bir parantez açalım. ( Eğer bu programı denerseniz, devreyi çalıştırdığınızda göreceksiniz ki programınız sizin dediğinizi yapmayacak, yani diyeceksinizki "bu porogram" çalışmıyor. halbuki bu kodlar doğru. burda ince bir nokta var. biraz elektrik-elektronik bilginiz varsa şu soruya cevap verirsiniz değilmi. Soru: Evimizdeki ampuller devamlı yanıyor mudur, yani anahtarı açtığınızdan itibaren kapanıncaya kadar devamlı yanar mı? hemen cevap verelim. evet yanar, ama bu doğru cevap değil. bu lambalar, devamlı yanmaz, arasıra canı sönmek ister ve söner, normal şartlar altında bu sönme olayı 10 milisn de bir olur. parantezin içine bir parantez daha açalım ( konuları oldukça basitten başlayarak karmaşığa doğru götürmek isitoyrum ve bu anlatım şeklini seçmemdeki amaç da konunun anlaşılırlığını ve doyuruculuğunu sağlamak. o yüzden sizin için çok basit olan bir yer karşınıza gelirse o bölümü geçebilirsiniz. 2 inci parantez burda bitti.) birinci parantezden devam edelim. lambalarımız sn de 100 defa iyice sönmesine rağmen biz bunu farketmeyiz. neden? çünkü 10 ms gibi bir zamanı gözlerimiz algılamaz. ve devamlı yanıyor görürüz, çünkü lamba sönmesine rağmen yanık kalma süresi daha fazla olduğundan devamlı yanıyor görürüz. birinci parantezi de burda kapattık.) --------------------------- dongubasi bsf portb,0 bcf portb,0 goto dongubasi ------------------------------ pic de eğer osilator olarak 4 MHZ osilatör kullanıyorsak yukardaki programda, led yanar 1 mikrosn yanık kalır sonra söner ve 3 mikrosn sönük kalır. ve bu programda biz bişey gözlemleyemeyiz. Sönük kalma süresi yanık kalma süresinden daha fazla olduğu için led devamlı sönük görünecektir. yukardaki döngü özgür, bağımsız ve koşulsuz bir döngü ve belli bir sayısı yok. yani gene bu program pic resetleninceye kadar yada gücü kesilinceye kadar yada bozuluncaya kadar devam edecektir. yani kısacası bir koşul ve bir sayı yok. şimdi 10 defa çalışacak bir alt bölüm yapalım. bunun için mantığı anlatalım. (çünkü assemnbler da döngü için bir komut yok.) 1) belli sayıda bir döngü yapılırken önce döngü sayısı bir değişkene aktarılır. 2) döngü başı için bir etiket tanımlanır. 3) ardından bu sayı bir komutla her defasında bir azaltılır. DECFSZ komutu bu işi yapar. F register içindeki sayıyı bir azaltıp F registerin içine koyar, ve F içindeki sayı sıfıra indiğinde yönlendirme yaparak kendinden sonraki komutu işletmeden, pic'i kendinden sonraki 2 inci komuta gönderir. 4) eğer sıfıra ulaşıldıysa zaten döngüden çıkar. ama eğer sıfıra ulaşılmadıysa döngübaşı etiketine yönlendirme yapılması gerekir ki döngü devam etsin. buynuda GOTO komutu yapıyor. 5) ve döngü dışına çıkışta ne yapacaksa yada program devam edecekse bir sonraki satırda da o verilir. şimdi bunları toparlayalım. ----------------------------- movlw d'10' movwf SAYAC DONGUBASI decfsz SAYAC,f goto DONGUBASI goto BAS ----------------------------- SAYAC değişkenine 10 atanırsa döngü 10 defa işlenir 100 atanırsa 100 defa işlenir. pic içinde döngülerin en çok kullanıldığı yerler gecikme sağlamak, buton kontrolü gbi işlemlerdir. gözle görülebilir bir gecikme sağlayacaksak bu durumda döngü için kullanılan sayı artırılmalıdır. ve bu durumda bir adet döngü bizim ihtiyacımızı karşılamaz. ama program gereği bir miktar mesela 100 mikrosn gibi bir geçikme sağlamak istiyorsak bu durumda bir döngü işimizi görür. gözle görülür bir döngüden kasıt mesela ledi flaşör gibi yakıp söndürme işlemi yapacaksak içiçe döngüler kurmalıyız. ama göze göre ayar olduğu için de bunu kendimiz değişkenlere vereceğimiz sayılarla deneyerek yada hesaplayarak ayarlarız. içiçe döngülerde de mantık aynı olacaktır. program birinci döngüden başlar ve hemen ikinci döngüye girer, ikinci döngü bittiğinde birinci döngünün ilk dönüşü tamamlanmış olur. İÇ İÇE 2 Lİ DÖNGÜ: Visual basic de bir örnek: -------------------------------- for i=1 to 10 for j=1 to 10 komutlar next next --------------------------- bu döngü sonucunda komutlar 10+10=20 defa değil 10*10=100 defa işlenmiş olur. aynı işlemi pic ile yaparsak, ----------------------------- TUMDONGU movlw d'255' movwf SAYAC1 DONGUBASI1 movlw d'255' movwf SAYAC2 DONGUBASI2 decfsz SAYAC2,f goto DONGUBASI2 decfsz SAYAC1,f goto DONGUBASI1 RETURN ----------------------------- burda return komutu; eğer bu döngü bir gecikme alt yordamı olarak çağrılacaksa pic i çağrıldığı yere geri göndermek içindir. eğer bir yerden çağrılma yapılmayacak ve program işlenip devam edecekse return komutuna gerek yoktur. İÇ İÇE 3 Lü DÖNGÜ: GECIKME MOVLW D'255' MOVWF SAYAC1 DONGU1 MOVLW D'255' MOVWF SAYAC2 DONGU2 MOVLW D'255' MOVWF SAYAC3 DONGU3 DECFSZ SAYAC3,F GOTO DONGU3 DECFSZ SAYAC2,F GOTO DONGU2 DECFSZ SAYAC1,F GOTO DONGU1 RETURN END bu son alt program içiçe 3 lü döngüde elde edilebilecek en fazla zamanı elde eder. şüphesiz ki burda elde edilecek zaman gecikmesi 255X255X255 mikrosn diye aklamıza gelebilir ama Değildir. sadece yukardan aşağıya komutların bir defa işlendiğini gözönüne alırsak 13 adet komut vardır. ve bu aralık içiçe defalarca işlenmektedir. buradaki 3 lü döngüde sayac değişkenlerine 255 verip belli aralıklarla ledlerin sönüp yanmasını beklemeyin. çünkü döngüden çıkmak için pic in yaklaşık 50.000.000 küsür tane işleyecek komutu var. buda yaklaşık 50 sn gibi bir zamana denk düşer. saat çevrimlerine göre döngü hesaplarını ayrıca bir sayfada anlatacağım.