Buton Kontrollu Flas

Başlatan onurinci, 13 Aralık 2012, 04:39:58

onurinci

Hocam saygılar
bir LED stroboskop yapmaya çalıştım

http://www.dosya.tc/server24/5jkniX/FLASHLED.rar.html

intcon gp2' verene kadar bunaldım yardım istemeye karar verdim.

devreye enerji verdiğimizde herşey sakin hiçbir işlem yapmaması gerekiyor,
GP2 'deki butona birkez bastığımızda Led 1' nci senaryoya göre yanıp yönüyor

birkez daha bastığımızda 2 senaryoya atlıyor benim ayarladığım tablolama ile hızlanıyor.

4 senaryo mevcut
1 _ durgun hiçbir işlem yok
2 _ yavaş
3 _ hızlı
4 _ daha hızlı
bunun gibi.  son senaryoya gelene kadar herşey çalışıyor.butona bir kez bastığımda zincirin

halkası gibi ring atıp hiç bir işlem yok durumunda bekleyeceğine komaya girip kalıyor.

hata mesajları stack overflow ,gibi birde bunu son posisyonunu korusun diye eepromun 0'rıncı
adresine yazmaya çalışacaktım gemi şimdiden karaya oturdu..

@ Device pic12F675  ,MCLR_OFF , PROTECT_OFF , WDT_OFF , INTRC_OSC_NOCLKOUT , CPD_OFF , BOD_OFF , PWRT_ON 


PAUSE 100                ' discipline wait
TRISIO=%0000100        'sets GPIO.2 input , GPIO.1  output
GPIO=0                   ' clear Port
ON INTERRUPT GOTO DEGER

OPTION_REG.7 = 0    ' Enable weak pull-ups
IOC = %00000100     ' Enable interrupt on GPIO.2

INTCON = %10010000  'Enable GIE and INTE interrupt

CMCON = 7          'turns off comparator function [CMCON0=7]
ANSEL = 0          'no ADC input - IMPORTANT if using ports in digital mode
VRCON.7 = 0         'turns off voltage reference to minimize sleep current

WPU=0000100         ' ports GP2  to weak pull-up resistors 




   
EFEKT VAR  BYTE   '  word

'EFEKT=0





BASLA:
        WHILE EFEKT=0
            GPIO=%000000
        WEND
       
        WHILE EFEKT=1
            GPIO=%000000
            PAUSE 400
            GPIO=%000010
            PAUSE 400
        WEND
       
        WHILE EFEKT=2
            GPIO=%000000
            PAUSE 250
            GPIO=%000010
            PAUSE 250
        WEND
       
        WHILE EFEKT=3
            GPIO=%000000
            PAUSE 50
            GPIO=%000010
            PAUSE 50
        WEND
       
'clrwdt
       

               
GOTO BASLA   
DISABLE
DEGER:
       EFEKT=EFEKT+1
       PAUSE 1
       INTCON.1=0 
       RESUME BASLA     
   ENABLE
 
END
               
   


ete

#1
Kesme kullanılan programlarda PAUSE komutunun kullanılmaması gerektiğini henüz öğrenmemişsin.
Pause 400 uzun bir süre ve bu esnada sen GP2 deki butona bassan bile program ancak 400 ms sonra kesmeye gidecektir.
Buda uygulamada aksaklıklara sebep olur. O nedenle gecikmeleri döngü içinde kısa pauseus olarak vererek halletmeye çalış.
Enbüyük pause değer 5us olursa en fazla 5 komut çevrimi sonra program kesmeye atlar ve senin istediğini yapar.

Diğer önemli bir hata ise IOC kesmesi aktif ediyorsun ama GP2_INT kesmesi (Bir nevi PortB.0 kesmesi) kullanıyorsun.
INTCON değeri GP2_INT kesmesi kullanacak yönde verilmiş. KesMe oluştuğunda sıfırladığın bayrak da GP2_INT kesmesine ait.
O halde IOC=%00000100 komutunu kaldır yada ona sıfır değerini ver.

Bu arada programın başına
DEFINE OSCAL_1K 1
komutunuda ilave etmen gerek aksi taktide sistem OSCAL değerini kaybeder ve abuk subuk çalışmaya başlar. Bu sorun gerçek devre ile alakalıdır. İsisde sorun olmaz.
Malum işlemcinin $3FFF adresinde fabrikason kalibrasyon değeri yazılıdır. İŞlemci çalıştığında ordaki değeri alır ve OSCAL değeri olarak kulanır. Böylece fabrikadan kalibre ediliş dahili Osilatör doğru değerinde çalışır. Bu komut programlama esnasında mevcut değeri alıp programı yazdıktan sonra aynı yere aynı değeri tekrardan yazmayı sağlar. Komutu koymaz isen kalibrasyon değeri silinir ve picde rastgele bir frekansta çalışır ve seni yanıltır.

Ete

onurinci

hocam olmadı müdaheleniz gerekecek senaryoları yeniden düzenledim donanımı set edemediğimden şüpheliyim zira anatomik farklılıklar mevcut olduğunu biliyorum fakat 16F628 portb=0 kesmesinde kusursuz çalışıyor .
F628 örneği
TRISB=%00000001
PORTB=%00000000   
ON INTERRUPT GoTo DEGER 
OPTION_REG=%0000000   
INTCON=%10010000 
CMCON=7   
EFEKT VAR BYTE
i var byte
EFEKT=0
i=0
BASLA:


buda tavsiyelerinie göre düzenlemeye çalıştığım
@ Device pic12F675  ,MCLR_OFF , PROTECT_OFF , WDT_OFF , INTRC_OSC_NOCLKOUT , CPD_OFF , BOD_OFF , PWRT_ON 

DEFINE OSCAL_1K 1

PAUSE 100                ' discipline wait
TRISIO=%0000100        'sets GPIO.2 input , GPIO.1  output
GPIO=0                   ' clear Port
ON INTERRUPT GOTO DEGER

OPTION_REG.7 = 0    ' Enable weak pull-ups
IOC = %00000000     ' Enable interrupt on GPIO.2  00000100

INTCON = %10010000  'Enable GIE and INTE interrupt

CMCON = 7          'turns off comparator function [CMCON0=7]
ANSEL = 0          'no ADC input - IMPORTANT if using ports in digital mode
VRCON.7 = 0         'turns off voltage reference to minimize sleep current

WPU=0000100         ' ports GP2  to weak pull-up resistors 




   
EFEKT VAR  BYTE   '  word

i var byte
EFEKT=0
i=0



BASLA:
        WHILE EFEKT=0
            GPIO=%00000000   ' hiç bir şey yapma
        WEND
''''''''''''''''''senaryo 1       
        WHILE EFEKT=2
            for i=1 to 8
                GPIO=%000000
                PAUSE 5
                GPIO=%000010
                PAUSE 5
            next i
           
            for i=1 to 3
            GPIO=%000000
            PAUSE 5
            GPIO=%000010
            PAUSE 5
            next i
        WEND
       
''''''''''''''''''''''''senaryo 2         
        WHILE EFEKT=3
            for i=1 to 8
                GPIO=%000000
                PAUSE 5
                GPIO=%000010
                PAUSE 5
            next i
           
            for i=1 to 3
            GPIO=%000000
            PAUSE 5
            GPIO=%000010
            PAUSE 5
            next i
        WEND       
''''''''''''''''''''''sanki buradan goto'ya dallanma yok koma durumu var
       

               
GOTO BASLA   
DISABLE
DEGER:
       EFEKT=EFEKT+1
       PAUSE 1
       INTCON.1=0      '''' bunu yanlış yazmış olabilirmiyim
       RESUME BASLA     
   ENABLE
 
END
               
   

ete

#3
Birde şu komutu düzelt. Sanırım Dahili pullup ları aktif edemiyorsun.

WPU=0000100    yerine WPU=%00000100   yazman gerekiyor.

Ete

onurinci

denedim hocam önerilerinizi dikkate aldım .devre hiç çalışmıyor değil senaryolar ve program çalışıyor.
tabi bence .butonda vazife yapıyor birinci ikinci vs.. çalışıyor son senaryoya geldiğinde başa gideceğine sapıtıp kalıyor
pauseus ta denedim program bitiminde goto basla etiketini gördüğünde herşeyin o satırdan sonra başlaması gerekmiyormu..??

ete

Bir kusur daha var programda.
Kesmeye girildiğinde ,
       EFEKT=EFEKT+1
şeklinde efekt değeri bir artırılıyor. Peki bir kere bastım efekt=1 oldu. Tekrar bastım efekt=2 oldu tekrar bastım efekt=3 oldu. Sonra birdaha basarsam efekt=4 olacak. Hani bunun sınırlaması.  Yok tabiiki . Olmayınca 250 defa daha basmanlazımki efekt=0 olabilsin ve tekrardan program iş görebilsin. Sorun asıl kaynağı budur sanırım.
Yukardaki efekt artırma satırının altına
       IF EFEKT=4 then efekt=0
satırını ilave et sorun düzelsin.

Ete

onurinci

hocam saygılar herhzamanki gibi  altın vuruşu yaptınız kusursuz çalışıyor.
son hali bu  işimi gördüm fakat merak etmeden edemeyeceğim
''''''''''''''''''''''''''''''''''''''''''''''''''''''
            for i=1 to 2
                GPIO=%000010
                pause 1000
                GPIO=%000000
                pause 1000
            next i
''''''''''''''''''''''''''''''''''''''''''''''''''''
burada for i=1 to 2  normalde 2 rakamını 4 yaptığımda sürenin uzaması lazım hiç reaksiyon yok

yanlış yazsam mcs'nin uyarması gerek değişkeni byte yaptım word'te yaptım yine bir şey yok.
burada bir altın öğdünüzü buldum uygulamada cevap alamadım acaba (while wend) arasında işe yaramıyormu???
öğüt===
Kesme kullanılan programlarda Pause komutunu kullanmaktan kaçının.
Zira pause komutu işletilirken kesme oluşsa bile pause süresi bitmeden program kesme etiketine gidemez.
Bunun çaresi bekletmeleride kesme altına almak yada döngüsel bekletme kullanmaktır.
Pause 200 yerine
For I=1 to 200
Pause 1
next
derseniz yine yaklaşık 200 ms lik gecikme yaratır ama kesmeye gitmek için en fazla 1 ms beklersiniz.
Ama Pause 200 dediğiniz zaman 200 ms dolmadan kesme etiketine gidemezsiniz.
Bu nedenle pause yerine pauseus kullanmaya bakın ve en büyük değerinizde 5us olsun. Bunu döngü içinde kullanarak gerekli gecikmeyi sağlayın . Ama unutmayın döngü komutları da her biri 5us den fazla bir gecikme yaratır. Bu nedenle 200 ms lik gecikme için 200.000/5=40000 hesaplayıp döngüyü for I=1 to 40000 şeklinde kurarsanız 200 ms değil 800 ms gecikme sağlarsınız. Biraz deneyerek gerçek zamanı yakalamak için I değerinin ne olmasını bulabilirsiniz.
Genelde vermeniz gereken değerin yarısından biraz eksiğini verin.

buda işim görülsün diye programın son hali
@ Device pic12F675  ,MCLR_OFF , PROTECT_OFF , WDT_OFF , INTRC_OSC_NOCLKOUT , CPD_OFF , BOD_OFF , PWRT_ON 

DEFINE OSCAL_1K 1

PAUSE 100                ' discipline wait
TRISIO=%0000100        'sets GPIO.2 input , GPIO.1  output
GPIO=0                   ' clear Port
ON INTERRUPT GOTO DEGER

OPTION_REG.7 = 0    ' Enable weak pull-ups
IOC = %00000000     ' Enable interrupt on GPIO.2  00000100

INTCON = %10010000  'Enable GIE and INTE interrupt

CMCON = 7          'turns off comparator function [CMCON0=7]
ANSEL = 0             'no ADC input - IMPORTANT if using ports in digital mode
VRCON.7 = 0             'turns off voltage reference to minimize sleep current

WPU=%00000100           ' ports GP2  to weak pull-up resistors 




   
EFEKT VAR  byte
Led    var GPIO.1
i var byte'byte




BASLA:

''''''''''''''''''''''''''senaryo 0       
        WHILE EFEKT=0
   
                high Led
                pause 500
                low Led
                pause 500

           

        WEND

''''''''''''''''''''''''senaryo 1       
        WHILE EFEKT=1
                high Led
                pause 400
                low Led
                pause 400

        WEND
       
''''''''''''''''''''''''senaryo 2         
        WHILE EFEKT=2
                high Led
                pause 300
                low Led
                pause 300
           

        WEND       
''''''''''''''''''''''senaryo 3
        WHILE EFEKT=3
                high Led
                pause 200
                low Led
                pause 200
        WEND       
''''''''''''''''''''''senaryo 4
        WHILE EFEKT=4
                high Led
                pause 100
                low Led
                pause 100
        WEND
       
GPIO=0 'temizlik yap
                       
GOTO BASLA
 
DISABLE
DEGER:
       EFEKT=EFEKT+1
        IF EFEKT=5 then efekt=0
       PAUSE 1
       INTCON.1=0     
       RESUME BASLA     
   ENABLE
 
END
               
   

ete

İşini görmüşsün ancak hala pause ler programda duruyor. Ben olsam onları kaldırırdım.
Verdiğin döngü 1to2 olrak 2 defa çalışacak bir döngü. 4 yaparsan 4 defa çalışması gerekir.
Fark yok dediğine göre program oraya hiç ulaşmıyor bence. Bu nedenle programın bütününe bakmak gerekir.

Ete

onurinci

Hocam saygılar
Tavsiyeleriniz üzere Pause sürelerinde değişiklik yaptım ,isis'te çalışıyor
nadiren butona basarken 50 keredede bir kere hata oluşuyor aşağıdaki hata counteri habire sayıyor, Return call stack mesajı veriyor normal işlemciye programı atsam ara sıra pic'in bloke olabileceğine bir işaretmidir bu hata ?.

@ Device pic12F675  ,MCLR_OFF , PROTECT_OFF , WDT_OFF , INTRC_OSC_NOCLKOUT , CPD_OFF , BOD_OFF , PWRT_ON 

DEFINE OSCAL_1K 1

PAUSE 100                ' discipline wait
TRISIO=%0000100        'sets GPIO.2 input , GPIO.1  output
GPIO=0                   ' clear Port
ON INTERRUPT GOTO DEGER

OPTION_REG.7 = 0    ' Enable weak pull-ups
IOC = %00000000     ' Enable interrupt on GPIO.2  00000100

INTCON = %10010000  'Enable GIE and INTE interrupt

CMCON = 7          'turns off comparator function [CMCON0=7]
ANSEL = 0             'no ADC input - IMPORTANT if using ports in digital mode
VRCON.7 = 0             'turns off voltage reference to minimize sleep current

WPU=%00000100           ' ports GP2  to weak pull-up resistors 




   
EFEKT VAR  byte
Led    var GPIO.1
x var word
y var word



BASLA:
GPIO=0                   ' clear Port


'''''''''''''''''''''' Senaryo 0       
While EFEKT=0
         
    For x=1 To 1000
             
        High LED
        Pause 1
        Next x
             
    For y=1 To 1000
           
        Low LED
        Pause 1
        Next y

Wend

'''''''''''''''''''''' Senaryo 1       
While EFEKT=1
       
    For x=1 To 750
             
        High LED
        Pause 1
        Next x
             
    For y=1 To 750
           
        Low LED
        Pause 1
        Next y

Wend

'''''''''''''''''''''' Senaryo 2         
While EFEKT=2
       
    For x=1 To 500
             
        High LED
        Pause 1
        Next x
             
    For y=1 To 500
           
        Low LED
        Pause 1
        Next y

Wend
       
'''''''''''''''''''''' Senaryo 3
While EFEKT=3
       
    For x=1 To 250
             
        High LED
        Pause 1
        Next x
             
    For y=1 To 250
           
        Low LED
        Pause 1
        Next y
       
Wend
             
'''''''''''''''''''''' Senaryo 4
While EFEKT=4
       
    For x=1 To 125
             
        High LED
        Pause 1
        Next x
             
    For y=1 To 125
           
        Low LED
        Pause 1
        Next y
       
Wend
       
'''''''''''''''''''''' Senaryo sonu
       
GPIO=0                   ' clear Port
                       
GOTO BASLA
 
DISABLE
DEGER:
       EFEKT=EFEKT+1
        IF EFEKT=5 then efekt=0    'Birinci rakam maximum efekt sayısı
       PAUSE 1
       INTCON.1=0     
       RESUME BASLA     
   ENABLE
 
END
               
   


ete

Hala programında yanlışlıklar var. Hata oluşmasının sebebi RESUME BASLA satırı. Bu nedenle orayıda düzeltmek gerekiyor.
Epeyce uğraştın. Programın olması gereken halini aşağıda veriyorum. Bak ve hatalarından kendine ders çıkart.
Bu programı simulasyonda deniyorum sorunsuz çalışıyor.
Bu arada belki sana yabancı gelebilecek bir komut göreceksin  " != " bu eşit değilse anlamına geliyor. "<>" ile eşdeğer bir ifadedir.
Bazı şeylere değinmeden geçemeyeceğim. Bir döngü kurmuşsun
    For x=1 To 1000             
        High LED
        Pause 1
        Next x
şeklinde , saba yalnızca bir kere HIGH LED komutu lazım iken döngü içinde bunu 1000 defa yineliyorsun. Gerek varmı?. Boşuna zaman kaybına ve komut gecikmesine sebep oluyor. Bir kere HIGH led deyip sonra döngüyü kursan yine değişen bir şey olmayacak. Ama komut yalnızca bir kere işletilmiş olacaktır.
Sana söylemiştim PAUSE yerine PUSEUS yani mikrosaniye kullan ve miktarda 10 us yi geçmesin. Sen yinede Pause 1 kullanmışsın bu gecikme kesme için hala yüksek bir değer ifade eder. O nedenle gecikmeleri 10us seviyesine düşürdüm.
Üstelik bunları karışmasın diye alt program halinde yaptım doğrusuda budur.

Ete

@ Device pic12F675  ,MCLR_OFF , PROTECT_OFF , WDT_OFF , INTRC_OSC_NOCLKOUT , CPD_OFF , BOD_OFF , PWRT_ON 

DEFINE OSCAL_1K 1

               ' discipline wait
TRISIO=%0000100        'sets GPIO.2 input , GPIO.1  output
GPIO=0                   ' clear Port
ON INTERRUPT GOTO DEGER

OPTION_REG.7 = 0    ' Enable weak pull-ups
IOC = %00000000     ' Enable interrupt on GPIO.2  00000100

INTCON = %10010000  'Enable GIE and INTE interrupt

CMCON = 7          'turns off comparator function [CMCON0=7]
ANSEL = 0             'no ADC input - IMPORTANT if using ports in digital mode
VRCON.7 = 0             'turns off voltage reference to minimize sleep current

WPU=%00000100           ' ports GP2  to weak pull-up resistors 

EFEKT VAR  byte
Led    var GPIO.1
x var word
y var word

PAUSE 500

BASLA:
GPIO=0                   ' clear Port


'''''''''''''''''''''' Senaryo 0       
While EFEKT=0                 
        High LED
        GOSUB BESYUZ                     
        Low LED
        GOSUB BESYUZ
Wend

'''''''''''''''''''''' Senaryo 1       
While EFEKT=1
        High LED
        GOSUB DORTYUZ
        Low LED
        GOSUB DORTYUZ
Wend

'''''''''''''''''''''' Senaryo 2         
While EFEKT=2     
        High LED
        GOSUB UCYUZ
        Low LED
        GOSUB UCYUZ             
Wend
       
'''''''''''''''''''''' Senaryo 3
While EFEKT=3
        High LED
        GOSUB IKIYUZ
        Low LED
        GOSUB IKIYUZ
Wend
             
'''''''''''''''''''''' Senaryo 4
While EFEKT=4
        High LED
        GOSUB YUZ
        Low LED
        GOSUB YUZ
Wend
       
'''''''''''''''''''''' Senaryo sonu
       
GPIO=0                   ' clear Port
GOTO BASLA


BESYUZ:
       FOR X=0 TO 10000
         PAUSEUS 10
         IF EFEKT>0 THEN RETURN
       NEXT
       RETURN
       
DORTYUZ:
       FOR X=0 TO 7500
         PAUSEUS 10
         IF EFEKT !=1 THEN RETURN
       NEXT
       RETURN

UCYUZ:
       FOR X=0 TO 5000
         PAUSEUS 10
         IF EFEKT !=2 THEN RETURN
       NEXT
       RETURN       
       
IKIYUZ:
       FOR X=0 TO 2500
         PAUSEUS 10
         IF EFEKT !=3 THEN RETURN
       NEXT
       RETURN             

YUZ:
       FOR X=0 TO 1250
         PAUSEUS 10
         IF EFEKT !=4 THEN RETURN
       NEXT
       RETURN                               
 
DISABLE
DEGER:
       EFEKT=EFEKT+1
        IF EFEKT=5 then efekt=0    'Birinci rakam maximum efekt sayısı
       INTCON.1=0     
       RESUME     
       ENABLE
  END


onurinci

Hocam vaktinize emeğinize sağlık ,hem problemim çözüldü hemde Gosub kullanımını pratik olarak öğrendik.

not= Pauseus yapmayı denemedim kendimce intcon kesmesini kaçırabilirim diye saplantıya düştüm ,demekki öyle değilmiş buda bir ders tekrar teşekkürler hocam sağlıklar dilerim..

Powered by EzPortal