Zamanlayıcı ve sayıcılar aşağıdaki görevler için kullanılırlar.
Zaman gecikmesi yaratmak için
Pals zamanı veya zaman aralığı ölçmek için
Pals veya oluşan olayları saymak için
Çoklu işlem uygulamalarında (Multi-tasking)
Kesme üretmek için
Standart 8051 iki zamanlayıcı/sayıcıya sahiptir. Bu zamanlayıcı/sayıcılar 8 bit veya 16 bit zamanlayıcı/sayıcı olarak kullanılabilir. Aşağıda M1 ve M0 bitlerinin değerlerine bağlı olarak zamanlayıcı/sayıcıların hangi modlarda kullanılabileceği belirtilmektedir.
TMOD
M1 M0 FUNCTION
| 0 0 | 8 bit counter or 8 bit timer with / 32 scaler
| 0 1 | 16 bit timer/counter
| 1 0 | 8 bit timer counter with auto-reload to initial start for count up
| 1 1 | TC1 - disabled
TH0 - TH0 is an 8 bit timer incremented by setting TR1.Interrupts are channelled to .001Bh
TL0 - is an 8 bit timer/counter controlled by TMOD and TCON
Zamanlayıcı/sayıcı çalıştır bitleri TR1 ve TR0, TCON registerinde bulunur. Bu bitlerden birisi "1" yapıldığında, bu bite karşılık gelen sayıcı çalışmaya başlar. Bu bitlerin değeri "0" yapıldığında zamanlama/sayma işlemleri de bitirilmiş olur. Kesme kontrolü registerinde (IE) bulunan ET1 ve ET0 bitleri, zamanlayıcı taşmasında kesme üretilip üretilmeyeceğini belirlemekte kullanılır. Bit değerinin "1" olması, zamanlayıcı/sayıcı taşmasının kesme üretmesi anlamına gelir.
TMOD registerindeki C/T biti, zamanlaycı/sayıcıyı, sayıcı modunda veya zamanlayıcı modunda çalıştırmak için kullanılır. Bu bitin değeri "1" yapıldığında zamanlayıcı/sayıcı, 8051 entegrenin TX giriş pinindeki olayları saymak üzere konfigüre edilmiş olur.
Bu bitin değeri "0" olduğunda zamanlayıcı/sayıcı, zamanlayıcı modundadır ve sistem osilatöründen gelen sinyali 12'ye bölerek çalışır.
TMOD registerindeki GATE biti, "1" yapıldığında, zamanlayıcı/sayıcı n'in aktif olması için, INTn ve TRn bitleri "1" yapılmalıdır. GATE biti "0" yapıldığında zamanlayıcı/sayıcı n,in aktif yapılması için, TRn bitinin "1" yapılması yeterlidir. GATE biti zamanı ölçmekte, olayların zamanını ölçmekte, pals genişliğini ölçmekte kullanılır. INTx hattı "1" olduğu sürede, bu değerler sayıcya geçirilir. Sistem osilatörünün frekansı 12'ye bölünerek zaman sayması gerçekleşir. Buna göre 12 MHz osilatör kullanan bir sistemde, zamanlayıcının frekansı 1 Mhz olur.
T0 Giriş Ucundan Pals Sayılması zamanlayıcı 0 (mod 1)
; T0 ucuna gelen dış sinyallerin sayılması
MOV TH0, #0 ; zamanlayıcı/sayıcıyı sıfırla
MOV TL0, #0 ;
MOV TMOD, #5 ; zamanlaycı/sayıcıyı sayma moduna getir.
; C/T=1, Mod 1
SETB TR0 ; zamanlayıcı/sayıcıyı başlat
; Sayılan olay sayısı herhangi bir anda TH0/TL0 registerlerinin okunmasıyla ; elde edilebilir. Sayma olayı, mikrokontrolcünün asıl yaptığı işten bağımsız ; olarak geri planda sayılır.
Yukarıdaki program parçasında frekansı yüksek olayların sayılması sırasında önemli bir problem ortaya çıkabilir. Örneğin zamanlayıcı 0'ın içeriği okunup, program tarafından kullanılamadan zamanlayıcı 0 taşmış olabilir.
Ön Düzenleme Kullanılarak Pals
sayılması (mod 0)
Öndüzenleme mod 0 kullanılarak, girişte oluşan palslar
32 ye bölünebilir. Bu sayede çok hızlı olayların
sayılması kolaylaşmış olacaktır. Zamanlayıcı/sayıcı
girişte 32 olay oluştuğunda 1 artacaktır.
;T0 ucunda oluşan olayları 32'ye bölerek say
MOV TH0, #0 ; zamanlayıcı/sayıcıyı sıfırla.
MOV TL0, #0 ;
MOV TMOD, #4 ; zamanlayıcı 0 sayıcı modunda , C/T=1, Mod 0
SETB TR0 ; zamanlayıcı/sayıcıyı başlat
Zaman dilimi yaratmak Mod 1: 16 bit zamanlayıcı/sayıcı
Zamanlayıcı/sayıcılar, işlemcinin servisine gerek duymadan geri planda çalışabildiklerinden, zamanlayıcı/sayıcılar kullanılarak zaman dilimi yaratmak ve gerçek zamanı saydırmak olanaklıdır.
Eğer zamanlayıcı/sayıcının her iki registeri, 00h değeriyle yüklenirse, bir taşma meydana gelmeden önce, zamanlayıcı/sayıcı 65,536 sayma gerçekleştirecektir. 12 Mhz lik entegre osilatörü kullanılan bir devrede, bu yaklaşık olarak 66 milisaniyelik (65,536 mikrosaniye) zaman dilimine karşılık gelir. Pek çok uygulamada genelde daha uzun zaman gecikmelerine gereksinim olduğundan, zamanlayıcı/sayıcı registerlerine ilave olarak bir 8 bit hafıza elemanı daha kullanılır. Bu hafıza elemanın değeri her taşmada "1" azaltılarak gereken zaman dilimi yaratılır. TH0 ve TL0 registerlerinin başlangıç değerleri isteğe göre seçilebildiğinden hassas zaman dilimleri yaratmak olanaklıdır. Örneğin TH0'a 80h, TL0'a 00h değerlerinin yüklenmesiyle zamanlayıcı sayıcı her 32,768 saymada taşacaktır. Taşma gerçekleştikten sonra, register değerleri tekrar 80h ve 00h değerleriyle yüklenmelidir. Aşağıdaki program parçası, gerçek gün zamanını ölçmek için zamanlayıcı/sayıcının nasıl kullanılabileceğini göstermektedir.
org 0000h ; program başlangıç adresi JMP Anaprogram org 000Bh ; zamanlayıcı 0 kesme adresi JMP TC0kesme ; zamanlayıcı 0 kesme programına git org 0100h ; ana döngü başlangıcı Anaprogram: CALL Baslangıc ; RTC ilk değerlerini ver dongu: sjmp dongu ; ana programın yapığı is ; R0 : uzun zaman dilimi yaratmak için kullanılan değişken ;TH0 ve TL0 0000h değerine ulaşınca kesme oluşturmak üzere programlansın Baslangıc:MOV R0, #20h ; R0 * 33ms = 1sec MOV SAN, #00h ; MOV DAK, #00h ; MOV SAAT, #00h ; MOV TH0, #80h ; MOV TL0, #00h ; kesmeler arasında 33ms MOV TMOD, #01 ;C/T=0, mod 1 (16bit zamanlayıcı) MOV TCON, #10h ;zamanlayıcı 0'ı başlat MOV IE, #82h ;tüm kesmeleri aktifle biti "1" ;zamanlayıcı "0" kesmesi aktif RET ;Zamanlayıcı 0 olduğunda devreye girecek kesme programı TC0kesme: DEC R0 ;sayıcı değişkeni azalt MOV A, R0 ;akümülatore al JNZ TC0CIK ;sıfır değilse geri don MOV R0, #20h ;R0'ın ilk değerini tekrar yükle INC SAN ;saniye = saniye + 1 MOV A, SAN ; SUBB A, #60 ;saniye >= 60 ? JNZ TC0Cık ; MOV SAN, #00 ;saniye = 0 INC DAK ;dakika = dakika + 1 MOV A, DAK ;dakika >= 60 ? SUBB A, #60 ; JNZ TC0CIK ; MOV DAK, #00 ;dakika = 0 INC SAAT ;saat = saat + 1 MOV A, SAAT ;saat >= 24 ? SUBB A, #24 ; JNZ TC0CIK ; MOV SAAT, #00 ;saat = 0 TC0CIK: MOV TH0, #80h ; MOV TL0, #00h ; CLR TF0 ; RETI ; SAN EQU R2 ; DAK EQU R3 ; SAAT EQU R4 ; End
Zaman Dilimi Yaratmak Mod 2: 8 bit Otomatik Yeniden-yükleme
(Auto-Reload)
Bir önceki örnekte, zamanlayıcı registerleri kesme programı
içerisinde yeniden yüklenmek zorundaydı. Zamanlayıcı
otomatik yeniden yükleme modunda kullanarak THx registerindeki
değerin otomatik olarak TLx değerine yüklenmesi olanaklıdır.
THx yeniden yükleme değeri olarak adlandırılır ve TLx'de
normal zamanlayıcı görevini görmektedir. Bu yöntemin tek
dezavantajı, sayma işleminin yalnızca 8 bit olmasııdır
(Önceki örnekte 16 bit olduğuna dikkat ediniz). Aşağıda
gün zamanı ölçümünün bu modda nasıl yapılabileceği bir
örnekle verilmiştir.
org 0000h ; program başlangıç adresi JMP Anaprogram org 0Bh ; zamanlayıcı 0 kesme adresi JMP TC0kesme ; zamanlayıcı 0 kesme programına git org 100h ; ana döngü başlangıcı Anaprogram: CALL Baslangıc ; RTC ilk değerlerini ver dongu: sjmp dongu ; ana programın yaptığı iş ; R0 : uzun zaman dilimi yaratmak için kullanılan değişken ;TH0 ve TL0 0000h değerine ulaşınca kesme oluşturmak üzere ;programlansın Baslangıc:MOV R0, #20h ; R0 * 33ms = 1sec MOV R1, #80h ; R0 azaltılmadan önce kaç döngü MOV SAN, #00h ; MOV DAK, #00h ; MOV SAAT, #00h ; MOV TH0, #00h ; 256 kere MOV TL0, #00h ; kesmeler arasında 33ms MOV TMOD, #02 ;C/T=0, mod 2 MOV TCON, #10h ;zamanlayıcı 0'i başlat MOV IE, #82h ;tüm kesmeleri aktifle biti "1" ;zamanlayıcı "0" kesmesi aktif RET ;Zamanlayıcı 0 olduğunda devreye girecek kesme programı TC0KESME: DEC R1 ;her 80h seferde R0'i azalt MOV A, R1 ;akumulatore al JNZ TC0CIK ;sıfır değilse geri don MOV R1, #80h ;R1'i tekrar yükle DEC R0 ; MOV A, R0 ; JNZ TC0CIK ; MOV R0, #20h ; R0 ilk değerini tekrar yükle INC SAN ;saniye = saniye + 1 MOV A, SAN ; SUBB A, #60 ;saniye >= 60 ? JNZ TC0CIK ; MOV SAN, #00 ;saniye = 0 INC DAK ;dakika = dakika + 1 MOV A, DAK ;dakika >= 60 ? SUBB A, #60 ; JNZ TC0CIK ; MOV DAK, #00 ;dakika = 0 INC SAAT ;saat = saat + 1 MOV A, SAAT ;saat >= 24 ? SUBB A, #24 ; JNZ TC0CIK ; MOV SAAT, #00 ;saat = 0 TC0CIK: MOV TH0, #80h ; MOV TL0, #00h ; CLR TF0 ; RETI ; SAN EQU R2 ; DAK EQU R3 ; SAAT EQU R4 ; END
Zamanlayıcı/Sayıcının Mod 3 de
kullanımı
Bu modda zamanlayıcı/sayıcının TH0 ve TL0 registerleri
iki bağımsız sayıcı olarak kullanılır. TCON ve TMOD
registerlerindeki bit kontrolleri TH0 registerindeki taşmaları
kontrol eder. Kesme oluşumu TH0'ın taşması ile meydana
gelir.
Pals Genişliği veya olay zamanı ölçme
(Gating)
Zamanlayıcı/sayıcı Mod 3 kullanılarak, pals genişliği,
geçen zaman ve durum sayımı gerçekleştirilebilir. Kapılama
biti (Gating) aktiflendiğinde, zamanlayıcı yalnızca, INTx
girişi "1" olduğu sürece aktif kalır. Bu sayede,
INTx girişindeki bir sinyalin aktif olduğu zaman miktarını
bulmak mümkündür. Aşağıdaki örnek, böyle bir
uygulamayı anlatmaktadır.
org 0000h ; program başlangıç adresi JMP AnaProgram org 000Bh ; Zamanlayıcı 0 kesme adresi SETB F0 ; F0 bitini tasma olduğunu belirtmek üzere aktifle RETI ; kesmeden dönüş org 001Bh ; Zamanlayıcı 1 kesme adresi RETI ; Kesmeden dönüş Anaprogram: CALL BaslangIc lp1: JNB P3.2, lp1 ;INT0 düşükse döngü lp2: JB P3.2, lp2 ;INT0 yüksekse döngü ;Bu noktada, TL0 içerisinde, INT0 yüksek olduğu süredeki sayma değeri bulunmaktadır. ;Bu değer kolaylıkla zaman bilgisine çevrilebilir. lp3: JB F0, Hata ; F0 "1" se Hata CALL Cevır ;Tl0 daki değeri zaman bilgisine cevir CLR F0 ; F0'i temizle JMP lp1 ; tekrar don BaslangIc: MOV TH0, #0h ; MOV TL0, #0h ; MOV TMOD, #07h ;C/T=1, Mod 3, Timer 0 MOV TCON, #10h ;zamanlayıcıyı başlat MOV IE, #82h ;Kesmeleri aktifle CLR F0 ;F= bayrağını temizle RET ; Hata: JMP HataIsleme CevIr: RET ; end