Hoşgeldiniz!

Kayıt olarak, topluluğumuzun diğer üyeleri ile görüşebilir, paylaşabilir ve özel mesaj gönderebileceksiniz.

Şimdi Kayıt Ol!

Assembly de Gecikme döngüleri ve hesapları

Katılım
9 Kas 2019
Mesajlar
1
Beğeniler
3
#1
Assembly de genel olarak iki çeşit gecikme döngü şablonu bulunur

1, ard arda gecikme döngüleri

örnek:



4 Mhz klistalde 4/1= pic sistem saatini dörde böldüğü için 4Mhz lik klistal için, 1Mhz hızda çalışır. Nasıl mı?

her bir çevrim sistem saatinin 1/4 dünü kullanır, Bu da her bir komut çevriminin , 1sn/1Mhz= her bir saykıl 1 us saniye sürer


Kod:
call   dongu           ; call çağrısı 2 çevrim yapar, eğer gecikme döngülerinin tam olması gerekiyor ise tüm komutların süreleri toplanır




dongu:                            ; buraya kadar 2 saykıl oldu




movlw        .10              ; bu komut 1 saykıl sürer


movwf        cnt0            ; bu işlemde 1 saykıl sürer , şimdiye kadar (2 call)  +(2 ilk değer yüklenmede)


dongu_1:                       ; şimdiye kadar 4 saykıl oldu ve döngünün sonunda return komudu olduğu için 4+2=6 saykıl şimdiden kullanmış oluruz




decfsz        cnt0,1        ;cnt0 ya 10 sayısı yükledik, kısaca döngü 10 defa dönecektir


goto           dongu_1    ;yalnız döngü son turda decfsz komutunun şartına uyduğu için jumping yapacaktır ve goto komudunu atlayacağından


return                           ; son döngüde 2 saykıl sürecektir,formur ((yüklenen değer-1)x3+(son değer 2 saykıl)


                                      ;kısaca (9x3+2)=29 saykıl+ (6) daha önce hesapladığımız komutlar)

özet (2 call) +(2 movlw, movwf)+(9x3+2)+(2 return)=35us lik bir döngümüz



peki , 100us lik bir döngü nasıl hesaplanır



çözüm:

önce frekansımızdan saykıl süresini buluyoruz,

20Mhz için 20,000,000/4=5,000,000, (1 saniye= 1,000,000us)/(5,000,000hz=5Mhz)=0.2 us=200ns

4 Mhz için , 4000 000/4= 1000 000= (1 saniye= 1000000us)/(1000000hz=1Mhz)=1 us



komut saykıl süresinin hesaplanması yukarıdaki gibidir

önce sistem saatin frekansını dörde bölüyoruz, çıkan sonucu saniyeye böldüğümüzde bize saykıl süresini verir



4 Mhz için



1sn/(4Mhz/4)=1us



100us/1us=100 saykıl sürer



(2 call + 2 ön değer + 2 return) 100-6=94 saykıl kaldı



94-(son tur 2 çevrim olduğu için, çıkarıp, sonra +1 döngü olarak ekliyoruz)







92/3=30 sağlaması 30*3=90

92-90 =2 +Nop



30+(1 son döngüyü önceden çıkardığımız için ekliyoruz)


formulumuz((31-1)*3+2) = 30*3+2=92

94-92=2 kalan eksik saykıl bize nop olarak eklenecektir



Kod:
call     delay_100us


delay_100us:                            ; +   2 call


movlw   .31                               ;+    1


movwf   cnt0                            ; +    1


dongu_0:                                   ;


decfsz  cnt0,1                           ;+     (30x3+2=92)    döngüden hesap bulma formürü


goto    dongu_0                        ;


nop                                             ;+     1


nop                                             ;+     1


return                                         ;+      2         92+2+1+1+1+1+2= Tam 100 us 4Mhz için, 500us 20Mhz için
Sanırım yukarıda döngülerin hesaplanmasını ve kullanılmasını açıkca anlatmış oldum
döngüye eğer ilk değere 1 verirsek o zaman 1-1x3+ (çıkan değer =2) = 2 saykıl sürer
eğer 5 değeri verirsek 4*3+2=14

Peki , 0 değeri verirsek ne olur? Önce biraz düşün döngü sayımız kaç olur? tahmininizi bekliyorum...

Düşündüğünüzü varsayıyorum, eğer düşünmeden bu bölüme geçtiyseniz
bundan sonraki bölümleri anlayamayacaksınız, çünkü işler daha karışacak, üst bölümleri tekrar edin...



Düşünmekten ve hata etme korkusundan korkmayalım, saçmada olsa ettiğiniz tahmin, çok önemlidir
çünkü hafıza daha doğrusu öğrenmek ve anlamak bir bitkinin daha doğrusu tohumun çimlenmesine benzer
eğer filiz bir seferde yüzeyi bulabilmiş olsaydı, derinlemesine sarılmış köklere sahip olamazdı,
bir ağacın büyüklüğü nasıl köklerine oranlıysa, başarının büyüklüğüde yapılan hatalara oranlıdır
Sanırım anlaşılmıştır



Çözümü;

eğer değeri sıfır olarak atarsanız, decfsz komutu, önce düşürdüğü ve sonra z bayrağına baktığı için

değerimiz 256 olacaktır, Burası çok önemli çünkü iç içe geçmiş döngüler ilk döndüklerinde verilen değer üzerinde

sonraki her dönüşlerde cnt0=0 olacağından, ilk hariç her döngü 256 olarak hasaplayacağız





Soru, 50 us saniyelik gecikme döngüsü kendiniz yapmaya çalışınız?


Çözüm1; fonksiyon çağlısı olarak kullanımı


Kod:
delay_50_us:            ;Not: gecikme döngülerini ayrı fonksiyon olarak yazarken call ve return ü hesaba dahil ediyoruz,


movlw      .15            ;Eğer program satırında kullanacaksak o zaman dahil etmiyoruz


movwf     cnt0          ;


dongu_0:                   ;50-6=44       (44-2 son tur)       42/3 =14   sağlaması      14+(1 son tur bir döngü olarak ekleniyor, önceden çıkardığımız için)


decfsz   cnt0,1         ;


goto       dongu_0    ;+2+1+1 (14*3+2=44)+2=50us


return                        ;

Çöüzüm2 program sırasına eklenerek kullanım



50-4=46 ;not call ve return dahil edilmiyor

46/3=15 sağlaması 15*3=45

46-45=1+Nop

15+1

cnt0=16



Kod:
movlw   .16


movwf   cnt0


dongu_0:


decfsz cnt0,1


goto  dongu_0


nop
(15*3+2=47)+3= 50us

2 iç içe geçen döngüler
altta yazdığım kalıpları öğreniniz,


Minmun döngüde gecikme;

Kod:
movlw    .1    ;

movwf     cnt0    ;(1-1*3+2)

dongu_0        ;=2+ 2 öndeğer

decfsz   cnt0,1    ;

goto dongu_0    ; min= 4 saykıl
maximum döngüde gecikme
1 ön değer verelek ilk döngüde max gecikme

Kod:
movlw    .0    ;

movwf      cnt0    ;(256-1*3+2)=767

dongu_0        ;

decfsz  cnt0,1    ;767+2ön değer

goto    dongu_0    ; max = 769
2 döngü içinde max gecikme, ön değer 0 ,kısaca ilk dışındaki her döngü


Kod:
dongu_0        ;

decfsz  cnt0,1    ;(256-1*3+2)=767

goto    dongu_0    ; max = 767  Not: bu döngü içindekilerini 256 kere döndülür yani 256 ya çarpar

Soru Tam 1 saniye gecikme yapacak gecikme döngüsü yapınız?

Çözümü;

1sn=1000 000us
2+ call,2+return
=999996


Kısaca proğramımız....


Kod:
delay_1sn

movlw    .0             ;

movwf    cnt0        ; 5*(256*(255*3+2)+767=197119) + (4*3+2=14)

movlw    .0             ;

movwf    cnt1        ;=985609 +6 ön değer

movlw    .5             ;

movwf  cnt2          ;=985615


dongu_0:                ;

decfsz    cnt0,1      ;

goto dongu_0        ;

decfsz    cnt1,1      ;

goto dongu_0        ;

decfsz    cnt1,1      ; 14385-2 call

goto dongu_0        ;kalan 14383



movl        .18        ;

movwf     cnt1     ;18*(255*3+2=767)+(17*3+2=53)+4=

movl        .0          ;=13863

movwf     cnt0     ;14383-13863

dongu_1:             ;

decfsz    cnt0,1   ;

goto dongu_0     ;

decfsz    cnt1,1   ;

goto dongu_1     ;kalan=520


movlw    .173     ;

movwf    cnt0     ;172*3+2=518

dongu_2             ;

decfsz  cnt0,1    ;

goto dongu_2    ;

return                  ;+2 =520  TAM 1000000 us =1sn lik tam hesaplı gecikme döngüsünü inceleyiniz
çıkabilecek en büyük değerleri çıkartın ve kalan lar için de her bir gecikme döngüsünü ayarlayın,
yukarıdaki örneğimizde nop kullanılmamıştır
767 çevrim yapar nop suz maxsimum
döngü arasına +1Nop koysaydık
767+256=1023 ü elde ederdik, daha kısa yazılımlar
yazmak için , büyük gecikmelerde nop kullanmak avantajlıdır
her bir Nop + 256 çevrim eder

örnek 2;
Tek nop lu döngü

Kod:
dongu_0:                ;255*(3+1 Nop=4)+3

nop                          ;

decfsz    cnt0,1      ;(255*4+3)=1023 saykıl

goto dongu_0        ;


İKi Noplu


dongu_0:                ;255*(3+2 Nop=4)+3

nop                          ;

nop                          ;

decfsz    cnt0,1      ;(255*5+4)=1279 saykıl

goto dongu_0        ;


gecikme döngüleri boş işler için zamanlama gereken durumlarda kullanıldığı gibi, aynı zamanda senkronizenin olduğu durumlarda
çift işlem olarakta kullanılabilir, bu durumda üst seviyeli diller in yapamadıkları çoklu senronizeli görevler yapabilirsiniz, mesela tam 100ms beklmemeniz
ve bu beklemeyi boş geçiktirmek yerine aynı süre içerisinde başka işlemlerde yapabilirsiniz, hadda daha complexli yazılımlar bile yaratabilirsiniz
gecikme döngüleri hazırlarken, zamanlamayı tam olarak sağlayınız, bu ilerde daha profesyonel olmak yolunda büyük kolaylık sağlayacaktır
 
Moderatör tarafında düzenlendi:
Üst Alt