avatar_ete

PIC Basic Ders-06 (Kesme (INTERRUPT) Kullanımı)

Başlatan ete, 28 Ağustos 2011, 16:13:09

efehurkan

Merhaba Ustadlar,  asagidaki kodlar 16f628 te sorunsuz calisiyor fakat 12f675 te calistirmayi basaramadim. 12f675 te Buton acildiginda 40 sn sonra led yaniyor, bir daha sonmuyor surekli yanik kaliyor.


DEFINE OSC 4
DEFINE OSCCAL_1K 1
Trisio=%0000001
Gpio=%00000000
OPTION_REG.7=0
ANSEL=%00000000
ADCON0=%00000000
cmcon=7
WPU=%00000100

SYMBOL BUTON= GPIO.0
SYMBOL LED = GPIO.1
SN    VAR BYTE 56
KES   var byte 57
I     VAR BYTE
ACIK  VAR BIT  'ACIK=1
pause 500
OPTION_REG=%10000111 
INTCON=%10000000
ON INTERRUPT GOTO KESME
TMR0=60   
BASLA:
      IF BUTON=0 then
         ACIK=1
         KES=0:SN=0
         INTCON.5=1 
         WHILE BUTON=0
           IF SN=40 THEN LED=1           
         WEND
         BUTON=0
           IF SN<40 THEN
             SN=0:KES=0
             INTCON.5=0
             GOTO BASLA
           ENDIF
                     
       ENDIF
       
       GOTO BASLA
           
                     
DISABLE
KESME:
      kes=kes+1
      If kes=20 THEN
         KES=0
         SN=SN+1
         IF SN=40 THEN INTCON=0
      ENDIF     
           
        TMR0=60
        INTCON.2=0
        RESUME
        ENABLE
        END

ete

Hata-1: Trisio=%0000001 ifadesi Trisio=%00000001 şeklinde yazılmalı
Hata-2:WPU=%00000100 ifadesi WPU=%00000001 şeklinde olmalı Butonun bağlı olduğu yere pullup vermen gerek.
Hata-3: BUTON=0 şeklinde komut çalışmaz. çünki buton giriş pinidir. Bana kalırsa bu komut yerine LED=0 yazılması gerekir oraya. Sorun bu olsa gerek.

Programa bakıldığında SN sayacının kesmeye bağlı olarak Butona basılı tutulduğu müddetçe çalıştığı görülebilir.
Buton bırakıldığı zaman sistem sıfırlanıp kesme iptal edilerek başa dönülmekte ve yeniden butona basılması beklenmektedir.

Asıl şikayetin ise 40 sn sonra led yanıyor bir daha sönmüyor. Peki kim söndürecek o ledi?
Bak bakalım programa LED=0 şeklinde ledi söndüren bir komut varmı?
Yok ben göremedim. O halde hiç şikayet etme sönmez o led kimse söndürmüyor çünki.

Sanırım Buton=0 yerine Led=0 yazman gerekiyor idi. Sorunun bu bana kalırsa.

Ete

efehurkan

Tesekkurler Hocam, emeginize saglik, yazdiginiz degisiklikleri yaptiktan istedigim gibi calisti, artik 16f628 yerine 12f675 kullanabilirim.

alisumer

ETE hocam lcd komutu arasında kesme olursa işi brakıp kesmeye gitmesini istiyorum basic de mümkün mü Asm de her türlü oluyor da  onunlada lcd sürmek ölüm gibi
 
Hep meraktan

ete

Basic de genel kural şu kesme içeren programlarda bir kesme oluştuğu zaman o anda işletilen basic komutu bitirilmeden kesme etiketine gidilmez.
Basic de LCDout komutunu verdiğin zaman ancak komut işini bitirince program kesme etiketine gidecektir.

Ete

alisumer

#125
hocam bi yöntem buldum işlem sırasında kesmeye gitmek için basic on ınterrupt komutu vermek yerine kodun başına asm org 0x04 adresını verip ardından kesmeye gönderince oluyor bir çok kod ile çalıştı ama istediğim kodda hata verdi f1938
7 seg lcd sürüyorum onda kesmenin işi yarıda kesmesi gerekiyor
hata kodu "overwriting previous address contens(0004).aynı adrese yükleme yapma  ile ilgili kodun normalde çalıştığının videosunu paylaşıyorum .

Hep meraktan

elektro77

#126
Bence bu bir devrim olmuş. Elinize sağlık...Tabi ki en iyi cevabı ete hocam verecektir.
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

ete

#127
Çok önceleri bu işe kafamı takmıştım. O zaman edindiğim intiba her iki işleminde aynı sonucu vermesi yönünde şeklinde aklımda kalmış.
Zira ASM de bir kesme açacaksanız kesme adresini Org 0x004 şeklinde vermeli ardından da kesme oluşunca nereye gidileceğini belirtmeniz gerekir. Ancak Org komutunun ardından verdiğiniz kesme adresine hemen gidilecek yada kod ilk çalıştığında gidilecek diye bir kural yok. Kesme bayrağı set edildiğinde gidilecek şeklinde bir kural var. ASM de işin kontrolünü PIC-ROm yani geri planda çalışan picin içindeki geri plan programı yapıyor. Basic de ise derleyicinin eklediği program işi kontrol ediyor olmalı. Bu nedenle aralarında bir zaman farkı var. Basic'e ASM de bir Kesme açılırsa işi kim kontrol edecek doğrusu bilemiyorum. Verdiğin videoyu izledim. Pic simulator hiç kullanmadım. Aslında kullanmak isterim zaman zaman en azından kod işletim sürelerini hesaplamak için lazım oluyor. Video da bir saçmalık vardı sebebini anlayamadım. basic de Kesme açınca 4 olu adreste kesmenin başlangıcı yer alması gerekirken RETURN komutu oraya yerleşiyor. Bence burada bir BUG var yada hata var. Hata simulator dan kaynaklanıyor olabilir. Bu konuda emin olmadan hemen karar vermemek gerekir.
güvenilir bir Simulator bulabilirsem deneyeceğim bazı şeyler.
Bu arada basic programlarında ASM tipi kesme kullanabilmek için Darrel Taylor'un yardımcı programları var idi. Aşağıdaki linki incelemeni öneririm
http://www.dt-ints.com/DT_INTS-14/asm_ints.html
Bir programda hem basic kesmesi hamde asm kesmesi de bu sistemle mümkün olabiliyor.
Bu yardımcı sistem ile basic kesme kurallarının dışına çıkabiliyorsun. Bu sistemle oluşturulmuş bir kesme programının simulatör incelemesinide görmek isterdim doğrusu.

Ete
Ete

alisumer

#128
hocam ne kadar disasm kulandıysam hepsinde basic kesmesi 4. adrese return koyup kesme oluşunca kesmeye girdiği noktaya geri gönderip alt satırlarda intcon 7  kapanmışmı kontrol edip işlem yapıyor yanı şöyle birşey hiç kesme komutu koymasakta sürekli her işlemimizin ardından kesme bayrağını kontrol etmek gibi birşey çok saçma . bazı kodlarda asm kesme komutlarının olmamasının sebebi ise basic 0.sıraya nedense istisnasız clrf 0x32 koyuyor o satırları dolduruyor bazısında olmuyor sanırım kodların uzunluğu ile alakalı çünkü kısa kodlarda sıkıntı olmadı hiç link e bakıcam teşekkürler
Hep meraktan

alisumer

Hocam bu kod PBP dosyasındaki pbppi14e.lib dosyasından bir bölüm kod başlangıcı ile ilgili kısım kodun en son kısmında return kullanılmış muhtemelen kesmedeki return bu return üzerinde biraz uğraştıktan sonra buradan yazarım
;****************************************************************
;* Startup Code                                                 *
;*                                                              *
;* Input      : None                                            *
;* Output     : None                                            *
;*                                                              *
;* Notes      : Must be first library routine.                  *
;****************************************************************

    ifdef LCDOUTDEC_USED
FLAGS_USED = 1
    endif
    ifdef LCDOUTDECL_USED
FLAGS_USED = 1
    endif
    ifdef LCDOUTJ_USED
FLAGS_USED = 1
    endif
    ifdef LCDOUT_USED
FLAGS_USED = 1
    endif
    ifdef I2CREAD_USED
FLAGS_USED = 1
    endif
    ifdef I2CWRITE_USED
FLAGS_USED = 1
    endif

  LIST
    ORG RESET_ORG		; Reset vector usually at 0
  NOLIST

    ifdef ICD_USED
  LIST
        nop                     ; Skip first location for ICD
  NOLIST
    endif

    ifdef FLAGS_USED
  LIST
        clrf    FLAGS           ; Clear all flags on reset
  NOLIST
    endif

  LIST
        goto    INIT            ; Finish initialization
  NOLIST
     
    ifdef LOADER_USED
  LIST
    ORG RESET_ORG + 4		; Make sure no library code in first 4 locs
  NOLIST
    endif

    ifdef INTHAND
  LIST
    ORG RESET_ORG + 4		; Interrupt vector at 4
	movlp	high (INTHAND)	; PCLATH automatically shadowed
        goto    INTHAND         ; Goto user interrupt handler
  NOLIST
    else
      ifdef ONINT_USED
  LIST
    ORG RESET_ORG + 4		; Interrupt vector at 4
        			; Had to have gotten here with a bra
        			; Return does not restore changed PCLATH
        return                  ; Return from interrupt without setting GIE
  NOLIST
      endif
    endif
Hep meraktan

alisumer

#130
Evet beyler aynen o yanlız f628 için lib dosyası pbppic14.lib e olanı gelişmişler için kodda bulunan return yerine programda yazdığım kesme adresini başına alttire yazarak yazınca direk kesmeyi yazdığım adrese dallanıyor başardım :)))
	  if ((CODE_SIZE > 2) & (RESET_ORG != 0))
            ifdef PM_USED
	"Error: RESET_ORG cannot be used with On Interrupt if code size > 2K."
            else
	error "RESET_ORG cannot be used with On Interrupt if code size > 2K."
            endif
          endif
    ORG RESET_ORG + 4		; Interrupt vector at 4
        GOTO _KESME;return                  ; Return from interrupt without setting GIE
  NOLIST
     endif
    endif
üstelik her seferinde kodu değişmenize gerek yok sadece kesme başlığını orda belirtiğiniz gibi sabit yazın her programda hallolur
Hep meraktan

alisumer

#131
işte budur hocam  ;D  ;D  ;D

Hep meraktan

ete

Bu kadar basit olması insanda şüphe uyandırıyor. Mutlaka kaçırılan bazı başka özellikler vardır. Ancak senin işin görüldüğüne göre dene bakalım sonradanbir aksaklık çıkacakmıdır.
Ete

elektro77

#133
Microfonunuz bulduğunuz yöntem kadar şahane değil.
Bende bu dosyalar görünmüyor.
"Eğer bir konuyu öğrenmek istiyorsan o konunun öğretmeni ol; daha iyi öğrenmek istiyorsan o konuda bir kitap yaz; daha da iyi öğrenmek istiyorsan yazdığın kitabi oku"

alisumer

pazar malı kulaklık sanırım bu yüzden yutuber olamam  :o evet nefes sesleri rahatsız edici kusura bakmayın gece iki gibi buldum yöntemi birdaha kayıt yapmak işime gelmedi ilk denememi paylaştım videodan önce denemek aklıma bile gelmedi hızlı versiyonu isiste paylaştığım videolarda sesler hep kötü anlaşılır derdim üyesi olduğum forumlara bilgi paylaşmak
Hep meraktan

Powered by EzPortal