kesme sorunum var ???

Başlatan oguztkn, 02 Ekim 2011, 23:10:49

oguztkn

Picbasicte yeniyim ve Ete Hocanın derslerinden kendimi geliştirmeye çalışıyorum fakat kesme konusunda aklıma takılan bir şey var :
mesela portb.0 dan portb.3 e kadar 4 tane sensör var bunlardan herhangi birinin 1 olmasıyla kesme oluşmasını istiyorum ama 4 ü de farklı işlem yapabilecek bunu basic le nasıl yapabilirim yardımcı olursanız sevinirim....

Şimdiden Teşekkürler.....

ete

Devrende ufak bir tadilat yapman gerekiyor. Zira B portundan kesme oluşturabilecek PortB.0 pini ile PortB.4-PortB.7 arası pinlerdir.
Bu durumda sensörlerini PORTB.4 ve PORTB.7 arasına bağlarsan PortB değişiklik kesmesinden yararlanabilirsin.
PortB.4-7 arasındaki pinlere kesme oluşturma özelliği verilmiştir. Aşağıdaki hususlara uyarsan sorunun hallolur;

PORTB.4 – PortB.7 arası pinlerde değişiklik kesmesi,
Bazen birden fazla pin için kesme özelliğinin kullanılması gerektiği zaman bu kesme özelliğini kullanıyoruz. Bunun için sırası ile aşağıdakileri yerine getiriyoruz.
a) Önce kullanacağımız pinleri giriş olarak ayarlayalım;
TRISB=%11110000
b) INTCON registerinden hem global kesmeler hemde PORTB change kesmesi bitleri aktif edilir.  Bit7=Global kesme biti , Bit3=PortB change Kesme bitidir.
INTCON=%10001000
c) Kesme oluşunca hangi etikete gidileceği ON INTERRUPT GOTO ETIKET komutu ile belirlenir. Biz KES isimli etikete gidileceğini varsayalım ve komutu buna göre yeniden yazalım. ON INTERRUPT GOTO KES
Buraya kadar yapılanlar ile kesme oluşturma işlemi tamamlanmış olur.
Şimdi kesme oluştuğunda gidilecek olan KES  isimli alt programı oluşturalım;
DISABLE
KES:
Buraya kesme oluştuğunda yapılacak işlemler ve komutları yazılır. Sen burada kesme oluşunca sensörlerde ne yapacaksan o komutları yazacaksın.
TEMP=PORTB  şeklinde PortB nin durumu okunarak kesme oluşturmak için portB nin durumu kayıt altına alınır. 
INTCON.0=0  komutu ile kesme bayrağı sıfırlanır.
RESUME
ENABLE
şeklinde alt program sonlandırılır.
Burada kritik komut TEMP=PORTB komutudur. Bu komutu koymazsanız kesme oluşmaz. Çünki işlemci bu komut ile PortB nin durumunu okur ve o durumda kullandığımız o 4 pinde bir değişiklik olur ise kesme bayrağını hemen set ederek programın kesme etiketine dallanmasını sağlar. Bu nedenle TEMPisimli bir Byte değişkeni oluştur ve Koymazsan kesme çalışmaz. Bu nedenle TEMP isimli bir Byte değişkeni oluştur ve kesmeden çıkmadan bu satırı yerine koymayı ihmal etme.

Hepsi bu kadar.
Ete

oguztkn

Öncelikle cevabınız için çok teşşekür ederim hocam kısaca programım şöyle mi olacak ??

TRISB=%11110000
INTCON=%10001000
ON INTERRUPT GOTO KES
DISABLE     bu komutu anlayamadım ?
KES: *bu etiket
*
*buralara kesme oluşunca olucak komutları yazacağım
*
TEMP=PORTB
INTCON.0=0
RESUME
ENABLE *-resume kesme bittikten sonra geldiğin  yerden devam et için yazılıyor ama enable resumeden sonra bunun anlamı nedir ?

ete

#3
Kesme oluştuğu anda başka bir kesme oluşmasını önlemek gerekir. Bunu sağlayan komut DISABLE dir. Bu komut aşağı yukarı şu işlemi yapar  INTCON.7=0 yani global kesmeleri kapatıp yeni kesme oluşmasını önler.

Aynı şekilde kesme etiketinden RESUME ile ayrılırken yeniden kesme oluşturulmasını aktif etmek gerekirki bunuda ENABLE komutu yapar.

Yazdığın kodlar doğru tabiiki ama aralara neler yazılacak onalrda önemli. Ama sıralama doğru. Hemen belirteyim. Kesme nin ne anlama geldiğini iyice öğrenmen gerekir. Özel bir durumdur. İşlemci bir şeyler yaparken kesme oluşunca yaptığı işi bırakır ve kesme etiketine gider ama ayrıldığı yeri unutmaz Kesmede işi bitince tekrar kaldığı yere döner. Bu işin kuralları vardır. Kaldığı yeri hatırlamak için stack denilen geçici veri depolama alanını kullanır. Bu alan aynı zamanda Gosub komutu tarafından da kullanılır. Bu nedenle gosublar iç içe 3 adetden fazla olmamalıdır. Yani bir yere gosub ile gittin oradan dönmeden yeniden bir gosubla başka bir yere gittin ve oradan da dönmeden başka bir yere gosub ile gittin. 3 etti daha fazla gosuble bir yere gitmemen en azından birinden Return ile dönmen gerekir.

Kesme kullanılan programlarda birde ana program bölümü vardır. Orada rutin işlerini yaparsın. Program bu bölümde genelde Basla etiketi ile işe başlar ve arada işler yaptıktan sonra Goto basla komutu ile tekrar basa döner aynı şeyleri yapmaya devam eder. Ama arada kesme oluşursa işi bırakıp kesme etiketindeki işleri yapıp geri döner.
Son olarak Kesme kullanılan programlarda PAUSE komutu kullanmaktan kaçının. Çok gerekiyor ise PAUSE yerine PAUSEUS 5 kullanın. EN büyük gecikme 5us (4 Mhz de) olmalıdır. Çünki kesme oluştuğunda BAsic o anda işlenen komutu bitirmeden kesme etiketine gidemez. Sizde Pause 500 gibibir komut verirseniz ve komutun başında kesme oluşursa ancak 500 ms sonra kesme etiketine gidilir ki orada iş işten geçmiş olabilir. Ama Pauseus 5 komutunu bir döngü içinde kullanırsanız yine 500ms lik bir gecikme yaratabilirsiniz ama kesme oluşursa en geç 5us içinde kesme etiketine gidersiniz. Bu da anında kesme etiketine gitmek demektir. Bu hususa çok dikkat ediniz.

Ete

oguztkn

Hocam tekrar rahatsız ediyorum ama nerde yanlış yapıyorum acaba :

TRISB=%11110000
TRISC=0
PORTC=0
INTCON=%10001000
'--------------------------------------------------------
TEMP VAR BYTE
ON INTERRUPT GOTO KES
'--------------------------------------------------------
basla
    high PORTC.0   'BUNU ÖRNEK OLSUN DİYE YAZDIM
    goto basla
'---------------------------------------------------------
DISABLE     
KES:
   IF PORTB.7=1 then
   low PORTC.0
   low PORTC.4
   low PORTC.5           ' sağ motor ileri
   High PORTC.1
   endif
   
   IF PORTB.6=1 then
   low PORTC.0            ' sağ motor ileri
   low PORTC.1
   low PORTC.5
   high PORTC.4
   endif
   
   if PORTB.5=1 then
   low PORTC.0
   low PORTC.1             'sol motor geri
   low PORTC.4
   high PORTC.5
   endif
   
   IF PORTB.4=1 then
   high PORTC.0
   low PORTC.1
   low PORTC.4               'iki motorda ileri
   high PORTC.5
   endif
TEMP=PORTB
INTCON.0=0
RESUME
ENABLE
end

bir de sensörlerden biri 1 olduğu müddetçe kesme de kalır mı ?
Yardımcı olursanız sevinirim

ete

Ortada bir yanlışlık yok gibi. Eksiklik var.
Eksiklikler;
1.Sigorta ayarlarını vermemişsiniz. Hangi işlemci olduğu belli değil
2. Define OSC 4 şeklinde çalışma frekansını belirtmemişsiniz.
3. Kesme komutunu vermeden önce yaklaşık 250 ms lik bir gecikme koymanız gerekir.
Eksikler bunlar onun dışında bir kusur yok. Denedim sistem çalışıyor.
Girişlerden birisi 1 olursa kesme oluşur ve kesmede belirtilen emirler yerine getiildikten sonra program kesme etiketinden ayrılır. Ekstra bir tedbir almazsanız program kesmede kalmaz. Ama isterseniz kesmede kalabilirsiniz. Girişlerden yalnızca birisine ait örneği yapayım;
   IF PORTB.7=1 then   ' sağ motor ileri
   PORTC=0         
   High PORTC.1
   While PortB.7=1:Wend
   endif

İlave ettiğim While...wend komutu tuş bırakılıncaya kadar programınorada beklemesine sebep olur dolayısıyla kesmeden çıkmamış olursunuz.

Ete


oguztkn

hocam ilgilendiğiniz için teşekkürler
sigorta ve işlemci bilgilerini ekledim şimdi 1 olduğu anda kesme oluyor fakat butonu 1 den 0 a çektiğimde hemen eski haline gelmiyor  bekleme yapıyor ondan sonra kaldığı yerden devam ediyor  bu neden olabilir birde dediğiniz 250 ms gecikmeyi nereye eklemeliyim

kodların son hali de bunlar :
@ DEVICE pic16F877
@ DEVICE pic16F877,WDT_ON
@ DEVICE pic16F877,PWRT_ON
@ DEVICE pic16F877,PROTECT_OFF
@ DEVICE pic16F877,XT_OSC
'*************************************************************************
TRISA=%111111
TRISE=%111
TRISB=%11110000
TRISC=%00000000
TRISD=%00000000
INTCON=%10001000
PORTB=0
PORTC=0
PORTD=0
CLEAR
pause 100
'************************************************************************
TEMP VAR BYTE
ON INTERRUPT GOTO KES
'************************************************************************
BASLA:
    high PORTC.0   'BUNU ÖRNEK OLSUN DİYE YAZDIM
    goto basla
'---------------------------------------------------------
DISABLE     
KES:
   IF PORTB.7=1 then   ' sağ motor ileri   
   PORTC=0           
   High PORTC.1   
   While PortB.7=1
   Wend   
   endif
TEMP=PORTB
INTCON.0=0
RESUME
ENABLE
end

ete

Diğer tuş kontrollerini mahsus mu çıakrdın. Benm yalnızca tek buton için örnek vermiştim. Aynı şey diğer butonlarada uygulanacak idi.
Normalde butonlar 10K dirençle LOW'a çekilmesi gerekir. Böylece elini butondan çekince pin ototmatik olarak low direnci nedeni ile hemen low olur.
Tuş kontrollerini daima HIGH'a çekme (Pull-up) ile yapıp LOW olmuşmu diye kontrol etmekte fayda vardır. Böylece B portundan dahili pullup dirençlerini Option registerinin 7 nolu bitini sıfır yaparak açarsınız. Böylece pinlere ayrıca direnç bağlamak zorunda kalmazsınız.
Zaten devrelerde GND her yerde bulunur bu nedenle butonlara GND çekmek daha kolaydır. Parazit oluşturmaz. Sen tersini yapmışsın.
Ben isisde denedim. AMa butonlara Pull-down direnci bağladım. Dolayısıyla bende gecikme olmuyor idi. Ama nasılbir gecikmeden bahsediyoruz onuda bilmek lazım.
Programınbaş taraflarında Pause 100 komutunu Pause 250 olarak değiştir. En başa sigortalardan sonra ;
Define OSC 4 komutunu ekle.

Ete

oguztkn

Hocam isite çizdiğim şemayı yolluyorum pinleri zaten gnd ye çektim direnç ile anlayamadım sorunu
çalıştırdığım pbp dosyasını birde hex dosyasınıda ekledim diğer butonlarıda bilerek çıkardım bir tanesini halledersem diğerlerine de öyle uygularım diye

ete

WDT programı resetliyor. Bu nedenle Sigorta ayarlarında yer alan WDT ayarlamasını OFF olarak değiştir.
@ DEVICE pic16F877,WDT_OFF
başkada bir şey gerekmez.

Ete

oguztkn

hocam çok kafanızı şişirdim ama wdt nin resetlediğini gördüm off yaptım  şimdide devre başlıyor çalışmaya ben buttona basıp 1 yapıyorum kesme yi yapıyor ama kesmeden çıkmıyor bu seferde orda kalıyor :Q

oguztkn

hocam sorunu buldum  haber vereyim dedim kesme de motor ters dönüyor yani in2 1 kesme çıkışında da in1 1 yaptığından motor kalıyor ana programda in1 i low yaptım düzeldi
yardımlarınız için çok teşekkür ederim kusura bakmayın rahatsız ettim

ete

Tabiiki sorunun ;

    high PORTC.0   'BUNU ÖRNEK OLSUN DİYE YAZDIM

satırı . Bunu sildin zannediyorum. Ben silmiştim. Zira kesmede verilen bir komutu program açılırken vermiş oluyorsun.
Deneme amaçlı olduğu için önce görüp sonra silmiştim.
Dene işlerinde program pinlerini kullanmamayı öğrenmelisin. Yani programda hiç kullanılmayan pinler ile deneme yapmalısın.

Ete

oguztkn

Hocam tekrar rahatsız ediyorum ama son sorum
kesmeyi sizin yardımlarınızla hallettim suan her pının 1 olmasıyla farklı kesmeler yaptım sımdı ıse ıkı pının aynı anda 1 olmasıyla farklı bır kesme yapmak ıstıyorum bunu and ıle mı yapmalıyım ıkı tane ıc ıce ıf ılemı yapmalıyım

ete

Oğuz,
Bu işi yapmanın bir kaç yolu olabilir. Normalde düşünürsen elinde 4 adet buton pini var (4 bit) bunların 4 lü kombinasyonalrı toplam 15 adettir. Yani 15 adet değişik tuş basılma şekli karşına gelebilir anlamına söylüyorum. Ama sanırım sen bu 15 adet yerine yalnızca birkaç tuş kombinasyonu kullanacaksın. Ben olsam şöyle yapardım;
DISABLE     
KES:
   TUSLAR=(PORTB & %11110000)>>4  'tus pinlerini toptan okudum ve 4 bit sağa kaydırdım.
   SELECT CASE TUSLAR
   CASE 1          '...........YANİ PORTB.4=1 KONUMU
   high PORTC.0
   low PORTC.1
   low PORTC.4               'iki motorda ileri
   high PORTC.5   
   
   CASE 2         '.........YANİ  PORTB.5=1 KONUMU
   low PORTC.0
   low PORTC.1             'sol motor geri
   low PORTC.4
   high PORTC.5   
   
   CASE 3        '..........YANİ PORTB.4 VE PORTB.5 BİRLİKTE BASILIRSA
   ...
   
   CASE 4        '..........YANİ PORTB.6=1 KONUMU
   low PORTC.0            ' sağ motor ileri
   low PORTC.1
   low PORTC.5
   high PORTC.4   
   
   CASE 5         '...........YANİ PORTB.6 VE PORTB.4 BİRLİKTE BASILIRSA
         
   CASE 6         '...........YANİ PORTB.6 VE PORTB.5 BİRLİKTE BASILIRSA
   
   CASE 7         '...........YANİ PORTB.6 - PORTB.5 VE PORTB.4 BİRLİKTE BASILIRSA   
   
   CASE 8        '...........YANİ PORTB.7=1 KONUMU
   low PORTC.0
   low PORTC.4
   low PORTC.5           ' sağ motor ileri
   High PORTC.1
   
   CASE 9         '..........YANİ PORTB.7 VE PORTB.4 BİRLİKTE BASILIRSA
   
   CASE 10        '..........PORTB7 VE PORTB.5 BİRLİKTE BASILIRSA
   
   CASE 11        '..........PORTB.7 VE PORTB.5 VE PORTB.4 BİRLİKTE BASILIRSA
   
   CASE 12        '..........PORTB.7 VE PORTB.6 BİRLİKTE BASILIRSA
   
   CASE 13        '..........PORTB.7 - PORTB.6 VE PORTB.4 BİRLİKTE BASILIRSA
   
   CASE 14        '..........PORTB.7 - PORTB.6 - PORTB.5 BİRLİKTE BASILIRSA
   
   CASE 15        '..........4 TUSUN HEPSİNE BİRLİKTE BASILIRSA
   
   END SELECT
TEMP=PORTB
INTCON.0=0
RESUME
ENABLE
end

Mutlaka kullanmayacağın kombinasyonlar olacaktır. Onları kodlardan sil . Mesela Case 15 olası bir durum olamaz. O halde CASE 15 mkonumunu sil çıkart. Yalnızca muhtemel kombinasyonları bırak . Tabiiki o konum meydana geldiğinde ne yapılacak ise altına yazman gerekiyor. Mevcutları ben yazdım zaten ama sen yinede kontrol et yanlış olabilirler.

Ete

Powered by EzPortal