avatar_ete

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

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

est32

#60
Hocam ben bu saati 3 yıldır kullanıyorum ve şansıma osilatör de stabil çıktı. Herhangi bir sorun yok. Osilatör 1.5 volt ile çalışıyor ve ben de hem doğrultma amaçlı hem de gerilimi yükseltme amaçlı 2 adet tarnsistör kullandım.
Hatta sadece 1Hz ihtiyacı olup RB0 kesmesi ile basit bir program çalıştırmak isteyenlere de bu yöntemi tavsiye edebilirim. Belki çok amatörce ama oldukça pratik bir çözüm. Ayrıca bu saatlerden 6-7 kadarını da internet üzerinden sattım ve çok şükür herhangi bir şikayet gelmedi.



Kesme yazılımı da şu şekilde;
'**************************************************************************************
DISABLE
KESME:         
          SN=SN+1
          toggle LED'SANİYEYİ 1 ARTIR,LAMBAYI YAK SÖNDÜR
          IF ALR=1 THEN HIGH LED'ALARM AYARLANIRKEN LEDİ SÖNDÜR
          IF mesgul=1 THEN HIGH LED'DERECE GÖSTERİRKEN LEDİ SÖNDÜR
          IF SN>59 THEN SN=0 : DK=DK+1 
          IF DK>59 THEN SA=SA+1 : DK=0
          IF SA>23 THEN SA=0 
         
          IF ALR=0 THEN READ 0,E_H : READ 1,ALR_SA : READ 2,ALR_DK
          IF ALARM_ERTELE>0 THEN ALARM_CAL=ALARM_CAL+1
          IF BUZZER=1 THEN ALARM_SUS=ALARM_SUS+1
          IF ALARM_SUS>600 THEN BUZZER=0 : ALARM_SUS=0'10DK ALARM ÇAL,SONRA SUS
          IF ALARM_CAL=ALARM_ERTELE THEN HIGH BUZZER : ALARM_ERTELE=0 : ALARM_CAL=65535
          ANA_EKRAN=ANA_EKRAN+1
          SAAT_SURESI=SAAT_SURESI+1
          DERECE_SURESI=DERECE_SURESI+1
          INTCON.1=0'KESME BAYRAĞINI SIFIRLA
          RESUME'GELDİĞİN YERE DÖN
          ENABLE'KESMELER YENİDEN AKTİF
'**************************************************************************************

eprom_20

ete hocam mrb,

Hocam ekte gönderdiğim Timer ve Kesme kodlarını ilk defa kulanarak yapmaya çalıştığım devreyi ve kodları bir gözatabilirmisiniz...?

Hocam kısaca devrede yapmak istediğim TMR0 veya TMR1  kullanarak portd.0 ve portd.3'e bağlı ledlerin sırayla 2 dakika aktif kalıp sönmesi..(zaman_1=2dk, zaman_2=2dk....)zaman_4'e ulaştığında yani 8dk sonra tekrar başa dönmesi ve böyle bir döngü oluşturması,,
Ama bu arada RB0 kesmesi oluşursa da buradaki yükleri 2 dk çalıştırıp kesmeden çıkması
kodlarda yanlışım olabilir hocam bunu ilk defa deniyorum,,,Birde hocam kesme oluşunca (RB0) portc.7 deki ledin sadece 5 saniye aktif kalıp sönmesi gerekiyor bunu program yapıyor ancak sanırım pause komutlarını oldukça fazla kullandım bunun olumsuz etkisi olur mu acaba?
Yardımlarınız için şimdiden çok teşekkür ederim

ete

Bir çok kez söyledim yine söylüyorum. Programda kesme kullanıyorsanız PAUSE kullanmayın. Aksi halde programınız doğru çalışmaz. Sebebi gayet basit.
Bir kesme oluştuğu anda programın derhal kesme etiketine gitmesi gerekir. Ancak Basic de bir temel kural var. Kesme oluştuğu andan program bir basic komutunu icra ediyor ise icra bitmeden program kesme etiketine gidemez.
Normal şartlarda komutlar çok kısa sürelerde icra edilirler ancak gecikme komutları hariç. Zira Pause 10 denildimi program 10 ms geçmeden kesme etiketine gidemez. Bu ise program akışında sorunlar yaratır.

Programında ne TMR0 neden TMR1 kullanıldığını gördüm. Halbuki açıklamanda bunları kullanarak sistemi çalıştırdığını veya çalıştırmak istediğini anlıyorum. O halde neden zamanlayıcıları kullanmadın?
BU durumda programından yapmak istediğini anlamam zor.
Açıklaman yetersiz. TMR0 ne için kullanılacak? , TMR1 ne için kullanılacak ? belli değil.
Programa bakılınca BASLA satırından GOTO BASLA satırına kadar şu işler yapılıyor
1. ZAMAN_1 led'i yakılıyor
2. 5000x10=50000 ms yani 50 sn süre ile led yanık kalıyor. Bu komut gecikmesi ile birlikte 60 sn kabul edilebilir yani 1 dak.
3. Sonra led söndürülüyor ve 500 ms kadar bekleniyor. Bu bekleme anlamsız bence.
4. ZAMAN_2 ledi yakılıyor
5. Yine 1 dak yanık bırakılıyor
6. ZAMAN-2 ledi söndürülüyor ve 500 ms sönük olarak bekleniyor buda anlamsız.
7. Benzer şekilde Zaman-3 ledi yakılıp söndürülüyor
8. benzer şekilde Zaman-4 ledi yakılıp söndürülüyor.
Tekrar aynı işlemler başa dönülerek tekrarlanıyor.

Şİmdi programda en azından PortB.0 kesmesi kullanıldığına göre senin 2 dakika programda ise 1 dakika olan bekleme işlemlerini TMR1 sayacına yaptırmak daha uygun olacaktır sanırım.
Bunu yapabilmek için illa kesme kullanmayada gerek yok aslında. Çünki bu beklemeler esnasında yalnızca PORTB.0 kesmesi bekliyoruz. O halde başka iş yapılmayacak ise TMR1 sayacını her 500ms de bir kesme oluşturacak şekilde ayarlarız. Sonra oluşan kesmeleri sayarız. 2 dakika için 4 adet kesme oluşması yeterli olacaktır.
Programa bir SAY değişkeni ekleriz byte cinsinden. Her TMR1 kesmesi oluştuğunda SAY=SAY+1 yaaprız. SAY=4 olduğunda 2 dakika geçmiş olacaktır.  Bunu bir alt programa dönüştürerek her bekleme için aynı alt programı kullanırız.
BEKLE:
       SAY=0
       TMR1H=$0B:TMR1L=$DE  'timer'a ön yükleme değeri verdik  'her kesme 500ms süre alıyor.
       T1CON=%00110001      'bölme oranı 1/8 ve timer1 aktif edildi
       PIR1.0=0
BEKLE_BIR:
           TMR1H=$0B:TMR1L=$DC     
           while PIR1.0=0:WEND 'KESME OLUŞUNCAYA KADAR BEKLE
           PIR1.0=0       
           SAY=SAY+1
           IF SAY=4 THEN RETURN
           GOTO DELAY_BIR
Programın başını da şöyle ayarlamak gerekir,
BASLA:
BASLA:

ZAMAN_1=1
gosub bekle
ZAMAN_1=0

ZAMAN_2=1
gosub bekle
ZAMAN_2=0

ZAMAN_3=1
gosub bekle
zaman_3=0

ZAMAN_4=1
gosub bekle
ZAMAN_4=0
GOTO BASLA

Kesme kısmına şimdilik dokunmadım. O kısım aynen kullanılabilir.

Dene bakalım olacakmı
Ete




ete

#63
Bu arada programın 20 Mhz ile çalışıyormuş Verdiğim kodlar 4 Mhz için geçerlidir. Ayrıca 2 dakika değil 2 sn hesabı yapmışım.

TMR1 bölme oranı en fazla 8 olabiliyor. Bu durumda 20 Mhz de ancak 100 ms lik gecikme yaratabiliriz. O halde SAY değeri 10 olunca 1 sn geçmiş olacaktır. Bu durumda SAY=600 olunca 1 dakika geçmiş olacak 1200 olunca da 2 dakika geçmiş olacaktır.
Bu durumda SAY değişkeni WORD tipinden tanımlanmalı ve SAY=1200 olunca sistem RETURN ile geri döndürülmelidir.

Bu arada Kesme kısmınıda değiştirmek gerekiyormuş. O kısmıda şöyle değiştir.
DISABLE  'yeniden kesme oluşması önleniyor 
KESME: 'program buraya geldiğinde kesme oluşmuş demektir.
     
        FOR I=0 TO 2000     'röle 2 dk aktif kalacak
        ALARM=1
        PAUSE 50
        ILERI=1
        PAUSE 10
        ILERI=0
        PLAY=1
        NEXT I
        ALARM=0
        PLAY=0
        SANIYE=0 
       INTCON.1=0  'RB0/INT Bayrağı (flag) silindi. 
       Resume      'geldiğin yere dön.
       Enable 

Tabiiki bu sistemde PORTB.0 kesmesi oluşursa diğer zamanlama işleri aksayacak demektir. Onlarında aynı şekilde devam etmesini istiyorsan iş gittikçe zorlaşıyor demektir. Bu durumda ikinci bir timer devreye sokulması gerekir. Nasıl olacağını hemen düşünmem zor. Ayrıca tam olarak ne yapmak istediğinide anlamadım henüz.

Ete


ete

Senden haber çıkmadı. Bu arada bend edüşünüp bir şeyler yaptım. Aşağıdaki program, Normal çalışıyor. Çalışmada PortD ye bağlı ledler 2 dak. yanıyorlar. Arada PortB.0 kesmesi gelirse sistem orayıda devreye alıyor ve zamanlayıcılar birlikte hareket ederek her kes kendi zamanında çalışıyor.

Ete

@ DEVICE pic16F877A                      		                                
@ DEVICE pic16F877A, WDT_OFF             
@ DEVICE pic16F877A, PWRT_ON             
@ DEVICE pic16F877A, PROTECT_OFF
@ DEVICE pic16F877A, HS_OSC         
define OSC 20

TRISA=%00111111
TRISB=%11111111
TRISC=%00000000
TRISD=%00000000
TRISE=%00000111       

ADCON1=7
CMCON=7
 
ON INTERRUPT GoTo KESME
OPTION_REG=%10000111    ' Bölme oranı 1/256    000=1/2 001=1/4 010=1/8 011=1/16 100=1/32 101=1/64 110=1/128 111=1/256
INTCON=%10010000 
TMR0=0
T1CON=%00110001


SAY VAR WORD
SURE VAR word
ZAMAN_1  VAR PORTD.0
ZAMAN_2  VAR PORTD.1
ZAMAN_3  VAR PORTD.2
ZAMAN_4  VAR PORTD.3
ALARM    VAR PORTC.5
PLAY     VAR PORTC.6
ILERI    VAR PORTC.7



SAYAC VAR   BYTE
I     VAR   WORD
SANIYE VAR  BYTE

PORTA=0
PORTB=0
PORTC=0
PORTD=0
PORTE=0


BASLA:

ZAMAN_1=1
gosub bekle
ZAMAN_1=0

ZAMAN_2=1
gosub bekle
ZAMAN_2=0

ZAMAN_3=1
gosub bekle
zaman_3=0

ZAMAN_4=1
gosub bekle
ZAMAN_4=0
GOTO BASLA

BEKLE:
       SAY=0
       TMR1H=$0B:TMR1L=$DE  'timer'a ön yükleme değeri verdik  'her kesme 500ms süre alıyor.
       T1CON=%00110001      'bölme oranı 1/8 ve timer1 aktif edildi
       PIR1.0=0
DELAY_BIR:
           TMR1H=$0B:TMR1L=$DC     
           while PIR1.0=0:WEND 'KESME OLUŞUNCAYA KADAR BEKLE
           PIR1.0=0       
           SAY=SAY+1
           IF SAY=600 THEN RETURN
           GOTO DELAY_BIR         

DISABLE  'yeniden kesme oluşması önleniyor 
KESME: 'program buraya geldiğinde kesme oluşmuş demektir.
      IF INTCON.1=1 then
         INTCON.5=1
         ALARM=1
         pause 50
         ILERI=1
         PLAY=1
         INTCON.1=0
         TMR0=60
         SURE=0
         GOTO CIK
       ENDIF
       SURE=SURE+1 '10 ms geçti
       If sure=12001 THEN
         INTCON.5=0
         ALARM=0
         PLAY=0
         ILERI=0
       ENDIF 
       IF SURE//10=0 then TOGGLE ILERI
       INTCON.2=0 
       TMR0=60   
CIK:     
       Resume      'geldiğin yere dön.
   Enable      'kesmeler yeniden aktif.

eprom_20

Yardımlarınız için teşekür ederim hocam dün ulaşamadım özür dilerim bugün kodları hemen deneyeceğim

Hocam devrede yapmak istediğim kısaca şöyle
Ekteki devrede görüleceği gibi 4017 entegresinin çıkışlarına bağlı ve hepsi değişik direnç değerlerine sahip potlar var. 555' e sabit 10uf kondansatör koyarsam hep 1Hz lik dalga üreteceğim Ama ben buradaki kondansatörleri değiştirerek  2 dakika boyunca her pot değerinde görev yapmasını (yani 2 dakika boyunca o frekansta dalga üretmesini) istiyorum..Zamanlayıcıdan kastım bu Hocam ayrıca 2 dakika da öylesine bir zaman dilimi 1 veya 3 dakika da olabilir

eprom_20

Hocam kodları denedim elinize,emeğinize sağlık çalışıyorlar,,sadece bir noktada farklılık var hocam
kesme oluşunca İLERİ komutunun sadece 1 defa çalışması bir daha kesme oluncaya kadarda çalışmamasını istiyordum ama burada devamlı flash yapıyor bunu engelleyebilirmiyiz acaba

DISABLE  'yeniden kesme oluşması önleniyor
KESME: 'program buraya geldiğinde kesme oluşmuş demektir.
IF INTCON.1=1 then
INTCON.5=1
ALARM=1
PAUSE 50
ILERI=1  ' bu port aktif
PAUSE 50
PLAY=1
ILERI=0  'port pasif  bir daha çalışmasın
INTCON.1=0
TMR0=60
SURE=0
GOTO CIK
ENDIF   

SURE=SURE+1 '10 ms geçti
If sure=12001 THEN
INTCON.5=0         
ALARM=0         
PLAY=0         
'ILERI=0       
ENDIF   

IF SURE//10=0 then 'TOGGLE ILERI       
INTCON.2=0         
TMR0=60 
ENDIF

kodları bu şekilde değiştirdim ama olmadı Hocam bunu nasıl engelleyebiliriz yardım ederseniz sevinirim hocam....Allaha emanet olunuz

ete

Bir yanlışın olsa gerek. Bu kodları kendim yazmadım senin yazdıklarından aldım.
Bak ne yazmışsın;
 FOR I=0 TO 200     'röle 2 dk aktif kalacak
        ALARM=1
        PAUSE 50
        ILERI=1
        PAUSE 10
        ILERI=0
        PLAY=1
        NEXT I

Burada İleri pini sürekli flash yapıyor.
Madem flash yapmayacak neden orada döngü kurup onları içine aldın?
Kesme kısmında 3 adet pin etkili bunlar;
ALARM
ILERI
PLAY
şayet kesme oluşunca bunlar yakılıp 2 dakika sonra söndürülecek ise kesme etiketini şöyle değiştir
DISABLE  'yeniden kesme oluşması önleniyor  
KESME: 'program buraya geldiğinde kesme oluşmuş demektir.
      IF INTCON.1=1 then
         INTCON.5=1
         ALARM=1
         ILERI=1
         PLAY=1
         INTCON.1=0
         TMR0=60
         SURE=0
         GOTO CIK
       ENDIF
       SURE=SURE+1 '10 ms geçti
       If sure=12001 THEN
         INTCON.5=0
         ALARM=0
         PLAY=0
         ILERI=0
       ENDIF 
       INTCON.2=0 
       TMR0=60   
CIK:     
       Resume      'geldiğin yere dön.
   Enable      'kesmeler yeniden aktif.


Ete

eprom_20

Hocam yardımlarınız için çok teşekkür ederim program çalışıyor ekte son halini ekledim,,
Allah razı olsun,,,Sevgiyle,,,,,

Burak

Hocam merhaba , bu konu üzerindeki tüm mesajları okudum , anladıklarım oldu ziyadesiyle anlamadıklarımda . Ben kafama takılanları sorayım .

Size sorulan sorularda , TMR1 sayıcısı için yaptığınız açıklamada

Alıntı Yapdiyelimki 5 sn de bir kesme yaratacağım. 5sn= 5.000 ms = 5.000.000us dir. İşlemci 4 Mhz de çalışıyor ise her bir komut çevrimi 1us olduğuna göre önce bölme oranını bulmalıyım ve hangi timer'ı kullanacağımı (8 bit yada 16 bit) tespit etmeliyim.
TMR0 için en büyük bölme oranı 1/256 idi. 5.000.000'u 256 ya bölersem  19531 elde ederiz. Çıkan rakam 8 bitten büyük bir raka m olduğu için 8 bit timer kullanamam. O halde 16 bitlik TMR1 sayacını kullanmalıyım.
Bu sayacın en büyük böleni ise 16 dır. O halde 5.000.000 /16 = 312500 elde ederiz. Bu rakamda 16 bitden büyük olduğu için bir tedbir

şeklinde bir açıklama yapmışsınız ama yanlış bakmadıysam TMR1 sayıcısının kayıtçısı olan T1CON kayıtçısına göre en büyük bölücü 1:8 olabiliyor diye gördüm yoksa atladığım birşey mi var bilmiyorum ?

Diğer sorumda şu , bu Pic Multi-Calc isimli programda ana menüdeki "Timer Help" yada "Timer Calc" seçeneklerinden hangisini kullanacağız ? Ben mesela 4 MHz osilatör frekansında 500 ms'de bir kesme oluşmasını istiyorum . Bu durumda bu programın hangi menüsünü seçip hangi değerleri nereye yazmam gerekiyor .?Timer Helper sekmesindeki Interrupt/Frequency yazan yere 500 ms değerini yazınca programın 8 bit timer bölümünde hiçbir değer göremiyorum .

Yardımlarınızı bekliyorum .
Ω Gens Una Sumus Ω

Hattuşa

peki ustam bu 500mS kesmeyi illa timerin içine oturtman şart mı?
yani şöyle yapsan diyorum:
bir timer kesmesi kursan, kurduğun kesmenin bölme oranı önemli olmasa ve kesmenin içinde bir sayaç çalıştırsan, çalışan bu sayaç istediğin süreye ulaştığında sıfırlasan ve sıfırlarkende başka bir değişkenin durumunu değiştirip işini ona göre yapsan olmaz mı?

ete

Multicalc programında ;
- Timer Calc seçeneğini kullanırsan kullanacağın timer ların parametrelerinide seçerek onu ne kadarlık sürede kesme yarattığını görebilirsin. Kesme yaratmak demek o sayacın maksimum değerini aştığı nokta anlamına geliyor. 8 bitlik sayaçlar için 255 , 16 bitik sayaçlar için ise 65535 değerlerinin aşıldığı noktalar.  Nedir parametreler dersen ekranda görülüyor. Önce işlemci çalışma frekansını giriyorsun. SOnra Sayacın 8 veya 16 bitlik olduğunu seçiyorsun. Sonra sayacın bölme oranını seçiyorsun. sonra ön yükleme değeri seçiyorsun. Bu değeri en sola alarak ön yükleme değerini sıfırlayabiliyorsun. Bu durumda aşağıda saaycın ne kadarlık sürede kesme yarattını görebiliyorsun.

- Timer Helper kısmında ise direk ne kadarlık sürede bir kesme istiyorsan (yada ne kadarlık bir gecikme yaratmak istiyor isen) onu us veya ms seçenklerinden birisini seçip oraya yazıyorsun. Hemen aşağıda girdiğin değer şayet 8 bitlik sayaç ile yaratılabilior ise onun alternatiflerini ve benzer şekilde aynı sürenin 16 bitlik sayaçlarla yaratılmasının alternatiflerini görebiliyorsun.
Yazdığın süreye karşılık 8 bitlik sayaç hanesinde hiç bir değer göremiyor isen o gecikmenin 8 bitlik sayaç ile yaratılmasının mümkün olmadığı anlamına geliyor. Her sürenin her sayaç ile yaratılması mümkün olamıyor.
Bunu test etmekiçin 1 nolu seçeneği de kullanabilirsin. Mesela, 8 bitlik sayaç seç, maksimum bölme oranı olan 1/256 yı seç
Ön yükleme değerini sıfır yap altta yaratılacak enbüyük gecikme değeri olarak 65543 gibi bir değer göreceksin. Aslında teorik olarak bu değer 65535 dir. Program komut gecikmelerinide hesaba katarak onu 65543 olarak hesaplamaktadır ki doğru bir değerdir. Göreceğin gibi 8 bitlik sayaç ile en fazla 65 ms lik bir gecikme yaratabiliyorsun. Sana 500 ms lazım ise elbette 8 bitlik sayaç tarafında bir şey göremeyeceksin.

Kullanım kolaylığı açısından ikinci alternatif daha fazla işine yarayacaktır.

TMR1 maksimum bölme oranı 1/8 dir. Bunu daha önce 1/16 olarak belirtmiş isem hata yapmışım. Burada düzeltmiş olayım.

Ete

Burak

#72
Hocam Onur'un mesajında vermiş olduğu hesaplara göre ;

Alıntı Yap1/4 için

                                              4.000.000 Hz
Counter =   ------------------------------------------------------------ = 976.5
                                       4 x (256-0)x 4 x 1Hz


1/8 için
                                              4.000.000 Hz
Counter =   ------------------------------------------------------------ = 488.28
                                       4 x (256-0)x 8 x 1Hz

1/16 için
                                              4.000.000 Hz
Counter =   ------------------------------------------------------------ = 244.14
                                       4 x (256-0)x 16 x 1Hz

1/32 için
                                              4.000.000 Hz
Counter =   ------------------------------------------------------------ = 122.07
                                       4 x (256-0)x 32 x 1Hz

1/64 için
                                              4.000.000 Hz
Counter =   ------------------------------------------------------------ = 61.03
                                       4 x (256-0)x 16 x 1Hz

1/128 için
                                              4.000.000 Hz
Counter =   ------------------------------------------------------------ = 30.5
                                       4 x (256-0)x 128 x 1Hz

1/256 için
                                              4.000.000 Hz
Counter =   ------------------------------------------------------------ = 15.2
                                       4 x (256-0)x 256 x 1Hz

1:64 bölücüsünü bize verdiği counter(sayaç) değeri bir tamsayı değerine en yakın olduğu ve hata yüzdesini en aza indirebileceğinden bu bölücüyü seçtik . Peki siz Kesme dersinde yaptığınız saati yaparken kullandığınız hesapları nasıl yaptınız ? "Timer Helper" programında "Interrupt/Frequency" kısmına ms cinsinden "1000" yada sıklık cinsinden 1 Hz yazdığımızda sadece 16 bit kısmında değerler görüyoruz . 8 bitlik TMR0'a ait bölümde hiçbişi görmüyoruz . Neden ? Nerede hata yada mantık hatası yapıyorum .
Ω Gens Una Sumus Ω

ete

Bu soruyu soracağın aklıma gelmişti ama basit bir mantık muhakemesi ile sonucu bulavağını düşünmüştüm. Ama bulamadın demekki hala anlamadığın şeyler var. Sorunun cevabı aslında çok basit. 1sn=1000 ms ediyor. Peki bunun içinde kaç tane 10 ms var.  1000/10=100 adet elbette.
Peki multicalc programında süre olarak 10 ms girsen sana 8 bitlik tmr0 tarafında bir şeyler gösterirmi? Gösterir elbette süre küçük çünki. Peki bu durumda ben tmr0 sayacını her 10 ms de bir kesme yaratacak şekilde kursam ve kesmeleride sayac isimli değişkenle ayrıca saysam sayac=100 olunca ne kadarlık süre geçmiş olur. Elbette 10msx100=1000 ms geçmiş olur. İşte saat projesinde yaptığım bu benim. Küçük dilimleri sayarak büyük dikşm elde etme kısaca.
Ete

Burak

Peki hocam anlattıklarınızdan yola çıkarak 1000'e tam bölünebilen değerlerde deneme yaptım .
Bu değerler 2 , 5 , 10 , 20 , 25 , 50  ms değerleri...

Elde ettiğim sonuçlar ise en düşük hata oranlarında şu şekilde .

Preload     Prescaler        Error           Interrupt/Frequency
-------------------------------------------------------------------------
     6             1:8            %0.349                    2 ms
    99            1:32          %0.616                    5 ms
    99            1:64          %0.547                   10 ms
    99            1:128        %0.512                   20 ms
    60            1:128        %0.379                   25 ms
    60            1:256        %0.365                   50 ms

Nihayetinde 2 ms seçeneğinde 500'de , "bir sn" sayacak ama 500 adet "counter=counter+1" komutunun gecikmesinide düşünmek gerekir .
O yüzden 50 ms kesme periodunu seçersek sadece 20 adetlik "counter=counter+1" gecikmesi oluşacak o yüzden 50 ms daha makul bir seçenek diye düşünüyorum . [yanılıyorda olabilirim .]

Ama bir yandan da sizin 8 bitlik TMR0 ile yapılan , önyüklemesiz , 1:64 oranındaki bölücü ile elde ettiğiniz 16384 us'lik kesme periyod süresini düşünüyorum . 1sn değerine tam olarak bölünmüyor .. Sizin değerleriniz için hata oranı hesabı yaparsak

64x256 = 16384 us + 7 (Inst. Cycle) = 16391

1.000.000
------------- = 61,00909035 gibi bir değer elde ediyoruz . 61'e yuvarladığımızda ;
   16391

"% 0.015" gibi mükemmel bir hata oranı veriyor neredeyse "0" yani yukarıda programın 8 bitlik TMR0 için hesapladığı değerlerden bile mükemmel .. İşte sizin bu değeri yerleştirmeyi nasıl akıl ettiğinizi anlayamıyorum yada hala bir yerlerde byük bir hata yapıyorum ...  ??? Yada düşündükçe kafam daha çok karışıyor ..
Ω Gens Una Sumus Ω

Powered by EzPortal