Not 24: CCP Birimi 2 – Capture (Yakalama).

Yayınlandı: 27 Ocak 2014 / Microchip PIC Programlama...
Etiketler:, , , , , , , , , , ,

Adsız  PIC  mikrodenetleyicilerin çoğunda bulunan CCP biriminin 3 görevi bulunmaktadır. Bunlar Capture/Compare/PWM görevleridir. PWM konusunu daha önce incelemiştik. Şimdi Capture üzerinde duracağız. Capture birimi girişten (PIC16f628a’da RB3) gelen sinyaller arasındaki süreyi ölçmemizi sağlar. RB3 pininden gelen sinyalin her düşen kenarında, her yükselen kenarında, her 4 yükselen kenarında veya her 16 yükselen kenarında bir kesme oluşturur.  Kesmenin hangi aralıkta oluşacağına biz karar veririz.  Yani aslında dışarıdan gelen sinyalleri yakalamış ve aralarında geçen süreyi ölçmüş oluruz. Capture pek çok yerde kullanılabilir ve çok yararlı bir özelliktir. PIC16F628A mikrodenetleyicisinin kataloğunda bulunan blog diyagramı inceleyelim.Adsız

Blok diyagrama dikkat edilirse RB3 pininden hemen sonra prescaler (ön bölücü) birimi bulunmaktadır. Burada kaç sinyalde bir kesme oluşturulacağı belirlenir. Daha sonra edge select kısmında sinyalin yükselen kenarında veya düşen kenarında algılama yapılacağı belirlenir.  4 veya 16 sinyalde bir algılama yapılacaksa sadece yükselen kenarda algılama yapılabilir. Daha sonraki kısımda ise kesme oluştuğunda Timer1 registerının içeriğinin CCP registerı içerisine aktarılması görülmektedir. Yani kesme oluştuğunda CCP1IF bayrağı 1 olur ve  16bitlik Timer1(TMR1H:TMR1L registerları) sayacının içeriği 16bitlik CCPR1H(yüksek değerli 8 bit) – CCPR1L (düşük değerli 8 bit) içerisine aktarılır.

Biz bu uygulamada capture özelliğini kullanarak basit bir frekansmetre yapacağız. Bu frekansmetre ile ölçtüğümüz değerleri uart üzerinden göndereceğiz.  Bunun için ilk olarak Timer1 birimini  ayarlamamız gerekli. Timer1’i her 1 us’de 1 artacak şekilde zamanlayıcı moda alıyoruz. Capture birimini kullanmak için timer 1 ya senkron sayıcı ya da zamanlayıcı olarak ayarlanmalı. Daha sonra CCP birimi ile ilgili ayarlamalar yapılıyor. CCP biriminin kontrol registerı aşağıdaki gibidir:

Adsız

Şimdi kodlarımıza göz atalım:


char txt[7];
unsigned capish=0,freq;
void main() {
T1CON.T1CKPS1=0; // Timer1 prescaler değeri 1:1 olarak ayarlandı.
T1CON.T1CKPS0=0; //
T1CON.T1OSCEN=0; // Timer1 harici osilatör pasif edildi.
T1CON.TMR1CS=0;  // Dahili saat kaynağı seçildi.
CCP1CON.CCP1M3=0; // Capture Her yükselen kenarda kesme oluşturacak.
CCP1CON.CCP1M2=1;
CCP1CON.CCP1M1=0;
CCP1CON.CCP1M0=1;
INTCON.PEIE=1; // Çevresel kesmelere izin verildi.
INTCON.GIE=1; // Bütün kesmelere izin verildi.
TRISB.B3=1; //Capture için RB3 giriş yapıldıç
TMR1H=0; //16 bitlik Timer1 sayaç registeri temizlendi.
TMR1L=0;
UART1_Init(9600); //Uart iletişim kuruldu. (9600 bits per second)
PIE1.CCP1IE=1; // Capture kesmesine izin verildi.
PIR1.CCP1IF=0; // Kesme bayrağı temizlendi.
T1CON.TMR1ON=1; //timer1 çalışmaya başladı.
while(1)
{
delay_ms(100);
freq=1000000/capish; //Frekans Hz cinsinden hesaplanıyor.
inttostr(freq,txt); //Hesaplanan frekans 100ms'de bir uart üzerinden gönderilecek.
UART1_Write_Text(txt);
UART1_Write_Text(" Hz");
UART1_Write_Text("\r\n");
capish=0;
}
}

void Capture_Kesmesi() iv 0x0004 ics ICS_AUTO {//kesme altprogramı
PIR1.CCP1IF=0;   // kesme bayrağı sıfırlanıyor.
TMR1H=0;TMR1L=0; // timer1 saya. registerı temizleniyor.
capish=(CCPR1H<<8)+CCPR1L; // CCPR1H ve CCPR1L registerları birleştirilerek capish isimli değişkene kaydediliyor.
}

Kodlarımızı inceledikten sonra devre şemamıza da bir göz atalım;

Adsız

Resmi büyük görmek için tıklayın…

Devrede 1KHz değerinde bir sinyal RB3 pinine girilmiştir. Görüldüğü üzere Uart terminalden PIC mikrodenetleyici 1015Hz olarak veri göndermektedir. 15Hz’lik fark simülasyondan kaynaklanmaktadır.

Bu notla alakalı tüm dosyalara buradan  ulaşabilirsiniz.

İyi çalışmalar.

yorum
  1. Onur dedi ki:

    Hocam, şu kısmı biraz açarmısınız ?
    void Capture_Kesmesi() iv 0x0004 ics ICS_AUTO {//kesme altprogramı
    nedir bu iv 0x0004 ics ICS_AUTO değerlerinin anlamları ?

    • mikrodunya dedi ki:

      0x0004 program belleğindeki kesme vektörünün adresidir. ICS Auto ise Context saving yani o anki program kaydedicisinin, status registerının içeriği vb. gibi bilgilerin kesme altprogramına dallanmadan önce kaydedilmesinin otomatik yapılacağı anlamına gelir.
      Bunu kısaca "void interrupt()" yazarak da halledebilirdik, fakat farklı bir kullanışını da göstermek istedim kesme altprogramının.

  2. ma dedi ki:

    dosyaları indiremedim link çalışmıyor galiba

  3. da dedi ki:

    linkte problem var galiba

  4. Hakan NET dedi ki:

    Selam,
    18F46K22 (16mhz X 4=64 mhz PLL çalışıyor) ile yaptığım bir projede 5khz-300khz arasında frekans ölçmem gerekiyor, fakat bu şekilde 65535’den sonra ölçüm yapamıyorum. Girişe frekans bölücü mü koymalıyım, yoksa başka bir yöntemle ölçebilir miyim_?

    Frekansı saniyede 10 kezden fazla ölçmem gerektiğinden bu yöntem hızlı işliyor, fakat 16 bit sınırında kaldım. Aynı şekilde TMR1’i kullandım, TMR0 ile daha faklı bir kullanım da yapabilir miyim_?

Bir Cevap Yazın

Aşağıya bilgilerinizi girin veya oturum açmak için bir simgeye tıklayın:

WordPress.com Logosu

WordPress.com hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Twitter resmi

Twitter hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Facebook fotoğrafı

Facebook hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Google+ fotoğrafı

Google+ hesabınızı kullanarak yorum yapıyorsunuz. Çıkış  Yap / Değiştir )

Connecting to %s