16f877 lcd sorunu ve portb.0 kesme sorunu

Başlatan safaka123, 07 Ağustos 2013, 01:58:45

safaka123

16f877 ile 4 mhz de LCD gayet güzel yazarken 8mhz e çıktığımda hiç bir yazı yazamıyor. lcdout komutundan sonra pause vermeme rağmen (pause 100) gibi hiç bir şekilde karakter yazmıyor. Pic 8 mhz de çalışırken LCD haberleşmesi için ne yapabiliriz. sanırım böyle bir sorun olmamalıydı 20mhz çalışan devreler ne yapsın. Bu nasıl çözülür.
Bir diğer sorun ise portb.0 kesmesi arada LCD, 4 karakter numara sayıyor bu kesme içinde. Kesme 100hz de bile sapıtıyor. Yapmak istediğim  dışarıdan portb.0 a 100hz. verdiğimde her periyotta saymasını istiyorum. kesme rutinin içinde 1 lcdout var. birde interruptan çıkış var.  çok kalabalık değil ama kesme saykılları kaçırıyor.  Bu kadar yavaş olmamalı diye düşünüyorum. Lütfen bu konuda fikri olan yardım edebilirmi.
Teşekkürler

XX_CİHAN_XX

Alıntı yapılan: safaka123 - 07 Ağustos 2013, 01:58:45
16f877 ile 4 mhz de LCD gayet güzel yazarken 8mhz e çıktığımda hiç bir yazı yazamıyor. lcdout komutundan sonra pause vermeme rağmen (pause 100) gibi hiç bir şekilde karakter yazmıyor. Pic 8 mhz de çalışırken LCD haberleşmesi için ne yapabiliriz. sanırım böyle bir sorun olmamalıydı 20mhz çalışan devreler ne yapsın. Bu nasıl çözülür.
Bir diğer sorun ise portb.0 kesmesi arada LCD, 4 karakter numara sayıyor bu kesme içinde. Kesme 100hz de bile sapıtıyor. Yapmak istediğim  dışarıdan portb.0 a 100hz. verdiğimde her periyotta saymasını istiyorum. kesme rutinin içinde 1 lcdout var. birde interruptan çıkış var.  çok kalabalık değil ama kesme saykılları kaçırıyor.  Bu kadar yavaş olmamalı diye düşünüyorum. Lütfen bu konuda fikri olan yardım edebilirmi.
Teşekkürler

Çok büyük ve karışık değilse kodlarını paylaşmanda yarar var özellikle kesme kısmını. Kesme içinde lcdout, pause vb. zaman alacak fonksiyonların bulunması hoş karşılanmaz. Hele ki kesmeyi pals sayma gibi bir amaçla kullanıyorsan hiç uygun olmaz. Kesme içinde bir flag işaretlersin ana program döngünde de bu flag işaretlenmişse lcdout mesajını yazdırırsın. Bu makul bir çözümdür.

Önemli bir detay: 8mhz krsital kullanıyorsan konfigurasyon ayarlarından osilator tipini XT yerine HS olarak seçmelisin.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

safaka123

#2
Öncelikle xt yerine hs yazdım çalışmadı. bir şeyi yanlış yapıyorum ama ne?
Program basitce dışarıdan aldığı 100hz i portb.0 kesmesini kullanarak %1 lik sayaç sayacak şekilde ayarladım fakat şu anda ki durum tam 100hz değil biliyorum. kabaca ayarlandı. buna rağmen isis te scope ta gördüğümde giriş sinyali ile çıkış sinyali birbirinden farklı. lcd saymayı kesme içinde yapmıyordum krono bölümünde yapıyordum ama belki faydası olur diye kesme içine yazdım. yine de faydası olmadı. Bu yavaşlık isis ten de kaynaklanıyor olabilirmi bir de o geldi aklıma . Programı ekte yolluyorum şayet indiremezseniz haber verirsiniz.
http://sdrv.ms/174bZhz

Bu arada tmr_0 kesme kullanarak yapılmış örnek var  fakat ben saat entegresinden gelen 4096 hz sinyali kullanırsam daha dengeli olur dedim ama sanırım bir şeyler benim düşündüğüm gibi gitmiyor. :)

Birde ben PIC konusunda çok daha başlangıcındayım. PBP 3.0 kullanıyorum isis 7.10 kullanıyorum. Config satırı pbp3.0 a göredir. (O da bulasıya kadar çok başımı ağrıtmıştı)

-Hasan-

#3
Programına kabaca bir baktım bazı önemli tanımlamaların önünde ' karakteri var. PBP ' de bu karakter yazıldıktan sonraki satır derlenmez. Bu yüzden açıklama cümlelerinin başına konur. Programınızda özellikle 'DEFINE OSC 4 diye bir satır var, başında bu karakter olduğu için burası derlenmiyor bilginiz olsun. Eee o zaman ilk başta nasıl çalışıyordu dersen; PBP ' de default XT osilatör frekansı 4 Mhz olduğu için çalışıyor. Eğer sen 8 Mhz ' de çalışacaksan:

DEFINE OSC 8 tanımını yapman gerekir. Dikkat et başında ' karakteri yok.

Artı LCD tanımlamasında da bu tip bir hata var onu da düzeltmelisin.

İkinci olarak Cihan kardeşimizin de dediği gibi kesme programlarında bekleme yapmak veya LCDOUT gibi bekleme yapabilecek komutları kullanmak uygun değildir, hele hele pals sayma işlemi yapılacaksa hiç değildir. 100 Hz frekanslı bir sinyalin periyodu 10 mS olduğundan kesme programının işlenme süresinin kesinlikle 10 mS ' yi aşmaması gerekir. Kesme programında saydırma işlemini yapıp ana programda LCD ' ye yazdırın.

Bir de diyeceğim şey şudur: LCDOUT komutunun arkasına PAUSE koymak LCD için hiç bir şey farketmez. Yani osilatör frekansınız tanımlarınıza uymuyorsa isterseniz 10 S bekletin hiç bir işe yaramaz. Çünkü program LCD ile iletişimi yapıp öyle beklemeye geçiyor.

PBP ' yi iyice öğrenmek için ETE Hocamızın PBP notlarına bakmanızı şiddetle tavsiye ederim. Ben PIC programlamaya onun sayesinde giriş yaptım. Ayrıca ona buradan çok teşekkür ediyorum.

İyi çalışmalar.

safaka123

teşekkürler açıklamanız için . Dediğiniz gibi define osc kısmını daha önce kullanıyordum ama programı başka bir örnekten kopyalarken o şekilde geldi ben de çalışıyor diye üstünde durmadım belirttiğiniz iyi oldu. Şayet Define RW den bahsediyorsanız onuda iptal edip direk şaseye bağladım. o port'u kullanmak için. Şimdi diyebilirsiniz bu kadar port varken neden tasarruf. başka bir programa ek olarak bu yapıldı bundan dolayı portları idareli kullanmam gerek. Pause için söylediklerinizi ilk defa duyuyorum. program lcd ye yazsın diye başka bir işle uğraşmasın diye kitapta yazıyordu. (prof. dr. doğan ibrahim beyin pic programlama kitabında şöyle diyor. lcd yi komut yoluyla reset yapmak için 15ms bekleriz. daha sonra 0x30 komutunu 8 bit olarak gönderip 160 mikrosaniye bekleriz ...) bundan dolayı koyuyordum. belki yazamamasının sebebi olarak gördüm.
Son olarak ETE beyin ne kadar biz amatörlere katkı sağladığını bilmezmiyim. bütün derslerini indirdim takıldığım yer olduğunda öncelikli olarak başvuru kaynağım. Emekleri için ne kadar teşekkür etsek azdır.

-Hasan-

#5
Hocam kitapta yazanlar doğrudur. Ancak LCD ' yi siz kontrol ediyorsanız. Normalde o LCD ' yi kullanmak gerçekte bir LCDOUT ile bitmez. 4 bit modun kurulması için bir byte bilgi gönderilir, ekranın açılıp hazırlanması için gibi birkaç byte ' lık komut bilgileri yollanır ilk başta ve her bir komutun bir icra süresi vardır. Bilgiyi yolladıktan sonra o süreyi beklemeniz gerekir. Artı EN palsinin periyodu da bilgilerin kabulü için önemlidir. Burada bu bekleme işini PBP yapıyor ve kendisi bunu osilatör frekansına göre hesapladığı için osilatör tanımlamasını yanlış yaptıktan sonra LCDOUT yazdığınızda zaten yanlış zamanlamayla birkaç veri gittiği için PAUSE yazmak hiç bir şey ifade etmiyor.

Rica ederim, kolay gelsin.

safaka123

doğru diyorsunuz çünkü öncelikle define osc 8 yaptım çalıştı ve lcdout kendi başına pause olmadan sayabiliyor. Sanırım pbp nin bize verdiği yardım. zira biraz önce kitaptan yaptığım alıntı direk asm. ile program yazıldığı varsayılarak anlatıyordu. Çok teşekkürler. saat frekansını 8mhz e çıkarınca 10ms lik darbeleri düzgün vaziyette okuyabilmeye başladı. tabiki isis lcd de sayarken yavaş kalabiliyor diye düşünüyorum normal pc saatiyle karşılaştırdığımda fark var. bayramdan sonra gerçek ortamda deneyince ortaya çıkacak. zira portb.2  kontrol portundan çıkış scope'a göre 10ms. lcd buna göre yavaş kalıyor ama dikkat ettim isis başka programları açarken bile daha yavaşlıyor.
  Şayet fazla geldi demeyecekseniz bir yerde okumuştum (ete hocamızın tavsiyelerinden biriydi) frekans sayacaksan yollardan biri PULSiN diyordu fakat nasıl kullanıldığı hakkında bilgim tam yok. portb.0 dan giren frekansın ne kadar olduğunu nasıl anlarım. bu konuda bir fikriniz varmı.  yaklaşık 1,5 gün bu konuda kafa patlattım bir çok forumda arama yaptım krono benzeri örnek çok az. genelde tmr0 ile yapılıyor. ben ise ds1307 den çıkan frekansın kristalden direk olarak elde edildiğini düşündüğümden daha doğru olacağı kanısına vardım ve bu şekilde davrandım. Bilmem fark varmı. Artı olarak 2 tane 4 bit sayaç kullandım bölme işlemi için. Şayet tecrübenize dayanarak fark yok derseniz TMR 0 da yapabilirim.

-Hasan-

#7
Hocam PBP ile uzun bir süre yazdım ancak PULSIN komutunu hiç kullanmadım. Bir pinden aldığımız palsin süresini hesaplıyordu sanırım. Örneğin isteğe göre PORTB.0 ' dan 0 gelmeye başlayınca süreyi saymaya başlıyor ve 1 gelince saymayı durduruyordu diye hatırlıyorum.

Ancak siz frekans ölçmek istiyorsanız en çok bilinen ve kullanılan yöntem şudur: İki tane TIMER kullanırsınız; bunlardan birisi ile 1s ' lik süre tutar diğeri ile de bu sürede gelen palsleri sayarsınız. Picproje E-Dergi 2 ' de bir üstadımızın bununla ilgili güzel bir makalesi vardı.

PIC ' lerde hassas 1 s ' lik kesme oluşturmanın en güzel yöntemi de; TIMER1 ' i 32.768 kHz lik kristal ile harici olarak tetiklemektir. Daha önce yaptığım bir saat devremde saat bilgilerini bu şekilde oluşturup saati 40-45 dk süre kesintisiz çalıştırdığımda oldukça hassas olduğunu gördüm. Bunu nasıl yapacağınız hakkında datasheetlerde ve internette bilgi bulabilirsiniz. Ancak ben bu uygulamayı ASM ile yapmıştım. PBP de bu kadar hassas yapmak mümkün olmayabilir. Eğer bu yöntemi kullanırsanız hassas 1 s ' lik sayaç yapabilirsiniz.

Siz kronometre tarzı bir şey yapmak istediğiniz için DS1307 ' ye hiç ihtiyacınız yok. DS1307 RTC (Real Time Clock) entegresidir. Yani sürekli olarak saat bilgisi güncelleyen entegre. Bu tarz entegelerin en büyük özelliği bağımsız iki kaynaktan beslenerek, devrenin enerjisi kesildiğinde çok düşük bir enerji ile saat bilgilerini güncellemeye devam etmesidir. Bu yüzden saat uygulamalarında hep bu tip entegreler kullanılır.

Ek olarak 1 s lik zaman üretmenin diğer bir yolu da PIC ' in çalışma frekansını 2 ' nin kuvveti olacak şekilde ayarlamaktır. 4 Mhz yerine 4.096 Mhz, 16 Mhz yerine 16.384 Mhz, 8Mhz yerine 8.192 Mhz gibi. Zaten TIMER1 ile 32.768 Khz kristal kullanmanın espirisi de buradadır. Eğer PIC ' in kristal frekansını bu tarz değerlerde seçerseniz ek bir 32.768 Khz kristale daha ihtiyacınız kalmaz.

İyi çalışmalar.

safaka123

önerin için teşekkürler ben ds1307 den gelen puls bilgisini başka yolla portb.0 dan almaya çalışıyordum. tmr1 kesmesini harici 4096 olarak dışarıdan tetiklersem sanırım doğru bir sonuç elde ederim. o zaman başka bölücülere gerek kalmadan içeride bu işi hallederim diye düşünüyorum. zaten sadece krono bölümünde bu kullanılacak. iyi çalışmalar.

safaka123

#9
TMR1 dahili osc  olarak çalıştırabildim fakat harici clock girişi ile çalışmıyor. ben mi yanlış bağlıyorum ds1307 nin 7 nolu bacağından aldığım sinyali rc0(t1oso) girişine verip registerleri harici ayarlıyorum çalışmıyor internal ayarladığımda kendi saat frekansına göre çalışıyor. Bağlantıda hata mı yapıyorum. sadece rc0 girişine veriyorum birde trisc de t1oso olarak kullanmak için ayar 0 mı 1 mi olacak. belkide ne olursa olsun tmr1 harici deniliyorsa çalışıyordur. bilemiyorum. Bu konuda yardımınızı bekliyorum takıldım kaldım.

Bayramsumbul

Merhabalar...İlk Sorunuz Çözüldü mü Bilmiyorum Ama
Alıntı Yap16f877 ile 4 mhz de LCD gayet güzel yazarken 8mhz e çıktığımda hiç bir yazı yazamıyor. lcdout komutundan sonra pause vermeme rağmen (pause 100) gibi hiç bir şekilde karakter yazmıyor. Pic 8 mhz de çalışırken LCD haberleşmesi için ne yapabiliriz. sanırım böyle bir sorun olmamalıydı 20mhz çalışan devreler ne yapsın. Bu nasıl çözülür.
Programında:
lcd E pini=1
bekle xkadar
lcd E pini=0
Yaparken 4Mhz'de Olsun 8 Mhz'de Çalışırken 2 Kat Fazla Beklemen Gerekir.Lcd'iniz Datasheet'ine Bakarsanız Orda İnstruction Set Adı Altında
Minumum Bekleme Süreleri Yazar.Bunu Timer İle'de Yapabilirsiniz.
Bir Elektronik Meraklısının Serüveni...

safaka123

Teşekkürler ilk kısım çözüldü şimdi ise başım tmr1 ile dertte. dahili osc ile çalışıyor harici saat palsi ile çalışmıyor.