Program döngüde kalıyor?

Başlatan veli, 17 Şubat 2018, 18:17:27

veli

arkadaşlar devreyi kurdum program normal çalışıyor fakat belli bir palsin üstünde geldiğinde kes isimli etikete gidiyor işlemini yapıyor fakat şart bozulduğunda bu döngüden çıkamıyor  nerdeyse tüm günümü aldı yinede olmadı yardım edebilir misiniz?(pic16f870)
 @ __config _HS_OSC & _WDT_OFF & _PWRTE_OFF & _LVP_OFF & _CP_OFF

DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT  3
DEFINE LCD_RWREG    PORTB
DEFINE LCD_RWBIT      2
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 1
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2

ADCON1=7
   
OKUNAN_FREKANS VAR WORD

     
    TRISA=%010000
    TRISB=%00000000
    TRISC=0
   
   symbol led=porta.0
   symbol led1=porta.1
   symbol led2=porta.2
   symbol led3=porta.3
   symbol led4=porta.5
   symbol led5=portc.0
   symbol led6=portc.1
   
   SYMBOL GIRIS=PORTA.4

   
 
   PORTA=0
   portb=0
   portc=0
   OKUNAN_FREKANS=0
   PAUSE 200
   
   basla:
                     
  COUNT GIRIS,1000,OKUNAN_FREKANS
   
  LCDOUT  $FE,$80,"motordevri ",#OKUNAN_FREKANS*4*60/2,"  "
  LCDOUT  $FE,$C0,#OKUNAN_FREKANS," ham deger       "
                                                           
   IF OKUNAN_FREKANS=>33 THEN
   high led
   else
   low led
   endif
   
   IF OKUNAN_FREKANS=>37 THEN
   high led1
   else
   low led1
   endif

   IF OKUNAN_FREKANS=>41 THEN
   high led2
   else
   low led2
   endif

   IF OKUNAN_FREKANS=>46 THEN
   high led3
   else
   low led3
   endif
   
   IF OKUNAN_FREKANS=>50 THEN
   high led4
   else
   low led4
   endif

   IF OKUNAN_FREKANS=>54 THEN
   high led5
   else
   low led5
   endif

   IF OKUNAN_FREKANS=>58 THEN
   high led6
   else
   low led6
   endif

kesici:
  IF OKUNAN_FREKANS=<59 THEN goto basla
  IF OKUNAN_FREKANS=>60 THEN
 
   high led6:high led5:high led4:high led3:high led2:high led1:high led:high portc.2
   pause 50
   low led6:low led5:low led4:low led3:low led2:low led1:low led:low portc.2
   pause 50
   endif
   IF OKUNAN_FREKANS=>60 THEN goto kesici
   IF OKUNAN_FREKANS=<59 THEN goto basla 
   
 
   goto basla
   end               
   
   
                           
   

F®T

Kes bir etiket ama nerden kes etiketine atlama yapıyor.Ayrica farklı etiketlerde var alt programları yok.Yada ben göremedim.
"Hakk" şerleri hayr eyler Zannetme ki gayr eyler Ârif anı seyreyler Mevlâ görelim neyler Neylerse güzel eyler.

veli

Kesici olacak o yanlislik olmuş kardes ya etiket ismi kesici yani ama yinede olmuyor

ete

Olmaz çünki programı Kesici etiketine kilitlemişsin.
Birlikte düşünelim, Okunan_Frekans<59 olduğu müddetçe program kesici etiketi ile goto başla komutları arasında dönüp duracaktır. Bunu sağlayan 2 komut satırı var.
   IF OKUNAN_FREKANS=>60 THEN goto kesici
   IF OKUNAN_FREKANS=<59 THEN goto basla
Burada tek satır olsa yeterli olurdu biri lüzümsuz . Neden basit. Sistemde yalnızca 3 olasılık konumu söz konusu,
1. Okunan Frekans<60
2. Okunan Frekans=59 ki bu zaten yukarıdaki 1 konuma giriyor
3. Okunan Frekans>59
O halde oraya iki satır yerine yalnızca,
IF OKUNAN_FREKANS<60 then BASLA yazmış olsan yeterli oalcak idi. Zira şayet Okunan frekans=60  veya üzeri olunca program IF satırını atlayıp Kesici etiketine gelecek idi.

Şimdi gelelim asıl soruna Kesici etiketi içinde şu satıra dikkatini çekerim;
IF OKUNAN_FREKANS=>60 THEN goto kesici
Kesici etiketine gelme sebebin zaten Okunan Frekansın 59 dan büyük olması idi. Peki bu etiket içinde Okunan Frekansın değişebilme ihtimali varmıdır? bence yok çünki okunan frekansı yeniden belirlemenin yolu programı başla satırına yollayarak yeniden Count komutundan geçirmektir. O halde zaten Okunan Frekans>59 olduğu için program hep kesici etiketi içinde çakılıp kalacaktır.
Yapılacak düzeltme şöyle olmalı;
Kesici etiketinin sonundaki o iki satırı kaldır ve program oradan direk Goto basşla ile başla etiketine gidip yeniden frekans saysın.

Ete

veli

Hocam cevabın için teşekkür ederim aslında ilk yaptığım program senin dediğin gibiydi ama böyle yapınca buzzer ve ledler 50 ms aralıkla yanıp sönünce program başa dönüyor haliyle bir daha yanıp sönmesi count komutundaki 1000 den dolayı 1 saniye alıyor buda istenmeyen bir durum bu şekilde yaptığım zaman yanıp sönme işlemi sürekli hale geliyor fakat o zamanda orada kitleniyor işte ama kitlenme sebebini anladım peki nasıl yaparız hocam bunu
@ __config _HS_OSC & _WDT_OFF & _PWRTE_OFF & _LVP_OFF & _CP_OFF

DEFINE LCD_DREG PORTB
DEFINE LCD_DBIT 4
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT  3
DEFINE LCD_RWREG    PORTB
DEFINE LCD_RWBIT      2
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT 1
DEFINE LCD_BITS 4
DEFINE LCD_LINES 2

ADCON1=7
   
OKUNAN_FREKANS VAR WORD

     
    TRISA=%010000
    TRISB=%00000000
    TRISC=0
   
   symbol led=porta.0
   symbol led1=porta.1
   symbol led2=porta.2
   symbol led3=porta.3
   symbol led4=porta.5
   symbol led5=portc.0
   symbol led6=portc.1
   
   SYMBOL GIRIS=PORTA.4

   
 
   PORTA=0
   portb=0
   portc=0
   OKUNAN_FREKANS=0
   PAUSE 200
   
   basla:
                     
  COUNT GIRIS,1000,OKUNAN_FREKANS
   
  LCDOUT  $FE,$80,"motordevri ",#OKUNAN_FREKANS*4*60/2,"  "
  LCDOUT  $FE,$C0,#OKUNAN_FREKANS," ham deger       "
                                                           
   IF OKUNAN_FREKANS=>33 THEN
   high led
   else
   low led
   endif
   
   IF OKUNAN_FREKANS=>37 THEN
   high led1
   else
   low led1
   endif

   IF OKUNAN_FREKANS=>41 THEN
   high led2
   else
   low led2
   endif

   IF OKUNAN_FREKANS=>46 THEN
   high led3
   else
   low led3
   endif
   
   IF OKUNAN_FREKANS=>50 THEN
   high led4
   else
   low led4
   endif

   IF OKUNAN_FREKANS=>54 THEN
   high led5
   else
   low led5
   endif

   IF OKUNAN_FREKANS=>58 THEN
   high led6
   else
   low led6
   endif


   IF OKUNAN_FREKANS=>60 THEN
 
   high led6:high led5:high led4:high led3:high led2:high led1:high led:high portc.2
   pause 50
   low led6:low led5:low led4:low led3:low led2:low led1:low led:low portc.2
   pause 50
   endif
 
   goto basla
   end               

ete

Anladığım kadarı ile frekans kesintiye uğramadan ölçülsün ledlerde kesintisiz flash yapması gerekiyor ise flash yapsın istiyorsun. Bunun cevabına geçmeden önce aşağıdaki açıklamayıda okumanı öneririm.

Programın amacı ölçülen frekans 59 dan büyük ise ledleri flash yaptırmak  onuda senin yazdığın gibi yapmakda fuzuli bir iş ya neyse. Yinede açıklamadan geçemeyeceeğim.
HIGH LED1 demekle programı şu işi yapıyor.
OUTPUT LED1
LED1=1
Yani bir taşla iki kuş. Şayet aynı LED1 pini bir input bir output olacaksa bu komut uygun ama bunun doğrusu LED1=1 şeklinde dir. Daha az yer kaplar işlemciyi daha az meşgul eder.
Diğer taraftan PORTA.0-PORTA.5 aralığındaki pinlere bağlı ledleri HIGH yapmaının yolu, onları teker teker high yaparak olmamalıdır. 
Şu kadar komut yerine (high led6:high led5:high led4:high led3:high led2:high led1:high led:high portc.2)
PORTA=%00101111:PORTC.2=1  demen yeterli idi.
AYnı şekilde ledleri söndürüken de PORTA=%00000000:PORTC.2=0 demen yeterli.

Şimdi asıl meseleye gelir isek;
Bu işin yolu frekans saydırmayı geri planda yapman gerekiyor. Yani sen bir önceki saydırma sonucu elde ettiğin veriye göre ledlere flash yaptırırken geri planda frekans da saymasına devam etmeli. 1sn lik tutulan zamanların sonucunda ledlerin flash yapıp yapmamasına karar verip tekrar saydırmayı aktive etmelisin.
Geri planda frekans nasıl saydırılır? 3 farklı yolu var. Ama bu 3 yolun birisi INT (PORTB.0) kesmesi kullanmaya bakıyor. Diğer ikisi ise TMR ları (TMR0 veya TMR1) harici girişten pals sayacak şekilde ayarlayıp zaman tutmaya dayanıyor.
He riki sayac da harici girişten gelen pulsleri sayacak şekilde ayarlanabilir. TMR0 sayacı PORTA.4 pinini kullanır. TMR1 sayacı ise 18 pin işlemciler PORTB.6 pininden 28 pin işlemcilerde PORTC.0 pininden giriş yaparak sayabilir.
Bu işin zor tarafı hem zaman tutup hem flash için gecikme kullanmak hemde frekansı aynı anda yapabilmekte. Ama işin kolayıda şöyle olabilir.
Frekans değerin düşük olduğu için TMR0 sayacını frekans saymakta kullanırım.
TMR1 sayacınıda 250 ms lik 4 dilim halinde çalıştırırp her bir dilimide ledlerin flash yapmasında konum değiştirme süresi olarak kullanırım. İŞlem sırası şöyle olabilir.
- Tmr0 harici kaynaktan puls sayacak şekilde organize edildi. (OPTION Registeri 5 nolu biti bunu ayarlıyor)
- TMR1 sayacı ise 250 ms lik gecikme yaratacak şekilde T1CON registeri ve TMR1 sayacına ön yükleme değeri verilerek ayarlandı.  TMR0 sıfırlanıp saydırma başladı.
- 250 ms sonunda PIR1.0=1 olacaktır buna bakarak 250 ms geçip geçmediğini kolaylıkla anlarsın.
250 ms sonunda şayet flash yaptırılacak bir şey var ise  onları toggle yaparsın.
- 4 adet 250 ms geçip geçmediğini sayarsın (4x250=1000 ms yani 1 sn edecektir)
Böylece 1000 ms geçmiş ise Frekans=TMR0 diyerek oradaki değeri frekans değişkenine aktarırsın.
Hesabını yapar ekrana verilecekleri ayrıca 250 ms lik dilimler arasında gösterirsin.
Hepsi bu .

Powered by EzPortal