Rotary encoder ve uzaktan kumanda sorunu

Başlatan crazy4blue, 28 Ekim 2014, 00:22:51

crazy4blue

Arkadaşlar merhaba.  açıkçası bu işlerde yeniyim. normalde yazılımcılık tabanı var ama pic konusuna 3 ay oldu gireli.

işin özü şu. bir amfi devresi için  pga2311 entegresi ile ses kontrolü üzerinde çalışıyorum. herşey gayet güzel.    fakat bu sistemde hem rotary encoder hem de uzaktan kumanda kullanılıyor.  ikisinin kodlarını projeye aynı anda eklediğimde sadece birisi çalışıyor. ya kumanda ya rotary encoder. ama tek tek eklediğimde hem kumanda hemde rotary de sıkıntı yok.  proje dosyalarını buraya ekliyorum.  acaba kesmeler mi çakışıyor. (başka bir tabir bulamadım :)
derleyici olarak proton kullanıyorum
şimdi dikkatimi çeken bir konu protonun uzaktan kumanda için sonyin komutu var. bu komutu kullandığım anda kesmeye giriyor ve bir daha kesmeden çıkamıyor(daha doğrusu ben isis simülasyonunda çıkartamıyorum.) dolayısı ile diğer işlemleri yapamıyor. ekte isis dosyası ve kaynak kodu mevcut.
not:işlemci olarak pic 16f877 kullanıyorum.
fyardım ederseniz çok sevinirim.

ete

Birden fazla kesme kontrolü yapılan programlarda kesme ayrımı genelde kesme bayraklarına bakılarak yapılır ve kesmeyi hangi kaynak  oluşturmuş ise program ona uygun etikete yönlendiririlir.
SeninMultikesme kısmında buna benzer bir mantık ya göremedim yada karmaşadan dolayı fark edemedim. İzahatı sen yaparsan sevinirim. O multi kesme ksımınınmantığı nedir. İlk satırlarda encoder kontrolü yer alıyor o tamam da progra sonrasında yer alan etiketleri neye göre değerlendiriyor.?

Kesme etiketi çok özel bir yerdir. Temel mantık bu yerden mümkün olduğunca çabuk çıkılması yönünde kurulmalıdır. Bir kesme içinden ,
If PORTD.5 <>1 Then GoTo son gibi bir satırla çıkacağıma bu satırı ana program içine koyar ve
If PORTD.5 <>1 Then kesme iptal  şeklinde tercihimi kullanırdım. Böylece kesme içinde fazladan bir satır olmazdı. Ne anlama geliyor bilmiyorum ama kesmeyi meşgul edecek satırlardak kaçınmak gerekir.
Yine, bir encoder okumasını enable yapabilmek için iki şart oluşturmuşsun,
If POWER_DURUM =1 Then
If BTN_DISABLE <> 1 Then   
bunlar olursa encoder okunabiliyor. Her biri kesme için eziyet bence daha iyi bir mantık kurulmalı.

Diğer bir konuda encoder okuması;
  new=  PORTD & %01100000   
    If new=old Then
    zaman=zaman+1
    If zaman=50 Then GoTo son
    satırları sıklıkla benim kullandığım ve kesme kullanmadan encoder okumak amacı ile geliştirdiğim bir mantık olup encoderin dönüp dönmediğini 50 kere kontrol ederek dönmüyorsa okuma işini terketmeyi amaçlayan bir mantıktır.
Kesme kullanacak isem her şey farklı olmalıdır. Zira encoder dönecek ise kesme oluşur dönmüyorsa program kesmeye girmez şeklinde düşünmek gerekiyor.
Yukarıdaki satırlarda program 50 defa encoder girişlerinde değişiklik varmı yokmu diye bakacak ve boşuna oralarada takılacaktır. Böyle olunca kumanda çalışmayacaktır elbette.
Bu arada zaman zaman Proton kullanmam yönünde öneriler alıyorum. Baqkın bu programa kesme var ama hangi kesme aktif belli değil. Çalışıp çalışmadığından emin değilim ama programa bakınca hangi kesmelerin aktif edildiğini görmem lazım. Burada göremiyorum. Sebebi Proton olmayabilir.
Encoder in kesme ile okunmasında temel mantık A ve B pinlerinin kesme oluşturacak şekilde kullanılmasıdır. Bu ya 18F serisinde bir işlemci ile INT0 ve INT1 pinlerine bağlanacak yada PortB değişiklik kesmesi kullanılacaktır.
Programa başlarken encoder pinleri bir kere okunacak sonrasında sistem otomatik çalışacaktır. Okunan ilk değer eski değeri olacak ve kesme oluştuğunda okunan değerde yenisi olacaktır. Bu aşamada 50 defa kontrol gerekmeyecektir. Anında okuma değerlendirilip kesmeden çıkılması gerekiyor.
Buna ait örneği geçenlerde vermiştim. İşte linki,
http://etepic.com/index.php/topic,1967.0.html
Kesme içinde ana program bölümünde yer alan bir alt etikete Gosub ilede olsa gidilmemesi gerekir. PBP da bu stack taşmasına sebep olur. Protonda ne gibi sorun yaratıyor bilemem ama bence kusurlu bir işlem. Gosub Display diye bolca kullanmışsın. Kesme içindeki işlemler o çerçevede halledilmelidir. Gerekirse ekrana verme komutlarını yeniden yaz ama başka yere gönderme programı.

Program epeyce uzun ve olaya tam hakim olmayınca incelemesi zor oluyor. Bu nedenle önce sen anlattıklarıma göre yeniden değerlendirme yap. Yazdıklarımın bazıları yanlış değerlendirme  olabilir. Kesme içinde bir IF RBIF ile başlayan bir satır gördüm bu kesme bayrağının değerlendirilmesidir. Ama en başta böyle bir şey yok terslik buradan geliyor.
Sonra gerekirse yeniden değerlendirelim.

Kumanda okuma bit bazında ve zaman esaslı bir işlemdir. Kumada okurken kesme gelirse okunan kumanda kodundan hayır gelmeyecektir. Bu nedenle tedbir almak gerekir. Mesela yeni kesmeden çıkılmış ise kumanda okumasına gidilebilir. İki kesme arasında kumanda mutlaka okunabilir. Bunu sağlamak için kesme içinde bir bit değişkeni set edilir (YENI=1) ve öyle çıkılır. Kumanda okunurken IF YENI=1 THEN deyip kumanda okuma işlemi gerçekleştirilebilir. Böylece en azından okuma ortasında kesme gelme ihtimalini en aza indirgemiş olursun. Bu benim çok kullandığım bir yöntemdir ve epeyce faydasınıda görüyorum.

Ete

crazy4blue

ete hocam üşenmeyip yazmışsınız çok teşekkür ederim.
aslında bu daha önce başka bir kişi tarafından yapılmış bir projenin  geliştirilmesi diyebiliriz. özellik katma. projenin aslında lcd yerine display kullanılıyordu.   
dediklerinizi göz önüne alıp hataları inceleyeceğim.      gerekirse baştan çok daha sade bir şekilde bu işi yapmaya çalışacağım.

crazy4blue

hocam bu kesme bayraklarına göre nasıl yönlendirebiliriz.     örnek bir kodunuz var mı acaba

ete

#4
İşlem çok basit. Diyelimki program içinde PORTB.0 kesmesi, PortB değişiklik kesmesi ve TMR0 kesmesi kullanıyoruz.
PORTB.0 kesmesi bayrağı INTCON.1 (INTF) ,
PORTB değişiklik kesmesi INTCON.0 (RBIF),
TMR0 kesmesi bayrağı      INTCON.2(TOIF),
Program aktive edilmiş her hangi bir kaynaktan dolayı kesme etiketine gelirse bu bayrakları sorgulayarak işe başlarız.
Örneğimizde 3 alternatif var,  iki sini en azından test ederiz,
KESME:
IF TOIF=1 then ATLA_TMR0
IF INTF=1 then ATLA_B0
Bu satırdan itibaren her hangi bir if yazmaya gerek yok 3 alternatiften ikisi değilse üçüncü alternatiftir kesin olarak ve buradan itibaren RBIF =1 olduğunu kabul edip ona ait bölümü yazarız. Bu bölümden çıkmadan önce kesme bayrağını sıfırlar ve GOTO ATLA diyerek çıkışa gideriz.
Bu satırdan itibaren TOIF kesmesi başlar. Yani
ATLA_TMR0:
altına bu kesmeye ait program satırlarını yazıp bayrağı sıfırlayıp
Goto ATLA diyerek çıkışa gideriz.
Bu satırdan itibaren artık ATLA_B0 etiketi yer alır Yani,
ATLA_B0: 
Buralara bu kesmeye ait satırları yazar ve bayrağı sıfırlayıp
CIKIS:
...
RESUME
ENABLE
şeklinde yada Protonda nasılsa ayarlayıp kesmeden çıkarız.

Ete

crazy4blue

Teşekkür ederim hocam. anlatıklarınıza uygun bir şekilde baştan yapacağım ama olsun. hem öğrenmiş olurum hem de  sorunsuz bir şekilde olmuş olur.

crazy4blue

ete hocam çok sağolun. verdiğiniz tekniklerle bütn projeyi sıfırdan yazıyorum. ayrıca encoder için de sizin yine başka bir proje de gösterdiğiniz donanım desteği (4013 lü) olan versiyondan alıntı yaptım.çünkü   hem uzaktan kumanda hem de encoder aynı anda  kullanazağım için yazılım tabanlı encoder kodlarında kaçırma atlama oluştu.  diğerinde simülasyonda şimdilik yağ gibi akıyor.

Powered by EzPortal