TMR0

Başlatan designer.21, 20 Mayıs 2020, 15:20:19

designer.21

Değerli hocalarım merhaba;
aşağıdaki kodlardan dolayı sizlerden şimdiden özür dilerim. zamanlama ile ilgili bir kod yazmak istiyorum ve bunu da bana en kolay gelen TMR0 ile yapmak istedim fakat bir türlü çözemiyorum. Aşağıda daha önce yayınlanmış bir TMR0 programı üzerinden biraz değişiklik yapıp kendi isteğimi yapmak istedim yine olmadı.

butona 3 saniye içerisinde 2 defa tıklanmışsa led'i TOGGLE yap bu kadar : )

aşağıdaki kodlar ile seyrettiğim yol bu şekil;
-Butona basıldı ve kesme başladı
-sayaç işliyor; butona 2 defa basılmışsa ve zamanlama 3 saniyenin altıdnaysa led'i TOGGLE yap.

çok basit düşünüyorum ve kod size çok saçma gelecek, kusura bakmayın tekrar.


@ __config _BODEN_ON & _BOREN_ON & _CP_OFF & _PWRTE_ON & _WDT_ON & _LVP_OFF & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT
DEFINE OSC 4
CMCON=7
TRISA=%00000000
TRISB=%00000001
PORTA=0
PORTB=0

SYMBOL LED=PORTA.0
SYMBOL BUTON=PORTB.0

SN    VAR BYTE 
KES   var byte
SAY     VAR BYTE
pause 500
OPTION_REG=%00000111  '1/256 bölme oranı ve TMR0=60 ile başlanırsa her 50 ms de bir kesme oluşacak
INTCON=%10000000
ON INTERRUPT GOTO KESME
TMR0=60   
    BASLA:
        KES=0
        SN=0
        IF PORTA.0=0 then SAY=SAY+1 and INTCON.5=1
        IF SAY=2 AND SN<3 THEN TOGGLE LED 
    GOTO BASLA
     
DISABLE
KESME:
'her kesme 50ms olduğuna göre 1 sn için 20 kesme oluşması gerekir. Önce bunu saymamız gerekiyor
      kes=kes+1
      If kes=20 THEN
         KES=0
         SN=SN+1
      ENDIF
        INTCON.2=0      
        RESUME
        ENABLE
        END


ama şöyle de bişey var tabi. bu uğraşlar sayesinde kesmelerin mantığını, zamanlama hesabını, INTCON - OPTION - TMR1 için kulanılan T1CON REGISTER'leri az çok kavradım. bana bişeyler kattı :)

ete

IF PORTA.0=0 then SAY=SAY+1 and INTCON.5=1
bu şekil kullanımı nerede gördün daha önceden?. Kullandığına göre bir yerde görmüş olmalısın!!!.
Bu yanlış doğrusu,
IF PORTA.0=0 then 
  SAY=SAY+1 
  IF INTCON.5=0 THEN INTCON.5=1
endif
şeklinde olmalı

Butona bastın ve kesme aktif oldu ve saniyeler saymaya başladı diyelim.
Ama birde şu kod a bir bak istersen.
    BASLA:
        KES=0
        SN=0
        IF PORTA.0=0 then SAY=SAY+1 and INTCON.5=1
        IF SAY=2 AND SN<3 THEN TOGGLE LED 
    GOTO BASLA
kes=0 komutu sürekli KES değerini sıfırlıyor. SN=0 komutu sürekli sn değerini sıfırlarsa ne olacak hiç bir zaman istediğin sn değerine ulaşamayacaksın.
BASLA satırından sonra KES=0:SN=0 verebilirsin. SOnrasına BASLA_BIR: diye bir etiket ismi koy ve en alta da GOTO BASLA değil GOTO BASLA_BIR demen gerekirki o değişkenler kesme aktif edildikten sonra sıfırlanmasın.

ETE

designer.21

Hocam verdiğim rahatsızlık için özür dilerim ama bu şekilde değiştirdim yine olmadı maalesef.

@ __config _BODEN_ON & _BOREN_ON & _CP_OFF & _PWRTE_ON & _WDT_ON & _LVP_OFF & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT
DEFINE OSC 4
CMCON=7
TRISA=%00000000
TRISB=%00000001
PORTA=0
PORTB=0

SYMBOL LED=PORTA.0
SYMBOL BUTON=PORTB.0

SN    VAR BYTE 
KES   var byte
SAY     VAR BYTE
pause 500
OPTION_REG=%00000111  '1/256 bölme oranı ve TMR0=60 ile başlanırsa her 50 ms de bir kesme oluşacak
INTCON=%10000000
ON INTERRUPT GOTO KESME
TMR0=60   
    BASLA:
        KES=0
        SN=0
        SAY=0
        
        BASLA_BIR:
                IF PORTA.0=0 then 
                SAY=SAY+1 
                IF INTCON.5=0 THEN INTCON.5=1
                endIF
                IF SAY=2 AND SN<3 THEN TOGGLE LED
        GOTO BASLA_BIR
     
DISABLE
KESME:
'her kesme 50ms olduğuna göre 1 sn için 20 kesme oluşması gerekir. Önce bunu saymamız gerekiyor
      kes=kes+1
      If kes=20 THEN
         KES=0
         SN=SN+1
      ENDIF
        INTCON.2=0      
        RESUME
        ENABLE
        END

ete

Şöyle bir düşün bakalım neden olmuyor acaba?
İp ucu vereyim. Programında sembol isimler tanımlıyorsun da bunları program içinde neden kullanmıyorsun? Kullansan bu sorunu yaşamayacaktın.
Sen buton olarak kimi kontrol ediyorsun basıldımı diye? Buton nereye bağlı? araştır bakalım.

Ete

designer.21

Hocam son haliyle bu şekilde yaptım bu defa kararsız bir şekilde çalışıyor.

kendi çapımda :) kod satırlarını tek tek inceliyorum, nerde hata var neden olmuyor bir türlü çıkamıyorum işin içinden

@ __config _BODEN_ON & _BOREN_ON & _CP_OFF & _PWRTE_ON & _WDT_ON & _LVP_OFF & _MCLRE_OFF & _INTRC_OSC_NOCLKOUT

DEFINE OSC 4
CMCON=7
TRISA=%00000000
TRISB=%00000001
PORTA=0
PORTB=0

SYMBOL LED=PORTA.0
SYMBOL BUTON=PORTB.0

SN      VAR BYTE 
KES     VAR BYTE
SAY     VAR BYTE
PAUSE 500
OPTION_REG=%00000111  '1/256 bölme oraný ve TMR0=60 ile baþlanýrsa her 50 ms de bir kesme oluþacak
INTCON=%10000000
ON INTERRUPT GOTO KESME
TMR0=60

    BASLA:
        KES=0
        SN=0
        SAY=0
        
        BASLA_BIR:
                IF BUTON=0 THEN
                SAY=SAY+1 
                IF INTCON.5=0 THEN INTCON.5=1
                ENDIF
                IF SAY=2 AND SN<3 THEN TOGGLE LED
        GOTO BASLA_BIR     
DISABLE
KESME:  'her kesme 50ms olduðuna göre 1 sn için 20 kesme oluþmasý gerekir. Önce bunu saymamýz gerekiyor
      KES=KES+1
      IF KES=20 THEN
         KES=0
         SN=SN+1         
      ENDIF
        INTCON.2=0      
        RESUME
        ENABLE
        END

MB_77

#5
bu mesaj tarafımdan silinmiştir.

MB_77

#6
bu mesaj tarafımdan silinmiştir.

ete

Timer0 yeniden yükleme değerin olan 60 değeri her kesme oluştuğunda çıkmadan önce timer0 a yüklenmelidir. yoksa sistem kafasına göre çalışır ki oda öyle yapıyor. Yani kesme süren 20 ms olması gerekirken 1 kereliğine 20 ms oluyor ama sonra alıp başını gidiyor çünki kesmeden çıkmadan önce TMR0=60 değerini vermiyorsun.

Her işte olduğu gibi bu konuda da sınırların olmalı. 3 sn dolduktan sonra sistem sıfırlanmalı bence yada sıfırlama için kendine bir kriter seçmelisin. Bu istediğin özellik bütün programın çalışması boyunca 1 keremi gerçekleşecek? burada öyle oluyor.

Ete

designer.21

#8
Cevaplarınız için çok teşekkürler. verdiğiniz bilgiler doğrultusunda kodları değiştirip bu defa yapabilirim inşallah. ayrıca 16F628A pic kullanıyorum

Powered by EzPortal