1. sayfa
Merhaba istediğiniz şartları karşılayan şu şekilde bir mantık kurgulanabilir. Farklı yaklaşımlar ve çözüm yöntemleride olabilir. Ama kesme kullanmadan aklıma gelen en sade çözüm aşağıdaki gibi. Gerekli açıklamaları kodun içerisinde yapmaya çalıştım. Not 1: Sadece not defterinde yazıldı. Syntax hataları veya farklı hatalarda olabilir. Ama size yol göstereceğini tahmin ediyorum. Not 2: Kodlar işinize yararsa benim adıma bir hayır kurumuna bağışda bulunabilirsiniz. ![]()
|
Hocam çok teşekkür ediyorum cevabınız için. Zamanlayıcı olarak timer kullanıp başlatıp/durdurarak yapmak amacındaydım. Yazdığınız kod hata verince aynı mantıkla şöyle yazdım: < Resime gitmek için tıklayın >< Resime gitmek için tıklayın > Sinyalin periyodu 100Hz. 10ms. Mcu'nun a4/TOCKI pinine verdiğim sinyale 45 derece faz verdim. Yani a0 pinine verdiğim sinyale göre daha erken sıfırdan geçecek ve kesme fonksiyonuna dallanacak. Bu fonksiyonda 45 derecenin zaman farkı 2.5ms olarak olarak ölçülecek. Yani 2500us. 10us de bir sayacı arttırdığım için sayaç değeri 250 olmalı. Ancak 119 gösteriyor.Kesme fonksiyonundaki algoritmada sıkıntı var ama çözemedim. < Resime gitmek için tıklayın > |
Hocam TOCKI timer0 kesmesini kullanarak doğru bir hesaplama yapamadım. Timer0 kesmesindeki kodları RB kesme fonksiyonuna yazdım ve RB kesmesini kullanarak doğru bir ölçüm yapabildim. 45 derece verdiğim faz açısını 43 derece görüyorum. Bu hesaplamayı timer zamanlayıcısını iki sıfır geçiş arasında başlatıp durdurarak hesaplayacak bir kod parçası yazabilir misiniz? |
Yukarida kullandiginiz tmr0 kesme kullanimi hatali bir kullanim şekli. Genis bir zamanda uzerine kafa yoralim. Siz ilk mesajinizda kesme kullabmadan basit sekilde diye şartlari belirleyince buna göre bir şablon hazirladim. Şablon kodda ne gibi bir hata aldiniz? |
6 adet hata almıştım. ilki float faz_olc() olarak gösteriyordu biraz kurcaladım çözemedim ama problem değil sonuçta yazdığınız kod da zaman farkını hesaplama mantığı en basitiyle delay komutuyla sayacı arttırmak. Tabi bugüne kadar timer ve kesmeleri öğrenmeye çalışıp bunlarla yapmaya endekslendiğim için bu şekilde düşünmedim. Hocam kabul eder mi, tabi etmek zorunda. Çünkü anladığım kadarıyla tam olarak mcu'ların çalışma mantığını anlayıp hakim olmak ve istediğini yapabilmek için assembly den başlamak gerekiyor. Kesme kullanmadan sadece timer'ı (timer0 yada timer1) çalıştırıp-durdurarak sade bir kod istemiştim. 16f877 de araştırdığım kadarıyla timer0 durdurulamıyor, timer1'in T1CON registerin'de ise TMR1ON bit'i çalıştırılıp durdurulabileceğini gösteriyor. Hocamla konuştuğumda '16f877 ile de çalıştım ben ve timer çalıştırılıp durdurulabiliyor' dedi. Daha sonra bir iki gün önce timer1 için; setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); set_timer1(0); delay_us(40); deyip ardından; setup_timer_1(T1_DISABLED); time=get_timer1(); ile timer1'i durdurup ekranda '40' ı görmüştüm. Hatta devamında; setup_timer_1(T1_INTERNAL | T1_DIV_BY_1); delay_us(40); setup_timer_1(T1_DISABLED); time=get_timer1(); deyip ekranda '80' görmüştüm yanlış hatırlamıyorsam. Yani başlatıp durdurabiliyordum. Timer0'ında içindeki değeri durduramadan anlık olarak alabildim. Gel gör ki bunlar beni ne kadar sevindirse de iki sıfır geçiş arasını doğru hesaplatamadım. Gerçi yanlış hatırlamıyorsam sinyalleri doğrultup sonra da offset verip (2.5v-5v arası) ve adc ye verip 2.5V ta takabül eden adc değeri 500 ise oku=read_adc() den oku değerini 'if' komutuyla 500 ise timer1'i çalıştır vs yapmıştım ama ortalık feci karışmıştı. Sıfır değerini adc den değilde şimdiki gibi pulse olarak dışarıdan alsam ki bunu da denemişimdir ama hatırlamıyorum. |
|
Fırsat bulmuşken konuya kısa bir katkı daha yapayım. Tasarım veya problem çözerken birden fazla çözüm yöntemi olabilir. Sizin önemli olan ölçümü doğru şekilde yapmakmı? Yoksa illa A0 ve Timer0 ı kullanmak zorundamısınız? İkinci şekilde bir talep varsa çok saçma bir durum! + Zaman veya peryot ölçümlerinde yazılan kodların çok iyi şekilde optimize edilmesi gerekir. Çünkü yazılan kodların cpuda işlenmeside bir zaman almaktadır. Hassas ve doğru sonuçlar için bu gecikmelerinde hesaba katılması gerekir. + Harici kesme ile ilgili donanımı iyi tanımanız gerekmektedir. 877 nin A0 ve A1 pinleri kesme için kullanılamaz! + Proteus dosyanızı ekleyin, fırsat bulunca denemeleri onun üzerinde yapmaya çalışırım. + ADC ile peryot ölçümü yapmak yanlış bir tercih. (ADC çevrim zamanı ve hesaplama, karar verme rutinleri nedeniyle hassas ve tekrarlanabilir sonuçlar alamazsınız) |
Şöyle diyeyim, bu benim yıllık ödevim olduğu için geçen dönemde hocadan adc, kesme ve zamanlayıcıları öğrenin diye tavsiyelerini duyduğum için, bir de hani ödevin adı Reaktif güç kontrol rölesi iken timer falan kullanmayıp delay kullanmak ödevin içini boşaltmış gibi bir algı oluştuğu için bende içim rahat etmiyor. Yoksa hocanın kesin timer ve kesme kullanacaksın diye bir söylemi yok. 'Harici kesme ile ilgili donanımı iyi tanımanız gerekmektedir. 877 nin A0 ve A1 pinleri kesme için kullanılamaz!' Nasıl yani RB kesme fonksiyonu içinde bu pinleri kullanamam mı? Proteus dosyalarını burdan ekleyemedim, sadece resim kabul ediyor. |
Ben bu cümlenize binaen a0 ve a1 i kesme olarak kullanamazsınız demiştim. RB kesmenini kullandığınızı/ nasıl kullandığınızı siz yazmazsanız takdir edersinizki bizim bilmemiz mümkün değildir. Kullanmanızın bir mantığı varsa tabiki kullanabilirsiniz. Bir problem ile uğraşan arkadaşlarımız, genelde kendi yaptıklarını / denediklerini cevap veren arkadaşlarında bildiği izlenimine kapılıyorlar. Sonrasında ise konu genelde, soru/cevap şeklinde ilerliyor. Konuyu okuyacak diğer arkadaşlarımız için bir tavsiye; probleminizi, ne yaptığınızı/yapacağınızı, ne gibi hatalar aldığınızı detaylı şekilde yazarsanız daha isabetli cevaplar alırsınız, konuya cevap vermek için vakitlerini ayıranlan kişilerede saygı göstermiş olursunuz. Lütfen yukarıda yazdıklarımı size karşı bir sitem olarak almayın, sadece yapılacak iş veya sorun ne kadar net tarif edilirse daha kaliteli cevaplar / içerikler üretilebilir, gereksiz zaman israfıda önlenmiş olur düşüncesindeyim. Gelelim asıl meselemize: Şablon kod olarak sabah paylaştığım kodları gerçek uygulamada derledim ve denedim sorun görünmüyor. Siz ne gibi bir hata aldınız? Diğer alternatif bir öneri: Sizin projeniz için aklıma gelen daha kısa ve kararlı sonuç üretecek alternatif diğer bir öneriyi aşağıda paylaştım. Yapmanız gereken 16F877 yerine birebir pin uyumlu 18F452 kullanmak. (harici 3 adet kesmeye destek verdiği için) Gelelim işin mantığına: + 2 adet harici kesme farklı faz açısı girişlerinin yükselen kenarını yakalamak için kullanıldı (INT1 ve INT2) {Toplamda 452de 3 tane var biz ikisini kullandık. 877 de 1 tane var bu mantık için yeterli gelmiyor} + Timer1 1us lik adımlarla çalışacak şekilde ayarlandı. Max ölçülebilecek süre 65535us = 65ms (Bu ayarlar ile Faz farkı 5ms ise ekranda 5000 e yakın bir değer görürsünüz) + Sonuçlar Seri port ile ekrana basıldı. Siz LCD kullanabilirsiniz. + Girişdeki NOT kapısı ve kapasitörler aklınızı karıştırmasın, deneme yapmak için basit şekilde faz farkı oluşturmak için kullandığım bir teknik. Gerçek uygulamada siz kendi sıfır geçiş devrenizin çıkışını buraya bağlayacaksınız. Başarılar... Test Devresi: < Resime gitmek için tıklayın > Header: < Resime gitmek için tıklayın > Kodlar: < Resime gitmek için tıklayın > İlk resimdeki terminalde görünen 5005 değerinin karşılığı olan işaret ölçümü: < Resime gitmek için tıklayın > |
Haklısınız hocam. 18f452 biraz uğraştırdı. 16f877'de 5V bağlamasakta çalışıyordu simülasyonda :). Bir de bu not kapısı olayını pek anlamadım; Kesme aldığımız iki porta da not kapısı bağlamadığımda 5ms'de 4910 civarı, Portlardan birine bağladığımda 5ms'de 4995-5000 arası, Her iki porta da bağladığımda 5ms'de 5080 civarı değer görüyorum. Ayrıca çok teşekkür ediyorum hocam bu uygulama için. Bir de mesela 16f877'de lcd bağlantısı, izlediğim videolardan dolayı elimde hazır olarak vardı. 18f452'de lcd bağlantısı nasıl olacak kısmında takıldım. Biraz temel bilgiler eksik bende hocam. Yani kullandığımız derleyicinin bir lcd kütüphanesi var ve orada bağlantıların nasıl yapılacağı yazıyor ve derleyici değişmediği sürece bu bağlantılar işlemciden işlemciye değişmiyor. Dolayısıyla 16f877'de lcd nasıl bağlıysa yine öyle bağladım. < Resime gitmek için tıklayın > |
Bir de Reaktif güç kontrol rölesi faz farkını azaltmak için şebekeye röleler vasıtasıyla kapasiteler ekler. Gayet mantıklı kodlar yazsam da röleleri çalıştıramadım. < Resime gitmek için tıklayın > Basit bir if komutuyla x değişkeni şu eğerler arasındaysa output_high(pin_c0) gibi kodlar yazdım ama olmadı. |
Yukarıdaki mesajdada belirtmiştim. "Not kapısına takılmayın diye". Yazdığım kodları test etmek için en basit faz farkı oluşturma devresi olarak kullandım. Sizin devrenizde o kısım haliyle farklı olacak. AC işaretleri bir şekilde alıp, sıfır geçişlerinde "Pals" olarak elde etmeniz / elde etmiş olmanız gerekir. LCD ile ile ilgili 877 de olan portlar ve pinler 452 dede var. Aynı şekilde bağladığınızda sorun olacağını tahmin etmiyorum.
Yukarıdaki uzun mesajda ifade etmeye çalıştığım gibi ne yazdığınızı görmeden / bilmeden birşey demek imkansız. Demekki sizin gayet mantıklı dediğiniz şey ile yazdığınız kodlar bir birine uymuyor ![]() |
Not kapısını sizin uygulamanızdan bağımsız olarak sormak istedim. Bağlamadığımda 2400 civarı bir değer görüp, not kapısını eklediğimde görmem gereken 2500 değerini görünce şaşırdım anlayamadığım için sizin uygulamanızdan bağımsız olarak sormak istedim. Ancak çözdüm. < Resime gitmek için tıklayın > Kesme yükselen kenarda gerçekleştiği için, benim sıfır geçişin palsinin yükselen kenarı, not kapısının yükselen kenarına göre bir önceki palse daha yakın. Not kapısını kaldırdım ve sıfır geçiş palsinin düşen kenarında tetikledim ve 2500 gördüm (45 derecede); (enable_interrupts(INT_EXT2_H2L); Röle mevzusunu da çözdüm. Çalıştıramadığım röleyi ayrı bir simülasyonda basit olarak çalıştırmaya çalıştım ancak çalışmadı. Basitçe Relay yazıp çıkan ilk röleyi seçtim ve çalıştı. < Resime gitmek için tıklayın > Hocam şuan en çok aciliyeti olan diğer konu 555 entegresi. Bu konuda bilginiz varsa çok ikrama geçer. Hocamız sinüs dalgasını 555 entegresinden almamızı istedi. < Resime gitmek için tıklayın > 5v'tan biraz fazlası var. Amacım 5v, 50Hz bir sinüs almak. Çıkış dalgasını 50Hz almak için aylar önce uğraşmıştım ancak yapamamıştım. Birkaç güne teslim etmem gerekiyor ödevi. Eğer bilgin varsa hocam çok ama çok makbule geçer. |
Röle konusunda yaşadığınız sıkıntı: Proteusda seçtiğiniz elemanın "VSM modelinin" olduğundan emin olunuz. Bazı bileşenlerin simülasyon/animasyon modelleri olmuyor, sadece şematik ve baskı devre çiziminde kullanılıyorlar. 555 ile ilgili tavsiyem; problem genliğin fazla olması ise, basitce 2 direç ile gerilim bölücü yapabilirsiniz. Başarılar.... |
Anladım. Hocam çok ama çok teşekkür ediyorum. Çok faydalı oldunuz. Beşiktaşlıysanız sizin niyetinize kampanyaya bağışta bulunabilirim. Aksi halde camiye verebilirim. |
Önemli değil. Bağış yapmak zorundada değilsiniz. Ama yapmak isterseniz size en az zahmet verecek yeri tercih edebilirsiniz. ![]() Tekrar başarılar... |
1. sayfa
Aralarında zaman farkı olan iki dalga arasındaki bu zaman farkını 16f877 mcu'su ile ölçüp ekrana yazabilir misiniz?
Elimde iki adet +-5V, 50Hz sinüs dalgası var. Bu dalgaların negatifini opamplarla doğrulttum. Sonuçta elimde 0-5V, 100 Hz ac dalgalar oldu. Bunların arasında faz farkı var. Sıfır geçiş dedektörü ile lojik hale getirdiğimiz sinyali mcu ya verip timer zamanlayıcısı ile faz farkını ekrana yazmayı çok istedim. Yapamadım.
Amacım Reaktif Güç Kontrol Rölesi yapmak. Ancak programlama ve mcu konularında çok yeniyim. Ccs c ve 16f877 üzerinde çalıştım. Mplab'a girmeye çalıştım ancak gerçekten çok derin bir dünya var o tarafta.
Mümkünse Ccs c de, 16f877 üzerinde, kesme fonksiyonlarına hiç girmeden, sıfır geçişinden devresinden faydalanıp timer'ı başlatıp durdurarak zaman farkını sade bir şekilde ölçebilirseniz çok iyi olur.
Yapabilecek olan pm den ulaşabilir.
DH forumlarında vakit geçirmekten keyif alıyor gibisin ancak giriş yapmadığını görüyoruz.
Üye Ol Şimdi DeğilÜye olduğunda özel mesaj gönderebilir, beğendiğin konuları favorilerine ekleyip takibe alabilir ve daha önce gezdiğin konulara hızlıca erişebilirsin.