16F628A Mikrodenetleyici ve Proton Basic ile Adım Adım Frekans Sayıcı Yapmak
Adım adım frekans sayıcı yapmak |
Mikrodenetleyici ile frekans sayıcı yapmak istediğinizde bulacağınız projeler, bütün sorunları çoğunlukla çözülmüş, sadece hex dosyası bulunan birçok proje veya açık kaynak kodları bulunan bazı projeler bulacaksınız. Her iki tip projelerin sorunları çözülmüş olarak sizlere sunulduğu için, ne neden nasıl yapılır en temelinden anlatılmadığından dolayı aynı temeldeki devre yapılarını başka devrelerde çözüm olarak kullanmak istediğinizde konuya sıfırdan yani temelinden başlamadığınız için çok fazla zorluk çekeceksiniz.
Bu yazıda mikro denetleyicilerle yapılabilecek frekans sayıcı devrelerinin en temel açıklamalarını, karşınıza çıkabilecek değişik sorunlar ve bu sorunlara bulunabilecek çözümleri bulacaksınız. Mikrodenetleyici programlama dilini Proton Basic olarak seçmemdeki sebep mikrodenetleyici ile yeni çalışmaya başlayan elektronik meraklılarının kullanabileceği bana göre en kolay dil olan pic basic pro nun daha gelişmiş komut setlerine sahip olması.
7805:
Bu devrede kullanacağımız LCD ekran ve 16f628a, 5 voltla çalıştığı için sabit voltaj regülesi olarak 7805 kullanacağız. Piyasada 100 ma ve 1A’lik olmak olarak bulunabiliyor. LCD ekran aydınlatmasını kullanmayacaksanız 100 ma olanı yeterlidir. Fakat bence fiyat farkı fazla olmadığından 1A olanını tercih edin. Burada dikkat edilmesi gereken bir konu var: 7805 voltaj regülatörü entegresinin ayak bağlantı noktalarına en yakın olan yerden olmak üzere, şaseden girişe ve şaseden çıkışa 100 nf kondansatör bağlayınız.
16f628a:
Mikrodenetleyici ile ilk defa uğraşmaya başlayanların ilk tercihi genellikle Microchip16f84 PIC olmuştur. Kısıtlı özelliklerine rağmen öğrenme sürecinin ilk aşaması için yeterli olan bir mikrodenetleyicidir,
Benim 16f628 PIC’i tercih etmemdeki sebep program hafızasının daha fazla olması ve çalışma hızının daha yüksek olmasına rağmen daha ucuz fiyata bulunması ve dahili osilatörünün bulunmasıdır. Devre tasarımlarında eğer yapacağınız iş çok keskin zamanlama gerektirmiyorsa kristal kullanmayıp hem çizimde kolaylık, hem de kristal için kullanılan pin lerin port olarak kullanılması sizin için kolaylık olacaktır. Eğer kristal kullanacaksanız; kristalin her iki ayağından şaseye 22 pf kondansatör bağlamayı ve giriş olarak tanımladığınız portu 4,7 kilo ohm direnç ile şaseye bağlamayı unutmayınız.
LCD:
Piyasada 2*16 LCD ekranlar kolaylıkla bulunabiliyor. Sizin dikkat etmeniz gereken kontrol entegresinin hd44780 olması pin dizilimi:
1=şase,
2=+5 volt,
3=görünürlük ayarı (4.7 k ayarlı direncin orta ayağını 3 nolu pine sol ayağını şase ye sağ ayağını + 5volta bağlayınız bu pine bağlı ayarlı direnç ten lcd ekranın görünürlük ayarını yapabilirsiniz),
4=rs pini (bu pini program yazarken tanımlayacağız),
5=rw pini (şaseye bağlayınız (başka uygulamalarda porta bağlamak gerekebilir)),
6=en pini (program yazarken tanımlayacağız),
7,8,9,10= data pinleri (4 bit haberleşme yaptığımız için kullanmayacağız)
11,12,13,14=data pinleri (program yazarken tanımlayacağız),
15= Arka plan aydınlatma (aydınlatma için olan led lambanın + volt ayağı 47 ohm dirençle +5 volta bağlayınız),
16= Arka plan aydınlatma (aydınlatma için olan led lambanın şase ayağı şaseye bağlayınız)
Yukarda anlattığım pin bağlantıları genellikle piyasada standart bulunan LCD’lere aittir. Bazen bağlantı ayak dizilimi değişik çıkanlar olabilir. Satın aldığınız LCD ekranın datasheetinden bağlantı pinlerinin sıralamasını kontrol ediniz. Daha önceki aldığım bazı ekranlar da çok değişik pin sıralamalarıyla karşılaştım.
Devre şeması ve pcb çizimi:
Yazıda anlatılan programları denemek için gerekli olan devre şeması ve pcb çizimi için gerekli olan pdf dosyası alttaki linklerde verilmiştir:
Frekans Sayıcıda Kullanılacak Proton Basic Komutları
Aşağıda anlattığım komutlar sadece üzerinde çalışacağımız frekans sayıcı projesi için gerekli olan birkaç komutun gerekli olan kısıtlı kullanım alanlarıdır. Daha fazla anlatım ve kullanım alanları ile ilgili bilgiye proton basic yardım bölümünden ulaşabilirsiniz. Eğer İngilizce bilmiyor iseniz elektronik kitap satan yerlerden Türkçeye çevrilmiş kitabını bulabilirsiniz. Bahsettiğim kitap Ankara’da bulunabiliyor.
Assembler Komutlarının Kullanılması:
Proton Basic istenildiği zaman assembler komutlarının kullanılmasına izin verir. Bu durumda Proton Basic yazılan komutlara hiçbir yorum katmadan işler. NOP bekletme komutu için 20 mhz de kullanılırken yapılan hesaplama şöyledir 1 NOP= 1000000/(20000000/4) mikro saniyedir. 0,2 mikro saniye=200 nano saniyedir. 20 mhz kristalde 1mikro saniye bekletme örneği:
Asm
Nop
Nop
Nop
Nop
Nop
endasm
Mikrodenetleyici ve Kristal Tanımlaması:
Proton Basic dilinin hangi mikrodenetleyiciyi kaç mhz kristalle kullandığınızı bilmesi gerekir. Bu tanımlama programın ilk 2 satırında yapılır. DEVICE ve XTAL bildirimleri ile belirlenir. Alttaki örnek bildirim 16f628a mikro denetleyici nin 20 mhz kristalle kullanımına örnektir.
Device=16f628a
Xtal 20
Portların Durumunun Belirlenmesi:
Mikrodenetleyicilerde bir portta birden fazla özellik bulunabilir. Siz istediğiniz port durumunu çeşitli bildirimlerle ayarlayabilirsiniz. Bunun en güzel yolu datasheetinden okuyup yapmaktır. Bilgiler her mikro denetleyici için değişebilir. Eğer konu ile ilgili fazla bilginiz yoksa ve portlar size sadece digital giriş ve çıkış olarak lazımsa Proton Basic sizin için bu işi otomatik olarak yapabilir. Bunun için kristal tanımlamasının altına all_digital = true yazmanız yeterli olacaktır. Bundan sonra portun giriş mi yoksa çıkış mı olduğu belirlenir. Bu tris belirleyicisiyle yapılır. tris bildirimine decimal sayı, hex sayı, binary sayı formatları yazılabilir. Aşağıda değişik örnekler vermeye çalıştım.
Device=16f628a
Xtal 20
all_digital = true
Trisb=0 (portb nin tamamı çıkış olarak ayarlandı)
Trisb=$0 (portb nin tamamı çıkış olarak ayarlandı)
Trisb=%00000000 (portb nin tamamı çıkış olarak ayarlandı)
Trisb=255 (portb nin tamamı giriş olarak ayarlandı)
Trisb=$ff (portb nin tamamı giriş olarak ayarlandı)
Trisb=%11111111 (portb nin tamamı giriş olarak ayarlandı)
Trisb.7=1 (portb nin 7 inci biti giriş olarak ayarlandı)
Trisb.7=0 (portb nin 7 inci biti çıkış olarak ayarlandı)
Değişkenler:
Sayısal değerleri kaydetmek bunlar üzerinde matematiksel işlemler yapmak için değişkenler kullanılır. Bu değişkenlere decimal sayı, hex sayı, binary sayı formatları yazılabilir.
Değişken tiplerinin alabilecekleri değerler ve kullanım örnekleri aşağıdadır.
FLOAT =32 bit kayar noktalı değişken
DWORD =32 bit değişken
WORD = 16 bit değişken
BYTE =8 bit değişken
BIT =1 bit değişken
Dim sayi as float
sayi=3.14
sayi=sayi*5
Dim sayi_a as dword
sayi_a=100000
sayi_a=sayia/2
Dim sayi_b as word
sayi_b=65500
sayi_b=sayi_b-500
Dim volt as byte
volt=0
volt=volt+20
Dim durum as bit
durum=0
durum=1
Bekletme Komutları:
Program yazarken işlemler arasında bekletme yapmak gerekebilir. Bunun için delayms ve delayus komutları kullanılır. Her iki komutun alabileceği en yüksek değer “65535” dir. Örnekler:
Delayms 1000 (1 saniye bekle)
Delayus 10000 (10000 mikrosaniye bekle)
Dim zaman as word
zaman=1000
Delayms zaman
Delayus zaman
.
Label Oluşturmak, goto ve gosub Komutu:
Basic dilinde program yazarken, program içerisinde küçük programlar yazarak işleri biraz düzenli hale getirebilirsiniz. Bu label oluşturarak yapılır. Label isimleri; İngilizce karakterler olmak şartıyla, proton basic dilinde kullanıma kapalı olmayan kelimeler dışında kalmak kaydıyla istediğiniz herhangi bir sözcük olabilir. Daha sonra bu program parçalarına goto ve gosub komutuyla erişebilirsiniz.
Portların Durumunun Tespit Edilmesi ve if then Komutu:
Portların durumları digital olarak belirlendiğinde ve giriş olarak tanımlandığında portun 1 bitinden okunacak durum bilgisi 1 yada 0 olabilir. Eğer porttan bilgi okuyup değerlendirmek istersek bunu if then komutuyla yapabilirsiniz. Alttaki örnek program portb nin 6 ıncı bitini 1 saniye aralıkla kontrol eder ve portb nin 6 ıncı bitinin durumu 1 olursa porta nın 2 inci bitini 1 yapar, 0 olursa 0 yapar.
Okunan portun 1 bitinin durumunun 1 olması için pinde 3 ila 5 volt arası gerilim olması gerekir. Çıkış olarak belirlenen port 1 ise 5 volttur. 0 ise 0 volttur
Device=16F628A
Xtal 20
All_Digital = true
TRISB.7=1
TRISB.6=1
TRISA.2=0
PORTA.2=0
bak:
If PORTB.6=1 Then
PORTA.2=1
EndIf
If PORTB.6=0 Then
PORTA.2=0
EndIf
DelayMS 1000
GoTo bak
Tekrar Komutu for next :
Program içerisinde bir işin birden fazla tekrar etmesi istendiğinde for next komutu kullanılır. Alttaki program porta’nın 2 inci bitini, belirlenen zaman aralıklarıyla 5 volt ve 0 volt yapar ve belirlenen iş adeti bittiğinde mikrodenetleyiciyi boş bir işleme alarak başka işlem yapmasını engeller.
Device=16F628A
Xtal 20
All_Digital = true
Dim sayi As Word
TRISB.7=1
TRISB.6=1
TRISA.2=0
For sayi=0 To 995 Step 1
PORTA.2=0
DelayMS 1000
PORTA.2=1
DelayMS 1000
Next
Dur:
GoTo Dur
Print Komutu:
Yukarıda anlatılan bağlantıları tamamladıysanız bundan sonra devre kısmı hep aynı kalacak sadece program değişecek. Proton Basic’de LCD’ ye yazı yazmak için Print komutu kullanılır fakat bu komutu kullanmadan önce programda mikro denetleyici tanımı ve kristal tanımından sonra LCD ekranının 16f628 ile olan bağlantısıyla ilgili bazı tanımlamalar yapmak gerekiyor
Declare LCD_Type 0 (lcd ekranın hd 44780 komut setine sahip olduğunu belirtir)
Declare LCD_DTPin PORTB.0 (lcd ekranın son 4 bit data erişim portu nun 16f628 de belirtilen pin den başladığını ve 3 port daha devam ettiğini belirtir)
Declare LCD_ENPin PORTB.4 (lcd ekranın en portunun 16f628 in belirtilen portuna bağlı olduğunu belirtir)
Declare LCD_RSPin PORTB.5 (lcd ekranın rs portunun 16f628 in belirtilen portuna bağlı olduğunu belirtir)
Declare LCD_Interface 4 (lcd ekranla 16f628 in 4 bit haberleşme yapacağını belirtir)
Declare LCD_Lines 2 (lcd ekranın 2 satır olduğunu belirtir)
Tanımlamalardan sonra lcd ekranın açılması için 500 milisaniye bekleyiniz. Ekranı temizlemek için cls komutu kullanılır. Print komutu nun kullanım şekline örnek olarak:
Print at 1,2,”tb2nhd”
Bu komut LCD ekranın 1inci satırının ikinci sütunundan itibaren tb2nhd yazısını yazar. Eğer program içerisindeki bir değişkeni ekrana yazmak istersek uygulayacağımız yol:
Örnek frekans isimli 16 bit değişkenimizi Print at 2,1,dec5 frekans komutuyla yazabiliriz. Burada karşımıza yeni çıkan dec5 ifadesi değişkeni decimal olarak 5 hanede yazmak istediğimizi belirtir. Eğer dec çeviricisi kullanılmayıp komut satırımız Print at 2,1,frekans olsaydı bu sefer ekrana frekans değişkeni içerisindeki ascii kod karşılığına denk gelen karakter yazılacaktı. Print komutunun çok daha değişik kullanım şekilleri ile ilgili gerekli bilgiyi proton basic in yardım bölümünden bulabilirsiniz alttaki kod basit bir uygulamadır.
Device=16F628A
Xtal 20
All_Digital = true
Declare LCD_Type 0
Declare LCD_DTPin PORTB.0
Declare LCD_ENPin PORTB.4
Declare LCD_RSPin PORTB.5
Declare LCD_Interface 4
Declare LCD_Lines 2
TRISB.6=1
TRISB.7=1
TRISA.2=0
PORTA.2=0
Dim frekans As Dword
frekans=145650
DelayMS 500
Cls
Print At 1,1,"frekans sayici"
Print At 2,1,Dec6 frekans," khz"
Dur:
GoTo Dur
Frekans Sayıcı Program Tipleri:
Frekans saymanın 2 tipi var dır. Birincisi oluşan bir periyodun high ve low zamanını sayıp bir saniyede oluşabilecek frekansı hesaplamaktır. İkinci yöntem ise bir saniyede oluşan toplam periyodu saymaktır.
Birinci tipte yapılan frekans sayıcı yüksek çözünürlükte düşük frekanslı olur. İkinci tipte yapılan frekans sayıcı ise daha yüksek frekansları sayabilir.
Düşük Frekanslı Yüksek Çözünürlüklü Frekans Sayıcı Yapmak:
Frekansı sayabilmek için önce porttaki low durumu beklenir. Daha sonra low durumunda hiçbir işlem yapmadan high durumu beklenir. High durumu oluşunca belirli zaman aralıklarıyla bir değişken in değeri arttırılır. Low durumu oluşup oluşmadığına bakılıp, low durumu oluşunca yine aynı değişkenin değeri aynı zaman aralıklarıyla arttırılır. High durumu oluşup oluşmadığına bakılıp, high durumu oluşunca işlem durdurulur ve bir saniyede oluşabilecek frekans hesaplanıp LCD ekrana yazılır.
Burada dikkat edilecek durum bekletme komutları olan delayms ve delayus un özellikleri dir,
Örnek Delayms 1000 yazdığınızda hiçbir zaman tam 1 saniye olmaz ufak ta olsa değişiklik gösterebilir siz bunu ölçüm sonuçlarınıza göre değiştiriniz delayus komutunun kullandığınız kristale göre bekleyebileceği en alt zaman vardır. 20 mhz için 2 mikro saniyedir yani yazabileceğiniz en düşük değer delayus 2 dir. 1 yazsanız da yine 2 mikro saniye bekler. Diğer kristaller için yardım dosyasına bakınız. İkinci dikkat edilmesi gereken mikrodenetleyicinin her yaptığı iş bir zaman kaybıdır. (Komut işleme süresi) Port durumunu kontrol etmek için kullanacağımız if then komutu ve sayaç artırmakta kullanacağımız matematiksel işlemde bir zaman kaybıdır. Bütün bunlar, hesaplamada elde edilen sonucu etkiler. Şu anda sizlere interrupt yani kesmeler ve zamanlayıcı (timer) ile ilgili bilgi aktarmadığım için sizlerin uygulayabileceği en güzel yöntem, elde edilen sonuç ile uyguladığınız frekansı karşılaştırıp delayus komutunu arttırmak ya da eksiltmektir.
Eğer daha az zaman beklemeleri oluşturmak isterseniz assembler olarak nop komutunu kullanabilirsiniz. 20 mhz de 5 nop komutu 1 mikro saniyedir.
Eğer sinyal jeneratörünüz yoksa yapılan devreyi ayarlamak için bilgisayar ortamında devrelerin analizinde kullanılan proteus ve benzeri programları kullanarak ayarları netleştirebilirsiniz. Aşağı yukarı gerçek zamanda yapılan ölçümleri yapabilirsiniz.
Aslında sadece high zamanı sayarak ve low zaman nında eşit olacağını düşünerek hesaplama yapabilirdik fakat pwm kullanılarak üretilmiş sinyallerde her zaman high zamanı ile low zamanı eşit olmaz. Bu durum ölçüm sonucunun yanlış olmasına sebep olur. Bu yüzden işlemi biraz uzatarak low zamanını da sayıyoruz.
Birde ölçüm işlemine başlarken portun low durumunu bekledik ve high durumu oluşunca saymaya başladık. Bunun sebebini şöyle açıklayabiliriz. İlk gördüğümüz durumu saymaya başlasa idik belki high veya low durumunun yarısından başlayacaktık bu yüzden ilk low durumunu aradık daha sonra high durumu oluşunca saymaya başladık.
Alttaki Proton Basic programı yukarda anlattığım şekilde yazılmış ve bilgisayar ortamında proteus programı kullanılarak netleştirilmiştir. Program 5 mikrosaniye aralıklarla sayar ve hesaplama yapar. Frekans yükseldikçe ölçekleme oranı lineer olarak ters orantıda düşer. Alttaki tablo orantıyı göstermektedir.
Device =16F628A
Xtal 20
All_Digital = true
Declare LCD_Type 0
Declare LCD_DTPin PORTB.0
Declare LCD_ENPin PORTB.4
Declare LCD_RSPin PORTB.5
Declare LCD_Interface 4
Declare LCD_Lines 2
TRISB.6=1
TRISB.7=1
TRISA.2=0
PORTA.2=0
Dim sayac As Dword
Dim yazi As Float
DelayMS 500
Cls
Print At 1,1,"tb2nhd"
Print At 2,1,"frekans sayici"
DelayMS 1000
olc:
sayac=0
If PORTB.6=0 Then
GoTo lowdurumu
End If
GoTo olc
lowdurumu:
If PORTB.6=1 Then
GoTo highdurumusay
End If
GoTo lowdurumu
highdurumusay:
sayac=sayac+1
DelayUS 6
nop
nop
If PORTB.6=1 Then
GoTo highdurumusay
End If
lowdurumusay:
sayac=sayac+1
DelayUS 6
nop
nop
If PORTB.6=0 Then
GoTo lowdurumusay
End If
yaz:
Cls
Print At 2,1,Dec sayac," adet"
yazi=100000/sayac
If sayac >10000 Then
Print At 1,1,Dec2 yazi," hz"
End If
If sayac >1000 And sayac <10001 Then
Print At 1,1,Dec1 yazi," hz"
End If
If sayac >9 And sayac <1001 Then
Print At 1,1,Dec (100000/sayac)," hz"
End If
DelayMS 200
GoTo olc
Yukarıdaki programda highdurumusay ve lowdurumusay label’larının altında delayus 6 ve 2 adet nop komutu var. Aslında olması gereken delayus 5 idi. Fakat bilgisayarda proteus programında kurduğum devrede ayar yaparken bu şekilde ayar yapabildim. Gerçek zamanda sinyal jeneratörü ile yapacağınız ayarlarda delayus değerlerini değiştirerek ayar yapınız.
Program 1 hz den 10 kilohertz’e kadar çözünürlük tablosunda verilen değerlerde ölçüm yapar.
Proton Basic de Counter Komutu ile Frekans Saymak:
Proton Basic in 125 khz kadar olan frekansları saymak için hazır komutu vardır. Counter komutunda dikkat edilecek husus komutun kullanılan kristal değerine göre değişiklik göstermesidir. Ayrıntılı bilgi için yardım dosyasına bakınız. Yukarıda da belirttiğim gibi bu komut 125 khz’e kadar sayabilir. Fakat en fazla bir word değişken içine 65535 değerini yazabilir. Eğer 65535 hz den 125 khz e kadar olan bir değeri saymak isterseniz dword tipinde değişken kullanıp 1saniye yerine 500 milisaniye bekletip sonucu yazarken 2 ile çarpınız. Aşağıda her iki durumu da açıklayan örnek programı veriyorum.
Counter komutu ile 65 khz e kadar sayan program:
Device =16F628A
Xtal 20
All_Digital = true
Declare LCD_Type 0
Declare LCD_DTPin PORTB.0
Declare LCD_ENPin PORTB.4
Declare LCD_RSPin PORTB.5
Declare LCD_Interface 4
Declare LCD_Lines 2
TRISB.6=1
TRISB.7=1
TRISA.2=0
PORTA.2=0
Dim sayac As Word
DelayMS 500
Cls
Print At 1,1,"tb2nhd"
Print At 2,1,"frekans sayici"
DelayMS 1000
olc:
Cls
sayac= Counter PORTB.6,1000
Print At 1,1,Dec sayac," hz"
DelayMS 200
GoTo olc
Counter komutu ile 125 khz e kadar sayan program:
Device =16F628A
Xtal 20
All_Digital = true
Declare LCD_Type 0
Declare LCD_DTPin PORTB.0
Declare LCD_ENPin PORTB.4
Declare LCD_RSPin PORTB.5
Declare LCD_Interface 4
Declare LCD_Lines 2
TRISB.6=1
TRISB.7=1
TRISA.2=0
PORTA.2=0
Dim sayac As Dword
DelayMS 500
Cls
Print At 1,1,"tb2nhd"
Print At 2,1,"frekans sayici"
DelayMS 1000
olc:
Cls
sayac= Counter PORTB.6,500
Print At 1,1,Dec (sayac*2)," hz"
DelayMS 200
GoTo olc
16f628a daki Timer1 Sayacını Kullanarak Yüksek Hızlı Frekans Sayıcı Yapmak:
16f628a mikro denetleyicide harici olarak çalışan ve program yazarken istediğimiz zaman değişik bağlantı noktalarındaki adımları sayabilen bir sayac vardır. Sayac değeri 16 bitlik tir. Üstteki programlarda adımları sayarken başka bir iş yapmak mümkün olmadı. Oysa Timer1 sayacını kullanırsak sayacı başlatıp başka işler yapıp daha sonra sayacı durdurup kaç adım saydığını kontrol edebiliriz. Ayrıca bu sayacın kendi içinde ayarlanabilir bir frekans bölücüsü vardır. Harici olarak saydığından diğer programlarda ki en yüksek frekans limitinden çok daha hızlı sayabilir ve 65mhz hıza erişebilir. Alttaki programlarda timer1 sayacı kullanılarak yapılmış 1 hz den 65 mhz e kadar frekans sayıcı program örnekleri var. Programlarda timer1 başlatıldıktan sonra bekleme için delayms komutu kullanılmıştır. Bu komutla çok keskin zamanlama elde edilemediği için siz ayar yaparken komutun bekleme süresini değiştiriniz. Eğer ayarlarken 1 birim değiştirmenize rağmen hala tam ayarlayamıyorsanız bir alt satırda delayus komutuyla ayarlamaya çalışın. Yine de olmazsa bir alt satıra nop komutuyla devam edin. Daha üst frekansları saymak icin 1/10 1/100 1/1000 gibi frekans bölücü entegreler kullanmak gerekecektir. İnternette bulduğum frekans sayıcılarda kullanılan frekans bölücüler her yerde bulunmuyor bu yüzden yazıya herhangi bir frekans bölücü bölümü dahil etmedim.
Timer1 ile 0- 65 khz 1hz Çözünürlüklü Frekans Sayıcı:
Device =16F628A
Xtal 20
All_Digital = true
Declare LCD_Type 0
Declare LCD_DTPin PORTB.0
Declare LCD_ENPin PORTB.4
Declare LCD_RSPin PORTB.5
Declare LCD_Interface 4
Declare LCD_Lines 2
TRISB.6=1
TRISB.7=1
TRISA.2=0
PORTA.2=0
Dim sayac As Dword
DelayMS 500
Cls
Print At 1,1,"tb2nhd"
Print At 2,1,"1hz 65 khz "
DelayMS 1000
Cls
olc:
T1CON=%00000010
TMR1L=0
TMR1H=0
T1CON=%00000111
DelayMS 1000
T1CON=%00000010
sayac=TMR1H * 255
sayac=sayac + TMR1L
Cls
Print At 1,1,Dec sayac," hz"
DelayMS 200
GoTo olc
Timer1 ile 65 khz 650 khz 10 hz Çözünürlüklü Frekans Sayıcı
Üstteki programda sayma esnasında 1 saniye bekledik. Kullandığımız sayaç timer1 16 bit oluğu için en fazla 65535 adım sayabiliyordu. 650 khz’e kadar saymak için 1 saniye yerine 100 milisaniye bekleyip okuduğumuz rakamı 10 ile çarptık. Bu şekilde 10 hz çözünürlüklü 65 khz ile 650 khz sayma işlemi yaptık.
Device =16F628A
Xtal 20
All_Digital = true
Declare LCD_Type 0
Declare LCD_DTPin PORTB.0
Declare LCD_ENPin PORTB.4
Declare LCD_RSPin PORTB.5
Declare LCD_Interface 4
Declare LCD_Lines 2
TRISB.6=1
TRISB.7=1
TRISA.2=0
PORTA.2=0
Dim sayac As Dword
DelayMS 500
Cls
Print At 1,1,"tb2nhd"
Print At 2,1,"65 khz 650 khz"
DelayMS 1000
Cls
olc:
T1CON=%00000010
TMR1L=0
TMR1H=0
T1CON=%00000111
DelayMS 100
T1CON=%00000010
sayac=TMR1H * 255
sayac=sayac + TMR1L
Cls
Print At 1,1,Dec (sayac*10)," hz"
DelayMS 200
GoTo olc
Timer1 ile 650 khz 6.5 mhz 100 hz çözünürlüklü frekans sayıcı
Device =16F628A
Xtal 20
All_Digital = true
Declare LCD_Type 0
Declare LCD_DTPin PORTB.0
Declare LCD_ENPin PORTB.4
Declare LCD_RSPin PORTB.5
Declare LCD_Interface 4
Declare LCD_Lines 2
TRISB.6=1
TRISB.7=1
TRISA.2=0
PORTA.2=0
Dim sayac As Dword
DelayMS 500
Cls
Print At 1,1,"tb2nhd"
Print At 2,1,"650 khz 6,5 mhz"
DelayMS 1000
Cls
olc:
T1CON=%00000010
TMR1L=0
TMR1H=0
T1CON=%00000011
DelayMS 10
T1CON=%00000010
sayac=TMR1H * 255
sayac=sayac + TMR1L
Cls
Print At 1,1,Dec (sayac*100)," hz"
DelayMS 200
GoTo olc
Timer1 ile 6.5 mhz 65 mhz 1000 hz çözünürlüklü frekans sayıcı
Device =16F628A
Xtal 20
All_Digital = true
Declare LCD_Type 0
Declare LCD_DTPin PORTB.0
Declare LCD_ENPin PORTB.4
Declare LCD_RSPin PORTB.5
Declare LCD_Interface 4
Declare LCD_Lines 2
TRISB.6=1
TRISB.7=1
TRISA.2=0
PORTA.2=0
Dim sayac As Dword
Dim yazi As Float
DelayMS 500
Cls
Print At 1,1,"tb2nhd"
Print At 2,1,"6,5 mhz 65 mhz"
DelayMS 1000
Cls
olc:
T1CON=%00000000
TMR1L=0
TMR1H=0
T1CON=%00000111
DelayMS 1
T1CON=%00000000
sayac=TMR1H * 255
sayac=sayac + TMR1L
yazi=sayac/1000
Cls
Print At 1,1,Dec yazi," mhz"
DelayMS 200
GoTo olc
Timer1 Sayacının Interrupt Özelliğini Kullanarak 16 bitlik Sayacı 32 bit Yapmak:
16f628a mikro denetleyicide bulunan timer1 sayacı 16 bitlik olduğundan en fazla 65535 adım sayabiliyordu. Eğer bu adım sayısı yetersiz olursa timer1 sayacının interrupt özelliğini kullanarak 32 bit adım saydırabiliriz. Interrupt özelliği şöyle çalışır:
Ttimer1 sayacı 65535 e kadar sayar 1 adım daha saydığında sayaç 0 olur ve interrupt özelliği kurulmuş ise yaptığı işlemleri kaydedip interrupt komutu ile yönlendirdiğiniz program bölümüne gidip oradaki işlemleri yaptıktan sonra tekrar kaldığı yerden devam eder. Burada oluşacak sorun delayms ve delayus komutlarının interrupt kullanım özelliğine kapalı olmasıdır. Yani interrupt özelliğini aktif edip bir alt satırda delayms 1000 veya delayus 10000 gibi bir bekletme komutu kullanırsanız bekletme komutları zamanı bitene kadar interrupt oluşsa bile yazdığınız komutlar süre sonunda çalışır. Bu durum programın yanlış işlemesine sebep olur. Bunun yerine interrupt kullanım özelliğine açık olan for next tekrar komutu kullanılır. Eğer program 1000 milisaniye beklemesi gerekiyorsa delayms 1000 yazmak yerine örnek:
Dim zaman as word
For zaman =0 to 1000 step 1
Delayms 1
Next
Yazarsanız 1 milisaniye de bir delayms komutundan çıktığı için oluşan interrupt çalışır.
Eğer daha kısa zamanlarda çalışmasını isterseniz örnek:
Dim zaman as dword
for zaman = 0 to 500000 step 1
delayus 2
next
Yazarsanız 2 mikrosaniye de bir delayus komutundan çıktığı için oluşan interupt çalışır.
Ya da delayms ve delayus komutlarını kullanmadan hem daha net bir süre elde edip hemde interrupt kullanım özelliğini sürekli çalışır yapmak isterseniz alttaki örnek 20 mhz kristal kullanımı için geçerlidir:
Dim zaman as dword
For zaman = 0 to 1000000 step 1
Nop
Nop
Nop
Nop
Nop
Next
Şeklinde bekletme komutları kullanabilirsiniz
Alttaki örnek programda timer1 sayacının interrupt özelliği kullanılarak sayabileceği adım sayısı 32 bit yapılmıştır. Adım sayısı yüksek olmasına karşın 1 saniyede sayabileceği adım sayısı sayacın çalışma hızıyla sınırlıdır. Ayrıca her oluşan interrupt, sayılan adımların bir kısmının eksik sayılmasına sebep olacağı için sayacağınız en yüksek adımla oluşan interrupt sayısını orantılayıp hesaplamanız gerekecektir. Programda olması gereken değerleri yazdım. En güzel ayar devreyi kurup sinyal jeneratörü ile frekans uygulayıp bekleme değerleri ve interupt oluşunca eksik sayılan adımların hesap orantılarında değişiklikler yaparak olacaktır.
Device =16F628A
Xtal 20
All_Digital = true
Declare LCD_Type 0
Declare LCD_DTPin PORTB.0
Declare LCD_ENPin PORTB.4
Declare LCD_RSPin PORTB.5
Declare LCD_Interface 4
Declare LCD_Lines 2
TRISB.6=1
TRISB.7=1
TRISA.2=0
PORTA.2=0
Dim sayac As Dword
Dim zaman As Dword
Dim arti As Word
On Interrupt GoTo arttir
INTCON =%11000000
PIE1 = %00000001
DelayMS 500
Cls
Print At 1,1,"tb2nhd"
Print At 2,1,"timer1 32 bit"
DelayMS 1000
Cls
olc:
arti=0
T1CON=%00000000
TMR1L=0
TMR1H=0
T1CON=%00000111
For zaman = 0 To 1000000 Step 1
nop
nop
nop
nop
nop
Next
T1CON=%00000000
sayac=TMR1H * 255
sayac=sayac + TMR1L
sayac=sayac+(arti*65535)
Cls
Print At 1,1,Dec sayac," adim"
DelayMS 200
GoTo olc
arttir:
Disable
INTCON.7=0
PIR1.0=0
arti=arti+1
INTCON.7=1
Enable
Resume
End
Timer1 Sayacının İçindeki Frekans Bölücüsünü Ayarlamak:
Timer1 sayacının içinde bölücü oranı ayarlanabilir bir frekans bölücüsü vardır. Yukarıdaki programlarda gerekli olmadığı için kullanmadık. Eğer kullanmak isterseniz T1CON durum belirleyici komutunu alttaki değerler ile değiştiririniz
T1CON=%00000111 (frekans bölücü 1/1)
T1CON=%00010111 (frekans bölücü 1/2)
T1CON=%00100111 (frekans bölücü 1/4)
T1CON=%00110111 (frekans bölücü 1/8)