Aynı programın bazı işlemcilerde sorunlu çalışması

Başlatan Yasin, 03 Ekim 2018, 00:31:15

Yasin

Merhabalar. Yaklaşık 1000 satır uzunluğunda bir program yazdım bir proje için. Ancak program her PIC'de düzgün çalışmıyor. 16F628A kullanıyorum. 50 taneye attığım program yarısında düzgün çalışıyor. Diğer yarısında hatalı çalışıyor. Hatalı çalışanlarda da hep aynı hatalar oluyor. (Mesela hatalı çalışanlarda enerjiyi keserken röle çek bırak yapıyor, ana program altında çalışan girişe göre led yaktığım satır düzgün çalışmıyor vs.) Ama düzgün çalışanlar gayet sorunsuz pürüz çıkarmadan çalışıyor. Programda şüphelendiğim 2 nokta var.

1. 2 dijit 7 segment display var devrede. Ve bu segment pinlerine bağlı inputlar var. Tarama yöntemiyle display ve inputları aynı pinlerden kullanıyorum. (Kartın tasarımı öyle, hazır bir karta yazdım programı) Display ve inputlar arası geçiş yaparken input yaptığım zaman Option_Reg'in 7. bitini 0, displaye geçtiğim zaman 1 yapıyorum ve bu sürekli ana program ve alt programların altında 0-1 olarak değişiyor. Bundan dolayı olabilir mi?

2. Program yüklerken bilgisayar veya programlayıcı kaynaklı olabileceğini düşünüyorum. Ama farklı programlayıcı ve bilgisayarlarda denedim. Değişen bir şey yok. Sizce neden olabilir sorun?

Dahili osc. kullanıyorum. Sigorta ayarları şu şekilde:

@ __config _INTRC_OSC_NOCLKOUT & _WDT_OFF & _MCLRE_OFF & _LVP_OFF & _CP_OFF & _BODEN_OFF

ete

Bir pini hem input hem output olarak kullanabilirsin ama Option_Reg ile bunu değiştirme fikrine katılmıyorum.
Option_Reg.7 biti yalnızca B protundaki pullup ları açar ve kapatır. Ama pinin giriş çıkış olma özelliğini değiştirmez.
Programı buraya koymadığına göre çekincelerin var saygı duyarım ama yapman gereken şey Giriş Çıkış değişkliği için ya TRISX.y şeklinde değiştirmen yada INPUT PORTB.x veya OUTPUT PORTB.x şeklinde bir komut kullanmandır.
Daha fazla yorum yapabilme imkanım yok maalesef. Kimisinde çalışması kiminde çalışmaması bence tamamen tesadüf. Nasıl çalıştığını yada çalışır gibi yaptığınıda anlamadım maalesef.
Ete

Yasin


İlyas KAYA

Boden_on , pwrte_on yapip deneyin
Boden i kapatırsanız 2.5voltun altına besleme indiğinde resette kalmaz ve mcu nun ne yapacağı belli olmaz. Programı incelemedim ilk olarak bunu bir deneyin.

Göz odur ki dağ ardını görsün,
Akıl odur ki başa geleceği bilsin.!

ete

Bir programın bazen çalışıp bazen çalışmaması yada senin deyiminle bazı işlemcilerde çalışıp bazılarında çalışmaması konusunda tecrübelerim bana stack taşması gibi etkenlere dikkat edilmesini söyler.
Programına genel olarak baktım. Genelde kaidelere uygun gözükürken aşağıdaki alt programda bir kusur gördüm.
IF OLHATA=0 THEN   
      INPUT OL:OPTION_REG.7=0
      IF OL=0 THEN
         OPTION_REG.7=1:OUTPUT OL
         OLHATA=1
         GOTO ALARM
      ENDIF
      OPTION_REG.7=1:OUTPUT OL
   ENDIF   

Bu bölüm GOSTERGE isimli alt programın bir parçası. Ana programdan buraya GOSUB ile gelinmektedir.
Ancak yukarıdaki kodun içine bakarsan GOTO ALARM şeklinde bir satır var ve bu stack taşması yaratacak nitelikte bir komut. Gosub ile geldiğin bir yerden GOTO ile başka bir yere gidiyorsun ve oradan sonrası ne oluyor takip etmedim. Alarm kısmında sanki program sonsuz döngüye sokuluyor gibi. Aralarda bir sürü gosub bulunuyor. 16F628 gibi bir işlemcide peş peşe ancak 3-4 tane Gosub peş peşe kullanılabilir fazlası stack taşması meydana getirir.
Bunları yazıyorum çünki dikkatini bu yöne çekip programını henüz programa hakim iken tekrardan kontrol edebilmeni sağlamak için.
Genel kaideler şunlar mutlaka biliyorsundur. Bende biliyorum ama ben bile zaman zaman bu hataları yapabiliyorum.
1. Gosub ile gidilen yerden mutlaka çıkış yada dönüş RETURN ile yapılmalıdır. Programı sonsuz döngüye sokmuş olsan bile önce bir işaret bitini set edip Return ile dönmen ve döndüğün yerde tekrar işaret bitini kontrol ederek gerekirse oradan sonsuz döngüye girmelisin.
2. Peş Peşe Gosub komutunu kullanmak işlemcinin stack kapasitesine bağlıdır. 16F628 için bu 3-4 belkide 5 adet den fazla olmamalıdır.

Programı hala inceliyorum. Başka bir olumsuzluk görürsem bilgi veririm.
Bu arada ilyas'ın dediklerine de dikkatini çekerim. Söyledikleri doğrudur.
Ayrıc İşlemcileri sonuna kadar zorlamadıktan sonra kalitelerini anlamak zor. Ama yüklü programlar bazı işlemcileri zora sokabiliyor. İşlemci aldığın yerede dikkat etmen gerek. Aynı seriden eleman almaya özen göstermelisin.

Son olarak Option_Reg registerinde bir kere pullup ları set etmen yeterli. Pin giriş olunca otomatikman devreye girer. Pin Çıkış olunca ise zaten devre dışıdır. Buna bağlı olarak fazlalıkları silde program biraz hafiflesin bari.
Ben olsam Optin kontrolünü devre dışı bırakır ve her birine gosub ile gidilen o satırları kaldırıp gereken yerde INPUT yada OUTPUT komutlarını kullanarak bir sürü GOSUB dan programı kurtarırdım.

Ete

Yasin

@ete hocam evet farkındayım o kısmın. Normalde o program parçasında ilk başta Alarm etiketine GOTO ile dallandıktan sonra enerjiyi kesene kadar oradan çıkmıyordu. Basit bir şekilde displaye yan sön yaptırıp siren rölesinin çek bırak yaptırıyordu o kadar.O nedenle zaten enerji kesilince stack sıfırlanacağı için uğraşmamak adına öyle yapmıştım. Sonrasında birkaç değişiklik yapmam gerekti. Alarm etiketinden başka yerlere gitmem gerekti. Orası öyle kaldı ellemedim ilk başta şuan ki soruna yoğunlaşmak amaçlı. Zaten program oraya bir pinin durumuna göre gidiyor. Test yaparken bile programın o kısmını hiç çalıştırmıyorum.

Alıntı YapSon olarak Option_Reg registerinde bir kere pullup ları set etmen yeterli. Pin giriş olunca otomatikman devreye girer. Pin Çıkış olunca ise zaten devre dışıdır. Buna bağlı olarak fazlalıkları silde program biraz hafiflesin bari.
Ben olsam Optin kontrolünü devre dışı bırakır ve her birine gosub ile gidilen o satırları kaldırıp gereken yerde INPUT yada OUTPUT komutlarını kullanarak bir sürü GOSUB dan programı kurtarırdım.

Onu bilmiyordum hocam o zaman başlangıçta bir kere pull-up dirençlerini aktif etmem yeterli. Aslında önceden dediğiniz gibi giriş ve çıkış ayarı için gosub ile gitmeden önce giriş yapıp gosub dönüşü sonrası çıkış yapıyordum ama program hafızasının sınırına yaklaştığım için giriş çıkış ayarlarını da gosub içindeki buton algılama programcıklarına dahil etmek zorunda kaldım. İşin tuhaf olanı aynı programı 16F648 ile denediğimde de aynısı oluyor. Bazılarında düzgün çalışıyor bazılarında hatalı çalışıyor. Bu akşam biraz daha uğraşacağım.

@İlyas KAYA Sigorta ayarlarını dediğiniz şekilde düzenleyeceğim.

Yasin

Sorunları çözdüm.

Enerji kesilirken röle çekip bırakmasını şöyle çözdüm. Bir tane giriş pininin durumuna göre (OL pini) Alarm isimli programa gidiyordum. OL pini 0 olunca direkt Alarm'a gidiyordum. Burada soruna neden olan kısım pin 0 olunca direkt işlem yaptırmam imiş. Olay şöyle oluyor. Enerjiyi kestiğimde beslemedeki kondansatörler boşalana kadar işlemci bir süre daha çalışıyor. Gerilim artık belirli bir seviyenin altına indiğinde 16F628 çalışmaya devam ediyor ama OL pini giriş olarak kullanılmasının yanı sıra displaye de bağlı olduğu için OL pinindeki gerilim daha düşük oluyor. Dolayısıyla işlemci çalışmaya devam etse bile OL pini sürekli 1 olması gerekirken 0 olarak algılanıyor ve işlemci Alarm programına geçerek alarm rölesini çektiriyor. Röle çekince zaten kondansatörler tamamen deşarj oluyor ve o anda hemen röle bırakıyor. OL pini 0 olunca hemen Alarm programına gitmek yerine OL pini 3 saniye boyunca 0'da kalırsa Alarm programına gidecek şekilde programı düzenleyince röle çekip bırakma sorunu çözülmüş oldu. Bu hatayı her işlemcide yapmamasını ise işlemcilerin giriş lojik 0 ve lojik 1 algılama eşiklerinin toleranslarına bağlıyorum. İşin tuhaf olanı ise Boden açık olsa bile kurtarmıyor olması.

Ledin düzgün çalışmama sorununu ise iç içe olan IF döngülerinde yaptığım ufak bir hatayı düzelterek çözdüm. (En dıştaki IF döngüsü içine koyacağım satırı bir içteki IF döngüsüne koymuşum.)

@ete, @İlyas KAYA

Yardımlarınız için çok teşekkür ederim.

Powered by EzPortal