Fonksiyon için interrupt seçimi.

Başlatan enrique34, 26 Mart 2016, 14:26:46

MB_77

#15
bu mesaj tarafımdan silinmiştir.

ete

#16
Bu işin PortB değişiklik kesmesi ile olmayacağını düşünüyorum. Olursada aşağıdaki gibi olur.
Zira elinizde 1 timer ve 4 ayrı kanal var. Hangi birini ölçeceksiniz.?
İkincisi PortB değişiklik kesmesinde kesmenin hangi kenarda olacağını belirleme imkanınız yok maalesef.
Başlangıçta diyelimki yükselen kenarda kesme oluştu. Timer sıfırlandı. Düşen kenarda kesme bir başka kanal tarafından da oluşturulabilir. Bu durumda siz yine 1. kanal için değer almaya çalışırsanız hata yaparsınız. Kesmeyi 2. kanal oluşturdu ama siz 1 ci kanal için değer alacaksınız. Olamaz böyle.

Bu işin olabilmesi için hangi kanal için çalıştığınızı bileceksiniz. Bu amaçla bir sıralama yapılabilir.
SIRA isimli bir değişkeniniz olur.  SIRA=1 dir başlangıçta. Bu timer 'ın PORTB.4 için çalışacağını belirler.
PORTB.4 girn sinyalin ölçümü tamamlandıktan sonra SIRA=SIRA+1 yapılır ve SIRA=2 olur. Bu timer1'in PORTB.5 den giren sinyal için çalışacağını gösterir. Ölçüm tamamlandıktan sonra SIRA=SIRA+1 yapılır SIRA=3 olur. İşlem tamamlanınca yeniden SIRA=SIRA+1 yapılıp SIRA=4 elde edilir. Böylece her bir kanal için sırası ile TMR1 kullanılarak ölçüm yapılmış olur.
Programın başınd SIRA=1 yapılması gerekir unutmayın. Bu yazdığım kodlar yalnızca sinyallerin HIGH sürelerini ölçer.
LOW süreleri için ayrıca kod yazmak gerekir. Onuda siz yaparsınız artık.
PORTB değişiklik kesme bayrağı direk ulaşılıp sıfırlanabilen bir bayrak değildir. Portun durumunu okuduğunuz zaman işlemci tarafından otomatik sıfırlanır bu bayrak. Boşuna RBIF=0 yazmayın . Derleyici itiraz etmez ama bir şeyde yapmaz benim bildiğim. ARA=PORTB komutu bu işi otomatik yaptırır. Zaten değişiklik kesmesinin çalışabilmesi için Portun durumunu kesmeden çıkamdan okumanız gerekirki bir değişiklik olduğu zaman doğru kesme oluşabilsin. Sizin kodlarda eksik olan bir husus bu.

Şimdi kesme kısmına bakalım;
Disable
KESME:
      select case SIRA
         TEMP.BYTE0=TMR1.BYTE0
         TEMP.BYTE1=TMR1.BYTE0     
      CASE 1                 
         IF portb.4=0 THEN  'High'dan Low'a geçiş.
           OLC1=TEMP         
         ELSE
           OLC1=TEMP-OLC1   'Low'dan High'a geçiş 
           SIRA=SIRA+1         
         ENDIF

       case 2
         IF portb.5=0 THEN  'High'dan Low'a geçiş.
           OLC2=TEMP         
         ELSE
           OLC2=TEMP-OLC2    'Low'dan High'a geçiş
           SIRA=SIRA+1
         ENDIF         
     
       CASE 3
          IF PORTB.6=0 THEN
             OLC3=TEMP
          ELSE
             OLC3=TEMP-OLC3
             SIRA=SIRA+1
          endIF
             
        CASE 4
           IF PORTB.7=0 THEN
              OLC4=TEMP
           ELSE
              OLC4=TEMP-OLC4
              SIRA=SIRA+1
           ENDIF
        END SELECT     
        IF SIRA=5 then SIRA=1
        ARA=PORTB  'bu komut Kesme bayrağını temizlemek için gerekli
        RESUME
        ENABLE



MB_77

#17
bu mesaj tarafımdan silinmiştir.

enrique34

Bilgiler çok güzel, teşekkür ederim... Farklı bir bakış açısı oluştu 16f1826'da bu özelliği bilmiyordum. Gerçi flash 8kb biraz küçük ama istediğim bir özellik mevcutmuş. Şimdi bunlardan bir mix yapıp farklı bir algoritma deneyip paylaşacağım....

MB_77

#19
bu mesaj tarafımdan silinmiştir.

enrique34

16f1826 ne kadar gıcık bir işlemci imiş. Gece sadece lcd'ye selam yazmak için uğraştım. Pic'i çalıştıramadım, evet özellikleri hoş ama kurması zahmetli geldi. Neyse sorun o değil lcd komutu dediğiniz gibi çok kayıp veriyor (16mhz)'de. Kesme yükselen kenar ayarlaması daha sonra düşen kenarına çekerek ve sizin mantık ile ete hocamın select case ile güzel sonuçlar alabildim. Ancak kafamı karıştıran sanırım program döngüsünde pek bir şey yapamayacağım galiba görüntü onu gösteriyor. Bu okuduğum sinyali evirip çevirip aynı modulasyon ile farklı pinlerden çıkaracaktım herhalde baya bir sekteye uğrayacak..

MB_77

#21
bu mesaj tarafımdan silinmiştir.

enrique34

#22
Bende biraz farklı bir yöntem buldum kendimce TARAMA yöntemi diyorum, yine aynı kalıplarla, ancak bir sorun var :)
Şimdi bir kanal ölçümü için;
1) TMR0 kullanıyorum TMR0=255 diyorum yani her bir cycle'da kesme oluşturuyorum...
2) İşlemcim 4Mhz ve prescaler 1:2 olduğuna göre 2uS 'de tarama yapmış oluyorum
3) 2uS'de bir gidip portumun durumuna bakıyorum ve us isimli değişkene 1 ekliyorum. (16bit sayma için)
4) Bu durumda kaçırsın kaçırsın 10us kaçırsın
Geçtim 4 kanalı bir kanal için ölçüm yapıyorum;
Şimdi farklı ölçümlerdeki saçmalıklar bu şekilde veya artık kafam basmıyor saçmalık bende mi? :S
1000us = 20us
1350us = 27uS
1745us = 35uS
1983uS = 39uS


Disable
int:
If us=65535 Then us=0
us=us+1
If PORTB.7=1 And ch1_status=0 Then
tmr1_first=us
ch1_status=1
EndIf
If PORTB.7=0 And ch1_status=1 Then
tmr1_second=us
ch1_status=0
    If tmr1_first>tmr1_second Then
    ch1_count=(65535-tmr1_first)+tmr1_second         
    Else
    ch1_count=tmr1_second-tmr1_first
    EndIf
    Print At 1,3,Dec5 (CH1_COUNT*100)/2
EndIf
TMR0L=255
TMR0IF=0
Resume
Enable
End


ayarlarımda şu şekilde;


TRISB =%10000000
INTCON=%10100000 'TMR0 İZİN VERİLDİ
T0CON =%11000000 'TMR0 AÇILDI, 8BİT SAYMA, 1:2 prescaler
TMR0L=255
Dim us As Word
Dim tmr1_first As Word
Dim tmr1_second As Word
Dim ch1_count As Word
Dim ch1_status As Bit
ch1_status=0
us=0
tmr1_first=0
tmr1_second=0
On Interrupt GoTo int
Enable

MB_77

#23
bu mesaj tarafımdan silinmiştir.

enrique34

Bu yazanlar dışında başka hiç bir şey yok... 

Start:

Goto start

Rahmetli babam derdiki dereyi geçmek için at değiştirilmez :)
16f1827 biraz sinirlerimi bozdu datasını baştan okumam gerek vaktim olmadı. Aslında çok güzel özellikleri varmış.

MB_77

#25
bu mesaj tarafımdan silinmiştir.

enrique34

Evet sorun bir şekilde çözülüyor teşekkür ederim ama benim asıl sorunum temelde gizli :)
Gerçi erol hocaya da bir mesaj attım umarım ilgilenir ama mantıksızlık bunun neresinde anlayamadım. Bir nevi olayı çözmeye çalışıyorum...
Bu nasıl bir dip kuyudur :) Mutlaka gözden kaçan bir durum var. Onu bilmeliyim yoksa uyku falan yok bana :) üstüne düştükçe saçma sapan hatalar yapmaya başlıyor insan... :
Bu kod çalışıyor evet ama çıktıları neden bu kdar farklı...
1000us = 20us
1350us = 27uS
1745us = 35uS
1983uS = 39uS


Device 18F452
Xtal = 4
Declare LCD_Interface 4
Declare LCD_Lines 4
Declare LCD_DTPin PORTD.4
Declare LCD_ENPin PORTD.2
Declare LCD_RSPin PORTD.3
TRISB =%10000000
INTCON=%10100000 'TMR0 İZİN VERİLDİ
T0CON =%11000000 'TMR0 AÇILDI, 8BİT SAYMA
TMR0L=255
Dim us As Word
Dim tmr1_first As Word
Dim tmr1_second As Word
Dim ch1_count As Word
Dim ch1_status As Bit
ch1_status=0
us=0
tmr1_first=0
tmr1_second=0
On Interrupt GoTo int
Enable

start:

GoTo start

Disable
int:
If us=65535 Then us=0
us=us+1
If PORTB.7=1 And ch1_status=0 Then
tmr1_first=us
ch1_status=1
EndIf
If PORTB.7=0 And ch1_status=1 Then
tmr1_second=us
ch1_status=0
    If tmr1_first>tmr1_second Then
    ch1_count=(65535-tmr1_first)+tmr1_second         
    Else
    ch1_count=tmr1_second-tmr1_first
    EndIf
    Print At 1,3,Dec5 ch1_count
    End
EndIf
TMR0L=255
INTCON.2=0
Resume
Enable
End


MB_77

#27
bu mesaj tarafımdan silinmiştir.

ete

Enrique34,
Özel mesaj atmışsın ama cevabı buradan vermek daha doğru.
Bu olaya çok fazla konsantre değilim ve çok sağlıklı bir cevap vermem mümkün değil.
Ama şöyle bir bakınca işlemci 4 Mhz ile çalışıyor ve bütün olay kesme içine sıkıştırılmış durumda.
Bu durumda işlemci kesmeye bir girince kolay kolay çıkamıyacak ve arada gelen bir sürü palside kaçırmış olacaksın anlamına geliyor bu.

Gerçekten basit bir işlemci için zor bir konu. Kolaylıkla halledilebileceğini (kesin doğrulukla ölçüm yapılmasını kast ediyorum) sanmıyorum. Doğruya yakın sonuçlar elde edilebilir ama işlemci frekansınıda artırmak gerekir. Böyle bir sistemin çalışabilmesi için en azından 30-40 Mhz lik bir çalışma frekansı olması faydalı olur. Akis halde işlemcin 4 Mhzde bu 4 kanalı aynı anda işleyemez.  Diğer bir sorunda ana programda sıfır işlem ama kesme içinde bütün ekran gösterimleride dahil her şey orada. Bu mantıkla çalışan bir programdan nasıl bir randıman bekliyorsunki.
Bu sistemin çalışması için kesme içinde sıfır komut gecikmesi olması gerekirdi. Ama her şeyi oraya koyunca bir kere kesmeye girince kolay kolay işlemci oradan çıkamıyor ve arada da diğer pulsler gelip gidiyor. Mantıksızlık burada bence.

Ete

enrique34

#29
Alıntı yapılan: MB_77 - 30 Mart 2016, 16:45:14
galiba ben senin olayı çözdüm ama söylemem gizli :)

birincisi us=us+1 ifadesi yanlış çünkü 2us de bir arttığından us=us+2 olmalıydı. ama tabi gizli hata hala devam ediyor :)

timer1 ne yapıyordu? pals boyunca durmadan sayıyordu. timer0 napıyor o da sayıyor ama sen kaale almıyorsun. sadece kesmeye giriş sayısını dikkate alıyorsun. kesme rutini 2usde tamamlansaydı mantık çalışırdı ama rutin daha uzun sürüyor dolayısıyla timer0'ın saydıklarını kesme çıkışında 255'e eşitleyerek çöpe atıyorsun.

Evet o kesin onun farkındayım ama çok ufak bir us çıktısı alıyorum garip değil mi :) us+2 olayı gözden kaçmış evet beynim dondu :)

Alıntı yapılan: ete - 30 Mart 2016, 16:54:42
Enrique34,
Özel mesaj atmışsın ama cevabı buradan vermek daha doğru.
Bu olaya çok fazla konsantre değilim ve çok sağlıklı bir cevap vermem mümkün değil.
Ama şöyle bir bakınca işlemci 4 Mhz ile çalışıyor ve bütün olay kesme içine sıkıştırılmış durumda.
Bu durumda işlemci kesmeye bir girince kolay kolay çıkamıyacak ve arada gelen bir sürü palside kaçırmış olacaksın anlamına geliyor bu.

Gerçekten basit bir işlemci için zor bir konu. Kolaylıkla halledilebileceğini (kesin doğrulukla ölçüm yapılmasını kast ediyorum) sanmıyorum. Doğruya yakın sonuçlar elde edilebilir ama işlemci frekansınıda artırmak gerekir. Böyle bir sistemin çalışabilmesi için en azından 30-40 Mhz lik bir çalışma frekansı olması faydalı olur. Akis halde işlemcin 4 Mhzde bu 4 kanalı aynı anda işleyemez.  Diğer bir sorunda ana programda sıfır işlem ama kesme içinde bütün ekran gösterimleride dahil her şey orada. Bu mantıkla çalışan bir programdan nasıl bir randıman bekliyorsunki.
Bu sistemin çalışması için kesme içinde sıfır komut gecikmesi olması gerekirdi. Ama her şeyi oraya koyunca bir kere kesmeye girince kolay kolay işlemci oradan çıkamıyor ve arada da diğer pulsler gelip gidiyor. Mantıksızlık burada bence.

Ete

Erol hocam evet farkındalık yaratmak istedim.. Arkadaş ile baya cebellendik bu konuda. Dediğinize katılıyorum ama şimdi sorun başka yöne gidiyor. 1000uS lik bir sinyali okumak için örnek olarak yazdığım bir kod lcd gecikmesini yok sayar isem bunun bana dönüşü 20uS oluyor. yani kolay kolay kesmeden çıkıyor ama sinyali öyle bir okuyor ki işin garip tarafı her biri iki katının 100'e bölünmüş hali geliyor. İlginç değil mi?

Powered by EzPortal