Merhaba arkadaşlar. Bu projede 18F2520 nin timer1 ve timer3 modüllerini kullanarak 4.5 MHz e kadar 1 Hz hassasiyette ölçüm yapabilen TTL frekansmetre tasarlıyoruz.
Her şeyden önce frekansın tanımını hatırlayalım. Periyodik işaretlerin bir saniyede yaptığı salınım sayısına frekans denir. Frekans ölçüm işlemi saniyede yapılan salınımların sayılmasıyla yapılabileceği gibi iki salınım arasında geçen sürenin (periyot) ölçülmesiyle de yapılabilir. Bu ikisi arasındaki kararımızı ölçüm yapmak istediğimiz işaretlerin ortalama frekansına göre verebiliriz. Düşük frekanslı işaretler için iki salınım arasında geçen sürenin ölçülmesi, yüksek frekanslı işaretler için saniyede yapılan salınımın ölçülmesi daha mantıklıdır. Biz de bu projede en az 1 Hz en fazla 4.5 MHz lik ölçüm yapmak istediğimizden saniyede yapılan salınımı sayma yöntemini kullandık. PIC 18F2520 yi seçmemizin yegane sebebi iki tane 16 bit timer a ihtiyaç duymamızdır.
Başlıkta da belirttiğimiz gibi mikrodenetleyici olarak PIC18F2550, dil olarak CCS C dilini kullandık.
Mikrodenetleyici tarafından yapılması gereken işlemler:
1) Olabildiğince hassas bir saniyelik zaman tutmak.
2) Bu bir saniye içerisinde gelen kenar sayılarını saymak.
Saydığımız işlemler o kadar temel işlemler ki artık her mikrodenetleyici de bu işlemleri yapacak donanım modülleri var. PIC 18F2520 nin donanım modüllerinden compare, timer1 ve timer3 modülleri bu iki işlem için fazlasıyla yeterli.
Timer1 ve Timer3 16 bitlik ve harici “clock” girişiyle(pin C0) arttırılabiliyorlar yani bu iki “timer” dan birini saniyede gelen yükselen kenarları saymak için kullanabiliriz. Biz timer1 i kullandık. Sadece T1CON “register”ındaki TMR1CS bitini lojik bir yaparak timer1 i harici “clock” ile çalışmaya hazır hale getiriyoruz. İkinci işlem için hazırlığımızı yaptık.
Sıra geldi bir saniyelik zamanın tutulmasına, bu işlem için timer3 ü kullandık. Genel olarak zaman tutma işlemini timer taşma kesmelerini sayarak yaparız. Mesela 16 bitlik bir timer 65535 e kadar artabilir ve 65536 da taşar. PIC i 20 MHz de çalıştırdığımızı varsayarsak her bir çevrim 200 ns olur ve 16 bitlik bir timer her 200nsx65535=13.107 ms de bir taşar(prescale veya postscale kullanmadığımızı varsayalım). Bu 13.107 ms leri sayarak daha geniş zaman dilimleri tutabiliriz veya timer i CCP nin compare modülü ile beraber kullanarak timer in 65535 e gelmeden daha önce bizim belirleyebileceğimiz bir değerde taşmasını sağlayabiliriz. Tam bir saniyelik zaman tutmak için kaç tane 13.107 ms saymanız gerekir? Cevabımız bir tamsayı değil. Bu yüzden timer3 ü “compare” modülüyle birlikte kullanıp her 10ms de bir taşmasını sağlayabiliriz. 10ms lik zaman dilimleriyle bir saniyelik zaman elde edebiliriz. Bunu yapmak için:
CCP modülünü timer3 için kurmak ve CCPRH, CCPRL “register” larına 10ms için uygun “compare” değerini yazmamız gerekiyor. 18F2520 de iki tane CCP modülü var, CCP1 ve CCP2. Biz CCP2 yi kullandık. CCP2 yi hangi modda kullanacağımızı CCP2CON “register” ıyla belirliyoruz. Her compare olayında Timer3 ün resetlenmesini istediğimizden:
CCP2M3:M0 bitlerini 1011 yapıyoruz = Compare mode, trigger special event; reset timer; CCP2 match starts A/D conversion (CCPxIF bit is set) olarak belirliyoruz. Compare değerimizin 10ms olmasını istiyorduk. 200ns çevrim süresinin 50000 tane sayması gerekir ki 10ms süresi geçsin. 50000 in hex karşılığı 0xC350 olduğundan CCP2H “register”ına 0xC3 ve CCP2L “register”ına 0×50 değerlerini yazıyoruz. Böylece CCP2 modülünü compare modda kullanmak üzere hazırladık. Şimdi de CCP2 modülümüz için hangi timer in kullanılacağını söyleyelim:T3CON “register”ındaki T3CCP2(6. bit) i lojik bir yaparak CCP modülleri için Timer3 ü kaynak gösteriyoruz. Evet, şu anda timer3 ü başlattığımızda (T3CON un ilk biti TMR3ON u lojik bir yaptığımızda) timer3 her 10ms de bir resetlenecek ve CCP2IF bayrağını lojik bire çekerek(compare interrupt) taşmadan bizi haberdar edecek. Böylece 10ms lik zaman dilimlerimizi hazırlamış olduk. Bu zaman dilimlerinden 100 tane sayarak 1 saniyelik zaman elde edebiliriz. Birinci işlem için de hazırlığımızı tamamlamış olduk. Bu iki işlemin özeti aşağıdaki resimde görülmektedir:
Peki burda elde ettiğimiz bir saniye tam olarak bir saniye mi? Mesela 10us eksik olsa 1MHz lik bir kaynağı 10Hz, 4MHz i 40Hz eksik ölçeriz. Ne kadar doğru bir saniye sorusu bizi ne kadar doğru 10ms ler sorusuna bu soru da ne kadar doğru 200 ns ler sorusuna bu soru da ne kadar doğru 20Mhz lik osilasyon sorusuna götürüyor.
Hassas bir frekansmetre için ince bir ayar yapmamız gerekiyor. Devre şemasında da görüleceği üzere kristal ile toprak arasında trimmer kondansatör kullanıldı. Katalogda tavsiye edilen kapasite değerleri var ancak tam 20 MHz lik osilasyon garanti edilemiyor dolayısıyla trimmer kondansatör yardımıyla 20MHz i bizim bulmamız gerekiyor. Frekansmetreyi bitirdikten sonra kalibre edilmiş bir sinyal jeneratörü veya başka bir frekansmetre kullanarak kendi ölçüm aletimizi kalibre edebiliriz. Sinyal jeneratöründen 4.5MHz lik 0-5V arasında değişen herhangi bir işaret ürettikten sonra kendi frekansmetremizi 4.5MHz gösterecek şekilde trimmer kondansatörümüzle ayarlıyoruz. Bu işlemi bir defalığına yapacağız ve 1Hz çözünürlüklü frekansmetremiz kullanıma hazır olacak.
Sıra geldi bu iki işlemin koordineli bir şekilde yapılmasına: Timer1 ve Timer3 ü sıfırlıyoruz. Timer1 i aktif ettikten hemen sonra Timer3 ü başlatıyoruz. 100. compare kesmesi geldiğinde(bir saniye dolduğunda) timer1 i pasif ediyoruz, ölçüm tamamlandı. Sonucu ekrana gönderiyoruz. Aynı işlemi sonsuz döngüde tekrarlıyoruz yani ölçüm her bir saniyede yenileniyor.
Bu bir saniye içerisinde frekansın 65535 den büyük olduğu durumlarda timer1 taşacaktır. Timer1 taşmalarını sayıyoruz ve frekansı taşma sayısıyla beraber hesap ediyoruz. Kaynak kod oldukça kısa ve yazının sonunda verildi, burada önemli kısmına bakalım:
.start_new(); output_high(pin_C3); while(1){ //sonsuz dongu }// main void start_new(){ t1tasma=0; compared=0; TMR1H=0x00; TMR1L=0x00; TMR3H=0x00; TMR3L=0x00; T1ON=1; T3ON=1; } #INT_CCP2 void compare(){ CCP2IF=0; compared++; if(compared==100){ T1ON=0; compared=0; value=get_timer1(); value=value+t1tasma*65535; if(value>4500000){ printf(lcd_putc,"\f FREQUENCY:\n>4500000(max) Hz"); } else{ printf(lcd_putc,"\f FREQUENCY:\n %Lu Hz",value); } start_new(); } } #INT_TIMER1 void timer1_tasti(){ TMR1IF=0; t1tasma++; }
Frekans metre devre şeması
Olası Geliştirmeler
4.5MHz lik üst sınır PIC in donanımı ile alakalı, yani bu üst sınır bir donanım sınırlaması. Timer1 propagasyon gecikmeleri sebebiyle daha hızlı artamamaktadır, aslında bu sınır 5MHz e kadar çıkabiliyor ancak biz güvenlik açısından 4.5MHz de durduk. İncelediğim frekansmetrelerde çeşitli bölücü entegreler kullanılarak ölçüm aralığı genişletilmiş ancak hata da artıyor tabii.
Bu haliyle frekansmetremiz sadece C0 pininin müsade ettiği voltaj seviyesindeki işaretlerin frekansını ölçebilmektedir(sinyal şeklinden bağımsız olarak). Bu seviyeler de lojik0 için 0-1 V arası lojik1 için 4V-5.5V arası. Bu da tabi frekansmetrenin kullanım alanını kısıtlamaktadır. Bu çalışmanın sonunda tepeden tepeye 100mV ile 300V arasında değişebilen işaretleri TTL seviyesine dönüştürebilmek için bir devre tasarlamak için uğraştım ancak pek istediğim gibi çalışmadığından burda yayınlamadım.
Eski multimetrelerdeki gibi kademe kademe ölçüm yapılabilir ancak bugünün frekansmetreleri şehir şebekesini de 1V tepe değerli işaretleri de kademe değişikliği yapmaksızın ölçebiliyor. Bu devre aklımın bir köşesinde duruyor, fırsat bulur ve yapabilirsem yayınlayacağım. Sizden gelen önerilere de açığız 🙂
NOTLAR
Arkadaşlar ben bu çalışmayı kullandığım simülasyon programlarında hatasız olarak simüle edemedim. Proteus, MPLAB veya PIC18 Simulator IDE de karşılaşacağınız durumlar sizi şaşırtmasın, kod gerçek bir PIC te gayet düzgün çalışmaktadır. Proteus önceki frekansmetrelerde doğru yapmasına rağmen bu çalışmada ölçümü yanlış yapıyor; saydığım diğer iki programın birinde timer3 16bit modda çalışmazken diğer programda compare mode aktif olmadı, bunları bu programların “bug” ı olduğunu düşünüyorum. En sonunda gerçek bir PIC de deneme yapma kararı aldım ve frekansmetreyi düzgün çalıştırabildim.
Çalışmanın kaynak kodu ve proteus simülasyon dosyası:
Şifre-Pass: 320volt.com
İyi çalışmalar dilerim.
PicProje E-Dergi 2 | Yazar: Fatih Erdem
Yayım tarihi: 2018/07/05 Etiketler: frekans metre, microchip pic projeleri, PIC18F2520