16f877 tmr1 kesme harici clock

Başlatan safaka123, 20 Ağustos 2013, 17:07:59

safaka123

16f877 ile tmr1 kesme kullanmak istedim ekteki program internal osc ile bu ayarla çalışıyor. İstediğim ds1307 entegresinin 7 nolu bacağından çıkan saat palsini rc0(t1oso) bacağına vererek harici osc ile çalışmasını sağlamak. Burada bir mantık hatası varmıdır. buraya illaki bir xtal takıp rc0 ve rc1 uçlarını mı kullanmak gerek.
ŞAyet benim düşündüğüm şekilde oluyorsa tmr1 ayarları nasıl olmalı harici osc kullanımı için.

http://sdrv.ms/16srgtX

program bu adreste mevcut. İnternette araştırdığım örneklerin hemen hepsi internal osc ye göre yapılmış. Bu konuda bir örnek verebilirmisiniz.

Teşekkürler.

safaka123

TMR1 kesmesi dahili osc ile çalışıyor fakat harici saat palsi ile çalışmıyor. Bunun nedeni nedir. Harici saat palsi ile çalışması için tmr1 ayarları nasıl olmalı.  bu konuda bilgi verebilirmisiniz.

Bayramsumbul

Merhabalar...Bakınız Datasheet Sayfa:57
Alıntı YapIn Timer mode, Timer1 increments every instruction
cycle. In Counter mode, it increments on every rising
edge of the external clock input.
Burada "Timer" Modunda Harici Saat'ten Bahsetmemiş.(Bu Demek Değildir ki Harici Saat Kullanılmaz)
Sayıcı Modunda İse Harici Saat İle Her Bir Hertz'de Bir Artacağı Belirtilmiş.
Yine Bakınız Sayfa:58
Alıntı YapTimer mode is selected by clearing the TMR1CS
(T1CON<1>) bit. In this mode, the input clock to the
timer is FOSC/4. The synchronize control bit, T1SYNC
(T1CON<2>), has no effect since the internal clock is
always in sync.
Burada "Timer" Modunda Ana Saat/4 Oranından Bahsetmiş.
Yani Anladığım Kadarıyla Senkronize Sayıcı Modunda Harici Saat Kullanılabiliyor.
Bir Elektronik Meraklısının Serüveni...

safaka123

dahili osc ile sorun yok çalışıyor sanırım osc/4 oranında çalışıyor. Fakat harici saat palsi ayarlamalarında çalışmıyor.
Datasheet tekrar baktım sanırım xtal ile harici osc olarak çalışıyor. Fakat sizin dediğiniz gibi sayıcı olarak çalıştırsam 1-) nasıl ayarlamam lazım. 2-) bu sayaç kesmeye gönderebilecek mi . Amacım rc0 dan giren 4096hz lik sinyalden 100 hz e yakın bir sayıcı elde etmek ve ayrıca hata payını azaltmak için 4096ya kadar sayıldığında resetleyerek sayıcının sıfırdan başlamasını sağlamak. Bunun için ne yapmalıyım bilemiyorum. TMR1 kesmesi tam benim istediğim düşünce fakat harici saat palsi ile çalıştıramıyorum bir xtal koyup da devam edebilirim ama bu konuyu çözmeliyim diye düşünüyorum.

Bayramsumbul

İsterseniz C'de Veya Asm'de Bir Kod Yazıp Denerim.Mantığınıda Adım Adım Yazarım.
Bir Elektronik Meraklısının Serüveni...

safaka123

picbasic öğreniyorum henüz amatörüm, bu daha iyi olurdu ama sorun değil asm ile yazarsanız komutları takip edebilirim birde mantığını anlatırsanız sanırım anlarım. Şayet sizin için yük olmayacaksam. Anlayamamın sebebi birçok örnek gördüm hep dahili osc kullanılıyor. sanırım bir örnek iyi olur.

Teşekkürler.

Bayramsumbul

Merhabalar...Bugün Bir Kod Yazmaya Çalışırım.
Bir Elektronik Meraklısının Serüveni...

ferit06

Alıntı yapılan: safaka123 - 22 Ağustos 2013, 00:46:22
dahili osc ile sorun yok çalışıyor sanırım osc/4 oranında çalışıyor. Fakat harici saat palsi ayarlamalarında çalışmıyor.
Datasheet tekrar baktım sanırım xtal ile harici osc olarak çalışıyor. Fakat sizin dediğiniz gibi sayıcı olarak çalıştırsam 1-) nasıl ayarlamam lazım. 2-) bu sayaç kesmeye gönderebilecek mi . Amacım rc0 dan giren 4096hz lik sinyalden 100 hz e yakın bir sayıcı elde etmek ve ayrıca hata payını azaltmak için 4096ya kadar sayıldığında resetleyerek sayıcının sıfırdan başlamasını sağlamak. Bunun için ne yapmalıyım bilemiyorum. TMR1 kesmesi tam benim istediğim düşünce fakat harici saat palsi ile çalıştıramıyorum bir xtal koyup da devam edebilirim ama bu konuyu çözmeliyim diye düşünüyorum.

TMR1 i 65536-(bölme oranı( 4096 ya bölseydiniz kolay olacaktı siz 4096/100=41==> 65536-41  TMR1=65495 ile )) yükleyeceksiniz sonra TMR1 taşması ile interrupt elde edeceksiniz.

Bayramsumbul


Merhabalar...Kodunuzu ASM Olarak Yazdım.
İlk Olarak Kodumu Yazıyım;
list p=16F877A   
   include "p16F877A.inc"   
   __CONFIG   _WDT_OFF & _PWRTE_OFF & _CP_OFF & _BODEN_OFF & _LVP_OFF & _CPD_OFF & _XT_OSC
   #DEFINE    Leddurum   0x20,0;Led Durum Biti
   #DEFINE      Ledpin      PORTB,0;Ledimizin Bağlı Olduğu pin
   ORG       0X00;Reset Durumunda Buradan Baslar
   GOTO      Init
   ORG         0x04;Kesme Adresi
   Goto      Kesme
Init
   BSF      STATUS,RP0;BANK 1'E GECILDI
   CLRF   TRISB;PORTB TAMAMEN CIKIS
   MOVLW   0x01;Timer1 Kesmesini
   IORWF   PIE1,1;         Aktif Ettik
   BCF      STATUS,RP0;BANK 0'A GECILDI
   CLRF   PORTB;
   MOVLW   0xC0;Kesmelere
   IORWF   INTCON,1;   İzin Verildi
   MOVLW   0xFF;Timer1 Sayıcı 
   MOVWF   TMR1H;         Değeri
   MOVLW   0xFF;65,534'den Saymaya
   MOVWF   TMR1L;          Başlayacak
   MOVLW   0x0B;Timer1
   MOVWF   T1CON;   Ayarları
Basla;Sonsuz Dongu
   Nop
GOTO Basla
Kesme
   MOVLW   0xFE;Timer1 Kesme
   ANDWF   PIR1,1;         Bayrağını Temizledik
   MOVLW   0xFF;Timer1 Sayıcı 
   MOVWF   TMR1H;         Değeri
   MOVLW   0xFF;Tekrar   
   MOVWF   TMR1L;      Yüklendi
   BTFSS   Leddurum;Burada
   Goto   $+4;Ledimiz
   BCF      PORTB,0;Yanıksa
   BCF      Leddurum;Sonuk
   Goto   $+3;Sonukse
   BSF      PORTB,0;Yanık
   BSF      Leddurum;Yapıyoruz
   RETFIE
END

RC0-RC1 Arasında Bir Saat Kaynağı Var.
RB0'da Bir Led. Belirlenen Kesme Sürelerinde Led'in Durumu Tersleniyor.
(Burada Saymaya 0xFFFF'den Başlıyor Bir Artınca Taşma Oluşturup Kesme Rutinine Giriyor.
Ben İsis'te 1Hz'lik Saat Kaynağı Kullandım Yani Saniyede Bir Yanıp Sönüyor.Gerçekte Denerdim Ama Çalışması Lazım.)

Bu Arada Açıklamalara Gelince Şöyle;
1-Bank1'e Geçildi.
2-PortB Tamamen Çıkış Olarak Ayarlandı.TRISB=0x00;
3-Timer1 Kesmesini Aktif Ediyoruz.Register PIE1,Bit TMR1IE
4-Bank0'a Geçildi.
5-PortB Çıkışları 0/Low Oldu.PORTB=0x00;
6-Global Ve Çevresel Kesmelere İzin Verildi.Register INTCON,Bit GIE Ve PEIE
7-Timer1 Sayıcı Değerleri Yüklendi 0xFFFF.Register TMR1H,TMR1L
8-Timer1 Ayarları Yapıldı.Presclar 1/1,Osilator Aktif,Senkronize Mod,Harici Saat Kaynağı,Timer1 Aktif.Register T1CON
Buraya Kadar Ayar Kısmı.
Burası İse Kesme:
1-Timer1 Kesme BAyrağını Temizledik.Register PIR1,Bit TMR1IF
2-Sayıcı Değerini Tekrar Yükledik 0xFFFE .Register TMR1H Ve TMR1L.
3-Kesme Programımızı Çalıştırdık(Burda Led Yak Sondur.)
4-Kesmeden Çıktık.Retfie


Geriye Sizin Yapacağınız Hesaplamalar Kalıyor..İyi Çalışmalar,Kolay Gelsin...
Bir Elektronik Meraklısının Serüveni...

safaka123

#9
Alıntı yapılan: ferit06 - 23 Ağustos 2013, 10:57:56
TMR1 i 65536-(bölme oranı( 4096 ya bölseydiniz kolay olacaktı siz 4096/100=41==> 65536-41  TMR1=65495 ile )) yükleyeceksiniz sonra TMR1 taşması ile interrupt elde edeceksiniz.


Ferit Bey, sizin yaptığınız gibi yaptım 50hz aldım bana 100 hz lazımdı  hesapla 100hz oldu fakat küçük frekans kullandığımdan hata payı büyük oldu bundan dolayı ds1307 32768hz veriyordu onu kullandım şu anda hata payı çok çok az isis görüntüsüne göre 100hz sabit kalıyor. Teşekkürler.

mesaj birleştirme:: 23 Ağustos 2013, 16:47:23

Bayram bey.
Öncelikle örnek için çok teşekkür ederim anlamamı kolaylaştırdı. Ben tmr1h ve tmr1l değerlerini girmemiştim. tmr1=0 vardı bu da çok büyük bir sayma olduğundan belki farketmemişimdir çalıştığını. Fakat internal da sorun olmadı zira frekans çok yüksekti. Birde sizin verdiğiniz örneğe göre komut sırasını dikkat ettim belki çalışması gereken sıra yanlıştır dedim. Giriş bölümü örneğinize ve verdiğiniz değerlere göre yapılınca kesme çalıştı. Sanırım birde ben saat frekansında hata yaptım çalışınca bunu anladım herşeyin mhz hızındaymış gibi olacağını düşündüm. :) Amatörlük böyle bir şey olsa gerek. Birde kesme içine tekrar tmr1h ve tmr1l değerlerini girmediğimden devamlı 0-65536 arası sayma yaptığından görmem zaten çok zor olacaktı. Tekrar emekleriniz için çok teşekkür ederim.

ferit06

programınızı bilmediğim için ben  sn de yaklaşık 100 kesme oluşmasını düşünerek hesaplama yapmıştım.

siz programı iki aşamalı olarak yazıp ilkinde 21 ikincisinde 20 sayacak şekilde

65536-20=65516
ve
65536-21=65515
değerlerini sırasıyla yükleyerek sn de 100 kesme oluşturabilirsiniz. ancak tam 100 hz elde etmek için programınızın kesmelere gidiş dönüş ve TMR yüklemelerinizdeki süre kayıplarını da hesap etmeniz gerekir. işlemci hızınıza bağlı oarak TMR1 e her defasında 65516 yükleniz yeterli olabilir.

safaka123

teşekkürler dediğiniz gibi yaptım. doğru çalışıyor. simulatörde . gerçek devreyi denediğimde o sayıyı tekrar check ederim.