Frekans Sayici- 16F628a (Yardım)

  1. KısayolKısayol reportŞikayet pmÖzel Mesaj
    overbite
    overbite's avatar
    Kayıt Tarihi: 13/Ağustos/2011
    Erkek

    İyi geceler,

    PIC 16f628a ile bir frekans sayiciyapmaya çalışıyorum.

    1 saniye içerisinde RB6/INT pinine gelen pulsları sayacağım.

    1 saniye tutmak için TMR1 timer'ını 32.768kHZ harici osilatör ile kullanıyorum.

    Proteus 8.5 ile devreyi kurdum. RB6'ya 10000Hz'lik sinyale kadar doğru gösteriyor fakat daha yüksek frekanslarda eksik sayıyor.

    Forumlarda RB6 pininin üst limitinin 50MHz civarında olduğunu yazmışlar. (datasheet'te öyle yazıyormuş ben kendim bakmadım.)

    benim sayaç daha 20kHz'te doğru okuyamıyor.

    Acaba bu simülasyon olduğu için mi böyle?

    Kodları mikroC for PIC 6.6.2'de yazıp derliyorum.

    Bir ekran görüntüsü ve kodlar aşağıdaki gibidir;

    Frekansmetre ekran görüntüsü

    // Lcd pinout settings
    sbit LCD_RS at RA1_bit;
    sbit LCD_EN at RA0_bit;
    sbit LCD_D4 at RB5_bit;
    sbit LCD_D5 at RB4_bit;
    sbit LCD_D6 at RB3_bit;
    sbit LCD_D7 at RB2_bit;
    
    // Pin direction
    sbit LCD_RS_Direction at TRISA1_bit;
    sbit LCD_EN_Direction at TRISA0_bit;
    sbit LCD_D4_Direction at TRISB5_bit;
    sbit LCD_D5_Direction at TRISB4_bit;
    sbit LCD_D6_Direction at TRISB3_bit;
    sbit LCD_D7_Direction at TRISB2_bit;
    
    unsigned long frekans = 0;
    
    void interrupt() {
       INTF_bit = 0;
       frekans++;
    }
    
    void ayarlar() {
       CMCON = 0b00000111; //karsilastirici kapatildi
       INTE_bit = 1;
       
       //TRISA0_bit = 0;  //CIKIS LCD E pinine gider
       //TRISA1_bit = 0;  //CIKIS LCD RS pinine gider
       TRISA2_bit = 1;  //GIRIS:  S11
       TRISA3_bit = 1;  //GIRIS:  S12
       TRISA4_bit = 1;  //GIRIS:  S13
       TRISA5_bit = 1;  //GIRIS:  reset butonu girisi (MCLR)
       TRISA6_bit = 0;  //CIKIS: bosta
       TRISA7_bit = 0;  //CIKIS: bosta
    
       //TRISB = 0b10000001;  // LCD Pinlerini kendi ayarliyor
    
       TRISB0_bit = 1;  //GIRIS: Sayilacak sinyal girisi
       TRISB1_bit = 0;  //CIKIS: bosta
       //TRISB2_bit = 0;  //CIKIS: LCD D7 pinine gider
       //TRISB3_bit = 0;  //CIKIS: LCD D6 pinine gider
       //TRISB4_bit = 0;  //CIKIS: LCD D5 pinine gider
       //TRISB5_bit = 0;  //CIKIS: LCD D4 pinine gider
       
       //T1CON register'inda harici osilator secilince bu ikisine bakilmiyormus
       //TRISB6_bit = 1;  //GIRIS: 32.768 kHZ kristal girisi
       //TRISB7_bit = 0;  //CIKIS: 32.768 kHZ kristal cikisi
       
       //TMR1 ayarlari  T1CON = 0b00001110;
       T1CKPS1_bit = 0;  //TMR1 prescaler 1/1 ayarlandi
       T1CKPS0_bit = 0;
       T1OSCEN_bit = 1;  //asenkron
       T1CON.F2 = 1;
       TMR1CS_bit = 1;   //RB6'dan gelen sinyalleri sayacak
       TMR1ON_bit = 0;
    }
    
    void frekans_goster(unsigned long f) {
      char i, n, k, dijit[10];
      n = 0;
      // dijitleri ayirarak diziye yaz
      do {
        dijit[n] = '0' + f % 10;
        f /= 10;
        n++;
      } while (f > 0 && n < 10);
    
      k = 13;            // gosterilecek sembol sayisi: 10 basamaklı sayı + 3 virgul
      for(i = 0; i < 11; i++) {
        if (k == 2 || k == 6 || k == 10) {
          if (i < n)
            Lcd_Chr(1,k+3,',');    // her uc basamaktan sonra virgul koy
          else
            Lcd_Chr(1,k+3,' ');    // sayi kisa ise virgul yerine bosluk koy
          k--;
        }
        if (i < n || i == 0) {
          Lcd_Chr(1,k+3,dijit[i]); // haneyi yaz
        }
        else {
          Lcd_Chr(1,k+3,' ');      // sayi kisa ise virgul yerine bosluk koy
        }
        k--;
      }
    }
    
    void Lcd_baslat() {
       Lcd_Init();
       Lcd_Cmd(_LCD_CLEAR);
       Lcd_Cmd(_LCD_CURSOR_OFF);
       Lcd_Out(1, 1, "Frekans Sayici");
       delay_ms(500);
       Lcd_Cmd(_LCD_CLEAR);
       Lcd_Out(1, 1, "F=");
    }
    
    void main() {
       ayarlar();
       
       Lcd_baslat();
       
       while(1) {
          GIE_bit = 0;         //Genel kesmeler pasif
          TMR1ON_bit = 0;      //TMR1 kapali
          frekans = 0;         //frekans sayaci sifirlandi
          
          TMR1L = 0b00000000;  //TMR1 degerleri yuklendi
          TMR1H = 0b10000000;
    
          TMR1IF_bit = 0;      //TMR1 kesme bayragi indirildi
          INTF_bit = 0;        //RB0/INT kesme bayragi indirildi
          
          TMR1ON_bit = 1;      //TMR1 basladi
          GIE_bit = 1;         //Genel kesmeler aktif
          
          while (!TMR1IF_bit) {}   //1 sn tutuluyor
          
          GIE_bit = 0;
          TMR1ON_bit = 0;
          
          frekans_goster(frekans);
       }
    }

     

     


    ulan bir susar mısın?
  2. KısayolKısayol reportŞikayet pmÖzel Mesaj
    aercys
    aercys's avatar
    Kayıt Tarihi: 12/Nisan/2008
    Erkek

    Hocam merhabalar,

    Koda çok ayrıntılı bakamadım ancak dikkatimi çeken bir nokta var. Puls değerini arttıran fonksiyonu tanımlamışsınız. Ancak kesme vektörü şeklinde değilde interrupt() şeklinde isim vermişsiniz. PIC mimarisine hakim değilim ancak interrupt fonksiyon_adı() şeklinde yada __ISR() şeklinde ilgili vektör tanımlaması yapmanız gerekmiyor mu?

    Edit: Şimdi inceledim sizin yazdığınız gibiymiş. 

    Ek olarak iki adet intteruptınız var. Timer ve external interrupt. Global interrupt fonksiyonunuz içerisinde sadece RB6 dan gelen interrupt'ı denetleyip frekans değerini arttırmayı deneyebilirsiniz

    aercys tarafından 14/Kas/16 01:23 tarihinde düzenlenmiştir

    0x62 0x75 0x6e 0x75 0x20 0x79 0x61 0x7a 0x61 0x6e 0x20 0x74 0x6f 0x73 0x75 0x6e 0x2c 0x20 0x6f 0x6b 0x75 0x79 0x61 0x6e 0x61 0x20 0x6b 0x6f 0x73 0x75 0x6e
  3. KısayolKısayol reportŞikayet pmÖzel Mesaj
    antivir-US
    antivir-US's avatar
    Kayıt Tarihi: 04/Ocak/2006
    Erkek

    pic ile haşır neşirim ama hiç frekans sayıcı yapmadım. Öncelikle TMR1 timer'ını 32.768kHZ harici osilatör ile kullanıyorum demişsin ve RB6'ya 10000Hz'lik sinyale kadar doğru gösteriyor demişsin. TMR1 harici osc kullanıyorsan RB6 ve RB7 pinlerine 32.768 kristal bağlamış olman gerekiyor, peki buradan nasıl frekans ölçtün, ben mi yanlış anladım?

    Yanılmıyorsam en yüksek frekans ölçümü için sanırım işlemci en son saat hızında(harici XT ile 20MHz), en yüksek sayan timer, en yüksek bölme oranında capture-compare şeklinde çalıştırılması gerekiyor. Yanılıyor da olabilirim fakat nette picli çok frekansmetre örneği var.


    Camınızı kırar, duvarınıza işer, bisikletinize biner, tekerini keser, arabanızı çizer, zilinize basar kaçarım. Kısacası ben annenizin sokağa çıkarken uzak dur dediği çocuklardan biriyim.
  4. KısayolKısayol reportŞikayet pmÖzel Mesaj
    overbite
    overbite's avatar
    Kayıt Tarihi: 13/Ağustos/2011
    Erkek

    Haklısınız RB6 pininde 32.768kHz kristal var. Sayacağım sinyali RB0/INT pininden(6 nolu  bacak) giriyorum. Yanlış yazmışım.

    Yalnız benim comparator kapalı. RB0 da yüksek kenar interruptlarını sayıyorum. 1 saniyede oluşan interrupt sayısının frekansa eşit olması gerektiği mantığıyla.


    ulan bir susar mısın?
Toplam Hit: 979 Toplam Mesaj: 4
16f628a