BU YAZILIMDA HATA VARMI

Başlatan toprak, 17 Ağustos 2011, 14:31:30

toprak

Bir zamanlayici programi yzdim fakat calismadi  sanirsam kesmeye gitmiyor yada bir kez tek gidiyor.bu neden kaynaklaniyor olabilir.
@	device  pic12F675, intrc_osc_noclkout, wdt_off, pwrt_on, mclr_off, protect_off	

DEFINE ADC_BITS 10       ' ADC 10 bit kullanýlacak
DEFINE ADC_CLOCK 3      ' ANSEL.4  ANSEL.5  ANSEL.6 yý ayarlar
DEFINE ADC_SAMPLEUS 50  ' örnekleme 
define OSC 4            ' Çalýþma frekansý
define osccal_1k 1
TRISIO = %000111      ' giriþ çýkýþ atamasý

CMCON = %00000111       ' Giriþlerdeki Comparatorlar kapalý
ANSEL=0 
ANSEL.0=%1          ' GPIO.1, GPIO.0 ,GPIO.2 Analog secildi, diðerleri digital
ANSEL.1=%1        
ANSEL.2=%1
ANSEL.3=%0

ADCON0.7=1          ' 8 bit doðru okumak için sola yaslanmýþ (10 bitin son (LSB) 2 biti kullanýlmýyor) 
ADCON0.6=0  

INTCON=%10000000
ON INTERRUPT GOTO KESME

TUS VAR WORD
DAK VAR BYTE
ZAMAN VAR BYTE
STUN1 VAR WORD
STUN2 VAR WORD
STUN3 VAR WORD
SAYAC VAR BYTE
SURE VAR BYTE
SN VAR BYTE
I VAR BYTE      
clear
PAUSE 100
 GPIO=0
BASLA:GPIO.5=0:GPIO.4=0
IF SURE<>0 AND DAK=SURE THEN
GPIO.5=1:PAUSE 200:GPIO.5=0
ENDIF 
  adcin 0,STUN1
  'if STUN1>=199 AND STUN1<397 THEN
     'GPIO.5=1:PAUSE 200:GPIO.5=0
     'endif
    if STUN1>=199 and STUN1<397 THEN TUS=1:goto DONGU
    if STUN1>=397 and STUN1<600 then TUS=4:goto DONGU
    if STUN1>=600 and STUN1<802 then TUS=7:goto DONGU

    if STUN1>=802 and STUN1<1000 then   '* tusuna basilirsa
    GPIO.4=1:PAUSE 200:GPIO.4=0:PAUSE 100
    dak=0:zaman=0:SAYAC=0:SURE=0:SN=0:i=0
     endif
    
  adcin 1,STUN2  
    if STUN2>=199  and STUN2<397 THEN TUS=2:goto DONGU
    if STUN2>=397  and STUN2<600 THEN TUS=5:goto DONGU
    if STUN2>=600  and STUN2<802 THEN TUS=8:goto DONGU
    if STUN2>=802  and STUN2<1000 then TUS=10:goto DONGU
 
  adcin 2,STUN3
    if STUN3>=199 AND STUN3<397 THEN TUS=3:goto DONGU
    if STUN3>=397 and STUN3<600 THEN TUS=6:goto DONGU
    if STUN3>=600 and STUN3<802 then TUS=9:goto DONGU
    if STUN3>=802 and STUN3<1000 then TUS=12:goto DONGU '#
    GOTO BASLA
    
 DONGU:
 FOR I=0 TO 6
 GPIO.4=1:PAUSE 200:GPIO.4=0:PAUSE 100
 NEXT I
 SURE=TUS  
 INTCON.5=1':dak=0:zaman=0:sayac=0:SN=0:i=0   
    
'********************************************************************************    
       DISABLE
KESME:
    INTCON.7=0 'tüm interruptlar? kapat yani INTCON.7=0
      SAYAC=SAYAC+1  	    'kesme sayac?  1 sn= 61(sayac) x 256 (Tmr0) x 64 (bölme)
      IF SAYAC=61 then  	    '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
         SAYAC=0       	     'sayaç s?f?rlan?yor
         SN=SN+1       	    'saniye de?eri bir art?r?l?yor
            IF SN=60 THEN  	   'saniye 60 olmu? ise 1 dakika süre geçti o halde
               SN=0        	   ' saniye s?f?rlan?yor
               DAK=DAK+1   	   ' dakika de?eri bir art?r?l?yor
            ENDIF
       ENDIF
       IF  DAK=SURE THEN  INTCON.5=0
 
                       
    INTCON.2=0 'kesme bayragi sifirlanacak                             
    INTCON.7=1 'Yani INTCON.7=1 kesmeleri açt?k.
    RESUME
    ENABLE  
    END

ete

Birden fazla kusur var programda. Sırası ile;

1. INTCON registerinde TMR0 kesmesini açmamışsın.  INTCON=%10100000 şeklinde açman gerekirdi.

2. Kesme kullanılan programlarda PAUSE komutunu kullanmaman gerekir. Aksi halde, kesme oluşsa bile  PAUSE süresi bitinceye kadar program kesme etiketine gitmez. Bu ise programda süre aksamalarına sebep olur. Peki nasıl gecikme sağlayacağım dersen döngü kurarak bunu yapman gerek. Örnek vermek gerekirse;
  Pause 100 için;
  FOR I=0 to 10000
    PAUSEUS 5
  NEXT
  RETURN
şeklinde bir alt program yazıp oraya GOSUB ile gidilmesi uygun olacaktır. 10000 değerini yaklaşık olarak verdim gerekirse deneme yanılma ile hassas bir ayarlama yapılabilir. Normal şartlarda 100 ms lik gecikme için I dongüsü 20000 e kadar kurulması gerekir. Ancak döngü komut gecikmeside işin içine girince 8000-10000 arası bir değerin yeterli olacağını düşünüyorum.
Bu durumda bütün pause leri kaldırıp yerine alt rpgramlara yönlendirme komutlarını koymanda yarar var.

3. TRISIO komutunu 6 bit vermişsin. Buda 8 bit verilmelidir.  TRISIO=%00000111 şeklinde olmalıdır.

4. Ansel komutunu tek satırda kullanabilirdin.  ANSEL=%00110111 şeklinde olabilir.

Şimdilik görebildiklerim bunlar. Düzeltmeleri yap ve yeniden dene sonucuda yazmayı unutma lütfen.

Ete




Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

toprak

#2
merhaba dediginiz degisiklikleri yaptim yanlizca su intcon=%1010000 degisikligini yapmadim cunku tuslara basildigi anda tmr0 kesmesinin aktif olmasini  istiyorum  o nedenle intcon.5 i dongu etiketinde aktif yapiyorum.yani bu sekilde olursa hatami olur. birde hem belirttigim sekilde hemde sizin belirttiginiz sekilde yaptim her iki durumdada zamanlama olmuyor.ayrica bu dediginiz gecikmeler icin tam olarak nasil olacak tam anlamamis olabiirim belki ondanda olmamistir diye dusunuyorum.
@	device  pic12F675, intrc_osc_noclkout, wdt_off, pwrt_on, mclr_off, protect_off	

DEFINE ADC_BITS 10        ' ADC 10 bit kullanýlacak
DEFINE ADC_CLOCK 3        ' ANSEL.4  ANSEL.5  ANSEL.6 yý ayarlar
DEFINE ADC_SAMPLEUS 50    ' örnekleme 
define OSC 4              ' Çalýþma frekansý
define osccal_1k 1
TRISIO=%00000111          ' giriþ çýkýþ atamasý

CMCON = %00000111      ' Giriþlerdeki Comparatorlar kapalý
ANSEL=%00110111        ' GPIO.1, GPIO.0 ,GPIO.2 Analog secildi, diðerleri digital

ADCON0.7=1      ' 8 bit doðru okumak için sola yaslanmýþ (10 bitin son (LSB) 2 biti kullanýlmýyor) 
ADCON0.6=0  

INTCON=%10000000
ON INTERRUPT GOTO KESME

TUS VAR WORD
DAK VAR BYTE
ZAMAN VAR BYTE
STUN1 VAR WORD
STUN2 VAR WORD
STUN3 VAR WORD
SAYAC VAR BYTE
SURE VAR BYTE
SN VAR BYTE
I VAR BYTE 
K VAR WORD     
clear
PAUSE 100
 GPIO=0
BASLA:GPIO.5=0:GPIO.4=0
IF SURE<>0 AND DAK=SURE THEN
GPIO.5=1:PAUSE 200:GPIO.5=0
ENDIF 
  adcin 0,STUN1
  'if STUN1>=199 AND STUN1<397 THEN
     'GPIO.5=1:PAUSE 200:GPIO.5=0
     'endif
    if STUN1>=199 and STUN1<397 THEN TUS=1:goto DONGU
    if STUN1>=397 and STUN1<600 then TUS=4:goto DONGU
    if STUN1>=600 and STUN1<802 then TUS=7:goto DONGU
    if STUN1>=802 and STUN1<1000 then   '* tusuna basilirsa
     GPIO.4=1:GOSUB GONDER:GPIO.4=0:GOSUB GONDER
    dak=0:zaman=0:SAYAC=0:SURE=0:SN=0:i=0
     endif
    
  adcin 1,STUN2  
    if STUN2>=199  and STUN2<397 THEN TUS=2:goto DONGU
    if STUN2>=397  and STUN2<600 THEN TUS=5:goto DONGU
    if STUN2>=600  and STUN2<802 THEN TUS=8:goto DONGU
    if STUN2>=802  and STUN2<1000 then TUS=10:goto DONGU
 
  adcin 2,STUN3
    if STUN3>=199 AND STUN3<397 THEN TUS=3:goto DONGU
    if STUN3>=397 and STUN3<600 THEN TUS=6:goto DONGU
    if STUN3>=600 and STUN3<802 then TUS=9:goto DONGU
    if STUN3>=802 and STUN3<1000 then TUS=12:goto DONGU '#
    GOTO BASLA
    
 DONGU:
 GPIO.4=1:GOSUB GONDER:GPIO.4=0:GOSUB GONDER
 SURE=TUS  
INTCON.5=1:dak=0:zaman=0:sayac=0:SN=0:K=0 
  GOTO BASLA
 GONDER:
 FOR K=0 TO 20000
 PAUSEUS 5
 NEXT K
 RETURN
   
    
'********************************************************************************    
       DISABLE
KESME:
    INTCON.7=0 'tüm interruptlar? kapat yani INTCON.7=0
      SAYAC=SAYAC+1  	    'kesme sayac?  1 sn= 61(sayac) x 256 (Tmr0) x 64 (bölme)
      IF SAYAC=61 then  	    '61 adet kesme olunca 1 sn. süre geçiyor.(999424 us)
         SAYAC=0       	     'sayaç s?f?rlan?yor
         SN=SN+1       	    'saniye de?eri bir art?r?l?yor
            IF SN=60 THEN  	   'saniye 60 olmu? ise 1 dakika süre geçti o halde
               SN=0        	   ' saniye s?f?rlan?yor
               DAK=DAK+1   	   ' dakika de?eri bir art?r?l?yor
            ENDIF
       ENDIF
       IF  DAK=SURE THEN  INTCON.5=0
 
                       
    INTCON.2=0 'kesme bayragi sifirlanacak                             
    INTCON.7=1 'Yani INTCON.7=1 kesmeleri açt?k.
    RESUME
    ENABLE  
    END

fryrmnd

#3
@toprak
kodun tamamına bakamadım da. ete hocanını belirttiği şekilde gecikme vermek için direk olarak
Pause 100

değilde

For i=0 to 100
 pause 1
next i

şeklinde yazmanız lazım. Çünkü kesme Pause 100 dediğiniz zaman bu 100ms lik kısma dek gelirse pic bu kesmeyi kaçırır.  bu kaçırma olayını önlemek için beklemeleri ufak ufak veriyoruz. 1ms gibi. Ve döngü içinde verince hem istediğiniz gecikme sağlanıyor (100ms) hem de kesmeyi kaçırmıyoruz

ete

Sonradan gördüm. En önemli registerlerden olan OPTION_REG ayarlamasını unutmuşsun.
Bu register senin sayac değişkenini saydıran TMR0 sayacının bölücü oranını ayarlayacaktır. 61 adet kesme sonunda 1 sn geçmesi için bölme oranı 1/64 alınmalıdır. Buna uygun OPTION_REG değeri ise %00000101 şeklinde olacaktır. (OPTION_REG=%00000101 )
Bunu programa ilave et çalışacaktır.

Ete
Bilgi hazinedir paylaştıkça büyür.            http://etepic.com

toprak

merhaba hocam dediginiz gibi yaptim ve en onemliside option_reg ekledim sonuc olumlu.tesekkurler. simdide bu zamanlayiciyi alici verici ekleyerek uzaktan konrol etmeyi  dusunuyorum.12f675 de hafiza boyutuyla yetmez kaygisini tasiyorum ama deneyip gorecegim.