Genel

CCS C’DE PIC16F877A İLE FREKANSMETRE

#include <16f877A.h>    
#include<stdbool.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD 
#use delay (clock=4MHz)
#include <lcd.c>

İlk olarak Kullandığımız denetleyicinin kütüphanesini 16f877A.h ekledik. bolean ifadeleri kullanacağımız için

stdbool kütüphanesini ekledik. FUSES ayarlarımızı yaptık. Kullanacağımız harici osilatörün frekansı 4MHz olacaktır. lcd.c kütüphanesini ekledik. Burada önemli bir noktaya dikkat çekmek istiyorum. #use delay(clock=4MHz) her zaman lcd.cden önce kullanılmalıdır.

unsigned int32 f = 0;   
unsigned int16 count1=0;
volatile int8 i=0;

frekans değerini tutacak olan f değişkenini unsigned int32 veri tipinde tanımladım. TİMER0 interrupt sayısını

count1 değişkenini tutar. Timer1 kesmesi sayısını i değişkeni tutar. Bu değişkenin değeri çok hızlı kontrol edileceği ve bir interrupt içinde değer değişimi olacağı için, değişkenin derleyicinin yapılandırmasından olumsuz etkinmemesi amacıyla volatile olarak tanımlandı.

void _1snbekle(void);
#INT_TIMER0
void  Timer0_kesme() 
{
   count1++;
}
#INT_TIMER1
void  Timer1_kesme() 
{ 
   set_timer1(40536);
  i=i+1;
}

Yukarıda timer0 ve Timer1 interrupt fonksiyonları tanımlandı. Timer sıfır kesmesi her meydana geldiğinde count1 değişkeni bir arttırılır. Bu programda timer sıfır değişkeni sayıcı olarak kullanılmıştır ve frekansı sayılan sinyal bu girişten almaktadır. Timer0 kaydedicileri 8 bittir ve maksimum 256 değerine kadar sayar ve ardından interrupt verip sıfıra döner . Örneğin bir saniye içinde sinyal kaynağından TIMER0 girişine 270 sinyal darbesi gelmiş olsun ve frekans sayımı için sadece TIMER0 kaydedicilerinden okuma yapılsın. Bu durumda 1 saniyenin sonunda okunan frekans değeri 14 olur. Çünkü TIMER0 kaydedicisi 256. darbeden interrupta girmiş olur ve sıfırdan tekrar saymaya başlar. count1 değişkeni ile kaç defa interrupt oluştuğu dolaysıyla frekans sayısına kaç tane 256 ekleneceği bulunur. Timer1_kesme fonksiyonu TIMER1 interruptı meydana geldiğinde oluşur. set_timer1(40536) komutu ile Timer1’e 65536’ya 40536’dan saymaya başlanacağı söylenir. Böylece 25000 cycle boyunca timer1 sayma yapar. i değişkeni 1 arttırılır.

void main()
{
   setup_psp(PSP_DISABLED);
   setup_timer_2(T2_DISABLED,0,1); 
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_ccp1(CCP_OFF);
   setup_ccp2(CCP_OFF);
   lcd_init();
   
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_8 );
   setup_timer_0(T0_EXT_H_TO_L | RTCC_DIV_1);
   enable_interrupts(INT_TIMER0); 
   enable_interrupts(INT_TIMER1);
  

Yukarıda ilk olarak main fonksiyonu tanılanır. lcd_init fonksiyonu lcd başlatılır. setup_timer_1(T1_INTERNAL | T1_DIV_BY_8 ); komutun ile timer1’in mikro denetleyicinin komut clock sinyalini kullanacağını belirtiyoruz. Mikrodenetleyicimiz 4MHz clock sinyalini girişine almaktadır. Bu clock sinyali işlemcinin komut clokuna gitmeden önce 4’e bölünür. Komut clock frekansımız 1Mhz’dir. T1_DIV_BY_8 ile komut clock frekansı 8’e bölünerek timer1 için 125KHz’lik bir clock sinyali elde ederiz. TIMER1 8 bitlik iki kaydedicisinde tuttuğu 16 bitlik sayaç değerini her clock darbesinde 1 arttırır.

setup_timer_0(T0_EXT_H_TO_L | RTCC_DIV_1); komutu ile TIMER0’in harici bir clock kaynağını ve bu clock sinyalinin 1’e bölüneceğini belirttik. Frekansını ölçmek istediğimiz sinyali RA4/T0CKI pinine bağlarız.

Ardından TIMER0 ve TIMER1 interruptları çalışmaya hazır hale getirilir. Ama henüz çalıştırılmadılar.

   while(TRUE)
   {      
      f = 0;
      count1 = 0;
      clear_interrupt(INT_TIMER0);
      clear_interrupt(INT_TIMER1);  
      _1snbekle();    
      f= get_timer0();      
      f =f+count1 * 256;
      printf(lcd_putc,"\fFREKANS %luHZ",f);  
      delay_ms(1000);
   }
}

Sonsuz while döngüsüne girilir. Frekans değerini tutacak f değişkenine 0 atanıyor. count1 değişkenine 0 atanıyor. Meydana gelmiş olan TIMER1 ve TIMER0 interruptları temizleniyor. _1snbekle fonksiyonu içine girilir. Bu fonksiyonda ilk olarak hazır hale getirilen interruptlar enable_interrupts(GLOBAL); çalıştırılırlar. set_timer1(40536); komutu ile timer 1’in 40536’dan itibaren 65536’ya kadar her 1/125000 saniyede bir sayacını bir arttırmasını ifade ediyoruz . Bu durumda her 0.2 saniyede bir timer1 interruptı üretilir. set_timer0(0); komutu sinyal sayımına sıfırdan başlanacağını ifade ediyor. while(i<5); komutu ile i değişkeni 5’ten küçük olduğu sürece bekleme yapılmasını ifade ediyor. i değişkeni timer1 interrupt fonksiyonu içinde 1 arttırılır. i ‘nin 5 defa artması için 5 defa timer1 kesmesi oluşması gerekiyor. Bu durumda 0.2*5 =1 sn bekleme yapılır. i=5 olunca while döngüsünden çıkılır. i değişkenine sıfır atanır. disable_interrupts(GLOBAL); ile timerlar durdurulur. f= get_timer0(); ile timer0 kaydedicisindeki sayac değeri alınır. f değişkenine count1 değişkeninin tuttuğu değer kadar 256 eklenir. Çünkü count1 timer0’in kaç defa 0’dan 256’ya kadar saydığını belirtir. TIMER0 256 olunca TIMER0 interruptı oluşur ve tekrar saymaya sıfırdan başlar. frekans değeri Hertz olarak lcd ekranına yazdırılır. 1 saniye beklenir.

void _1snbekle(void)
{
   enable_interrupts(GLOBAL);      
   set_timer1(40536);
   set_timer0(0);
   while(i<5);
   i=0;
   disable_interrupts(GLOBAL);
}
#include <16f877A.h>    
#include<stdbool.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD 
#use delay (clock=4MHz)
#include <lcd.c>
unsigned int32 f = 0;   
unsigned int16 count1=0;
volatile int8 i=0;
void _1snbekle(void);
#INT_TIMER0
void  Timer0_kesme() 
{
   count1++;
}
#INT_TIMER1
void  Timer1_kesme() 
{ 
   set_timer1(40536);
  i=i+1;
}
void main()
{
   setup_psp(PSP_DISABLED);
   setup_timer_2(T2_DISABLED,0,1); 
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_ccp1(CCP_OFF);
   setup_ccp2(CCP_OFF);
   lcd_init();
   
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_8 );
   setup_timer_0(T0_EXT_H_TO_L | RTCC_DIV_1);
   enable_interrupts(INT_TIMER0); 
   enable_interrupts(INT_TIMER1);
  
   while(TRUE)
   {      
      f = 0;
      count1 = 0;
      clear_interrupt(INT_TIMER0);
      clear_interrupt(INT_TIMER1);  
      _1snbekle();    
      f= get_timer0();      
      f =f+count1 * 256;
      printf(lcd_putc,"\fFREKANS %luHz",f);  
      delay_ms(1000);
   }
}
void _1snbekle(void)
{
   enable_interrupts(GLOBAL);      
   set_timer1(40536);
   set_timer0(0);
   while(i<5);
   i=0;
   disable_interrupts(GLOBAL);
}

c dosyasını ve proteus dosyasını buradan indirebilirsiniz:

https://github.com/Fatihalparslan/FREQUENCYMETER-WITH-CCS-C-FOR-PIC16F877A

her türlü danışmanlık için : e-mail:fatih22alparslan@gmail.com

özel ders: https://www.ozelders.com/ders-veren/fatih-a-403441

Ücreti karşılığında Freelance iş yapmak isterseniz: Whatsapptan iletişime geçin.

Ücret karşılığı proje için whatsapp:

https://wa.me/message/4DTQQTTMLPFWC1

CCS C’DE PIC16F877A İLE FREKANSMETRE&rdquo için 1 yorum

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 )

Google fotoğrafı

Google 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 )

Connecting to %s

%d blogcu bunu beğendi: