Picproje Elektronik Sitesi

DERLEYİCİLER => CCS C => Konuyu başlatan: samedkutuk - 18 Haziran 2020, 01:31:08

Başlık: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: samedkutuk - 18 Haziran 2020, 01:31:08
Merhabalar
Öncelikle herkese iyi çalışmalar dilerim umarım herkes iyidir :)

Pıc16f877A mikrodenetleyicisi ile CCS C derleyicisini kullanarak Bir kare dalganın periyodunu bulan bir proje yapmaya çalışmaktayım.
Bunu farklı yollar ile daha önce yapmıştım fakat ödev yönergesinde izlemem gereken farklı bir yöntem belirtilmiş ve ben bu yöntemi ya doğru anlayamadım yada bir mantık hatası yapıyorum.

işlemleri şu şekilde ;
*Kare dalga sinyali RB0 pinine bağlayarak harici kesme kuruldu
*Harici kesme içerisinde 1 uS lik taşma süresine sahip timer_1 kesmesi kuruldu ve aktif edildi
*Harici kesme düşen kenar olarak ayarlandı ve düşen kenar tetikleme geldiğinde timer_1 kapatıldı
*Timer_1 kesmesindeki değişken değeri okunarak değer hesaplandı.

işlemler bu şekilde fakat yükselen kenar tetikleme bir kez okunduğunda bu kesme kenar seçimi kesme fonksiyonu içerisinde değiştirildiğinde kesme fonksiyonundan anında çıkıyor mu program nasıl oluyor kavrayamadım

Deneyimli olanlar yardımcı olabilir mi;
Kod um aşağıdaki gibidir.

#include <frekans.h>
#include <lcd.c>
#use fast_io(d)
#use fast_io(b)
#byte t1con=0x10  // t1on un adresi tanımlanıyor
#bit t1on=t1con.0//timer 1 on off biti tanımlanıyor
int16 Frekans=0;
/////////////////////////////////
#int_ext
void dis_kesme()
{
t1on=1;//timer1 i başlat
ext_int_edge(H_TO_L);// düşen kenar kesmeyi aktif et
t1on=0;// kesmeyi kapat       
ext_int_edge(L_TO_H); // yükslen kenar tetikleme aktif
lcd_gotoxy(1,1);
printf(lcd_putc,"Frekans:%Lu",Frekans);//frekansı yazdır
}
/////////////////////////////////
/////////////////////////////////
#int_timer1
void timer1_kesme(){
Frekans++;// her taşma oluştuğunda frekansı bir arttır
}
//////////////////////////////////
void main()
{
set_tris_d(0x00);
output_d(0x00);
set_tris_c(0x00);
output_c(0x00);
lcd_init();
//lcd_putc("\fSamed Kutuk");
t1on=0;
SETUP_TIMER_1(T1_INTERNAL|T1_DIV_BY_8);

ENABLE_INTERRUPTS(GLOBAL);
ENABLE_INTERRUPTS(INT_TIMER1);

enable_interrupts (int_ext);
enable_interrupts (GLOBAL);
ext_int_edge(L_TO_H);
SET_TIMER1(3035);//1us taşma için ayarlanan ön yükleme değeri
t1on=1;// timer 1 aktif
   while(TRUE)
   {
      //TODO: User Code
   }


}
referns aldığım yardımcı kaynağım
(https://i.ibb.co/yV2Fj02/image.png) (https://ibb.co/yV2Fj02)
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: RaMu - 18 Haziran 2020, 01:56:42
Harici kesme içerisinde bir bayrağın olacak,
eğer harici kesme yükselen kenar ile gelmişse,
timer başlatıp,
harici kesmeyi düşen kenara ayarlayıp,
kesme düşen kenara ayarlı diye bayrağı kurup
kesmeden çıkacaksın.
Kesmeye bir daha geldiğinde baktınki
kesme düşen kenar ile gelmiş
bu sefer
kesmeyi yükselen kenara ayarlayıp
kesme yükselen kenara ayarlı diye bayrak kurup,
timer ı durdurup
timer daki değeri alacak kaydedeceksin ve
periyod değeri hazır diye bayrak set edecek,
kesmeden çıkacaksın.
Mainde periyod değeri hazır değişkenini sürekli kontrol edip
değer hazırsa işleyip ekranda felan göstereceksin ve
periyod hazır değişkenini sıfırlayacaksın.

Daha az bayrakla uğraşmak için
kesme hem düşen hem yükselen kenarda gelsin
şeklinde kesme kurabilirsen (senin mcu da bu özellik var mı hatırlamıyorum) kurup,
yükselen kenarda farklı bir kesme
düşen kenarda farklı bir kesme alabilir ve
kodlarını bu iki ayrı kesme noktasına yazabilirsin.
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: samedkutuk - 18 Haziran 2020, 02:02:54
Alıntı yapılan: RaMu - 18 Haziran 2020, 01:56:42Harici kesme içerisinde bir bayrağın olacak,
eğer harici kesme yükselen kenar ile gelmişse,
timer başlatıp,
harici kesmeyi düşen kenara ayarlayıp,
kesme düşen kenara ayarlı diye bayrağı kurup
kesmeden çıkacaksın.
Kesmeye bir daha geldiğinde baktınki
kesme düşen kenar ile gelmiş
bu sefer
kesmeyi yükselen kenara ayarlayıp
kesme yükselen kenara ayarlı diye bayrak kurup,
timer ı durdurup
timer daki değeri alacak kaydedeceksin ve
periyod değeri hazır diye bayrak set edecek,
kesmeden çıkacaksın.
Mainde periyod değeri hazır değişkenini sürekli kontrol edip
değer hazırsa işleyip ekranda felan göstereceksin ve
periyod hazır değişkenini sıfırlayacaksın.

Daha az bayrakla uğraşmak için
kesme hem düşen hem yükselen kenarda gelsin
şeklinde kesme kurabilirsen (senin mcu da bu özellik var mı hatırlamıyorum) kurup,
yükselen kenarda farklı bir kesme
düşen kenarda farklı bir kesme alabilir ve
kodlarını bu iki ayrı kesme noktasına yazabilirsin.


Öncelikle yanıtınız için teşekkür ederim

Fakat ikinci olarka geldiğini nasıl algılayıp farklı bir işlem yaptıracağım sonuçta bir çok kez aynı kesme alt programına giriyor programım algoritma konusunda yardımcı olabilir misiniz?
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: RaMu - 18 Haziran 2020, 02:28:10
Alıntı yapılan: samedkutuk - 18 Haziran 2020, 02:02:54Öncelikle yanıtınız için teşekkür ederim

Fakat ikinci olarka geldiğini nasıl algılayıp farklı bir işlem yaptıracağım sonuçta bir çok kez aynı kesme alt programına giriyor programım algoritma konusunda yardımcı olabilir misiniz?


Yazdıklarımı bir kağıda akış diyagramı olarak çizersen daha net görebilirsin.
Alıntı yapılan: RaMu - 18 Haziran 2020, 01:56:42Harici kesme içerisinde bir bayrağın olacak,
...
kesme düşen kenara ayarlı diye bayrağı kurup
kesmeden çıkacaksın.
...


Kod örneği bile varmış forumda:
https://www.picproje.org/index.php?topic=56431.0
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: samedkutuk - 18 Haziran 2020, 02:31:46
Alıntı yapılan: RaMu - 18 Haziran 2020, 02:28:10Yazdıklarımı bir kağıda akış diyagramı olarak çizersen daha net görebilirsin.

Dediklerinizden şöyle bir sonuç çıkardım hocam

/////////////////////////////////
#int_ext
void dis_kesme()
{
durum++;
if(durum==1){
t1on=0;
SET_TIMER1(3035);
t1on=1;//timer1 i başlat
ext_int_edge(H_TO_L);// düşen kenar kesmeyi aktif et
break;
}

if(durum==2){
t1on=0;// kesmeyi kapat   
ext_int_edge(L_TO_H); // yükslen kenar tetikleme aktif
durum=0;
}

}


Bu şekilde yapınca da bir sonuç alamadım
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: RaMu - 18 Haziran 2020, 03:40:33
Yaklaşmışsın, biraz daha uğraşsan olacak gibi.
Timer çalışıyor mu, son değeri doğrumu,
son değeri düşen kenarda kaydettim mi,
timer başlatırken sıfırlamam gereken değişkenlerim var mı
gibi kısımlarada dikkat et.
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: yas - 18 Haziran 2020, 11:49:04
Kesme yükselen yada düşen kenarda olacak diye uğraşmak istemezsen kesme için portb nin son 4 bitindeki değişikliği takip eden kesmeyi de kullanabilirsin. Pin lojik seviyesi her değiştiğinde kesme gelecektir. Kesme geldiğinde timer kapalı ise timer başlar, kesme tekrar geldiğinde timer açıksa kapatılıp değeri işlenir.
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: samedkutuk - 18 Haziran 2020, 13:10:50
Alıntı yapılan: RaMu - 18 Haziran 2020, 03:40:33Yaklaşmışsın, biraz daha uğraşsan olacak gibi.
Timer çalışıyor mu, son değeri doğrumu,
son değeri düşen kenarda kaydettim mi,
timer başlatırken sıfırlamam gereken değişkenlerim var mı
gibi kısımlarada dikkat et.
Sanırım timer içerisinde hiç değeri artıramıyorum yani kesme meydana gelmiyor timer kesmesi sebebi ne olabilir
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: samedkutuk - 18 Haziran 2020, 13:11:54
Alıntı yapılan: yas - 18 Haziran 2020, 11:49:04Kesme yükselen yada düşen kenarda olacak diye uğraşmak istemezsen kesme için portb nin son 4 bitindeki değişikliği takip eden kesmeyi de kullanabilirsin. Pin lojik seviyesi her değiştiğinde kesme gelecektir. Kesme geldiğinde timer kapalı ise timer başlar, kesme tekrar geldiğinde timer açıksa kapatılıp değeri işlenir.
Hocam malesef ödevim bu şekilde harici kesme ve timer ile yapmam gerekiyor
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: sadogan - 18 Haziran 2020, 13:20:55
Bahsi geçen yönerge nedir ?
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: samedkutuk - 18 Haziran 2020, 13:39:45
@sadogan
@RaMu
aşağıdaki resim izlememe gereken yönerge
harici kesmenin yükselen kenarını algılayıp timeri başlatıp alçalan kenar geldiğinde timeri kapatarak periyodunu bbulmam isteniyor.
ve aslında kısmen de yaptım

(https://i.ibb.co/Cb9WQ7k/image.png) (https://ibb.co/Cb9WQ7k)

aşağıda vermiş olduğum osiloskop görüntüsünde sarı kaynak bir kare dalga kaynağından aldığım yükselen kenar tetiklemede c0 pinini high yapıp düşen kenar tetikleme de ise low yaparak aslında yükselen kenar tetiklemeyi ve düren kenar tetiklemeyi yakalayabildiğimi anlamış oldum
fakat sorunum şuan timerin şuan neden çalışmadığı
bu süreyi ölçemiyorum şuan
(https://i.ibb.co/344wZMW/Ekran-Al-nt-s.png) (https://ibb.co/344wZMW)
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: sadogan - 18 Haziran 2020, 14:58:58
Tmr1 için clock seçmen ve ön bölücüyü ayarlaman gerek

Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: 10f200.h - 18 Haziran 2020, 15:05:21
Kesme içerisinde timer1 e tekrar 3035 değerini yüklemen gerekir.
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: samedkutuk - 18 Haziran 2020, 15:28:37
Alıntı yapılan: sadogan - 18 Haziran 2020, 14:58:58Tmr1 için clock seçmen ve ön bölücüyü ayarlaman gerek



ön bölmeyi ve kaynak seçimini yükledim hocam
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: samedkutuk - 18 Haziran 2020, 15:30:09
Alıntı yapılan: 10f200.h - 18 Haziran 2020, 15:05:21Kesme içerisinde timer1 e tekrar 3035 değerini yüklemen gerekir.

Nasıl yani kesme fonksiyonu içerisinde ;
#int_timer1
void timer1_kesme(){
set_timer1(65535);
output_toggle(pin_c3);
Frekans++;// her taşma oluştuğunda frekansı bir arttır
}

bu şekilde mi yapmam gerekiyor
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: yas - 18 Haziran 2020, 15:38:06
Sanki yanlış bir kurgu var gibi.
-İstenen şey INT0 ile kesme geldikten sonra sürekli yada bir defa çalışacak timer kesmesi mi kurmak.
-Yoksa INT0 ile kesme geldiğinde timer içeriğini okuyup (işleyip) çıktı olarak almak mı?

-Eğer birinci ise her INT0 kesmesinde timer kurulmalı (bölücü oranı, clock kaynağı, 8/16 bit modu ve timer set değeri). Daha sonraki bütün timer kesmelerinde bayrak temizlenmeli.
-Eğer ikinci ise her INT0 kesmesinde timer okunduktan sonra timer içeriği sıfırlanmalı.

Yapılmak istenilen frekans sayıcı gibi bir şeyse. Bence gidiş yolu farklı olmalı. INT0 kesmesi hiç olmamalı. Onun yerine iki tane timer kesmesi olmalı ve birincisi okuma periyotu için kesme üretmeli diğeri ise harici kaynaktan clock alan okumada kullanılan timer da hata yada taşma olduğunda bölücü oranını değiştirmeli.
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: 10f200.h - 18 Haziran 2020, 16:07:13
Alıntı yapılan: samedkutuk - 18 Haziran 2020, 15:30:09Nasıl yani kesme fonksiyonu içerisinde ;
#int_timer1
void timer1_kesme(){
set_timer1(65535);
output_toggle(pin_c3);
Frekans++;// her taşma oluştuğunda frekansı bir arttır
}

bu şekilde mi yapmam gerekiyor
Evet aynen bu şekilde. Eğer bunu eklemezsen  kesme oluştuğunda timer 3035 ten 65535 e kadar saymaya devam eder.
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: samedkutuk - 19 Haziran 2020, 13:10:32
Alıntı yapılan: 10f200.h - 18 Haziran 2020, 16:07:13Evet aynen bu şekilde. Eğer bunu eklemezsen  kesme oluştuğunda timer 3035 ten 65535 e kadar saymaya devam eder.

Peki bunu harici kesmenin içine de eklemem gerekir mi
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: 10f200.h - 19 Haziran 2020, 16:01:42
Hayır gerekmez.
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: samedkutuk - 20 Haziran 2020, 01:08:32
Alıntı yapılan: 10f200.h - 19 Haziran 2020, 16:01:42Hayır gerekmez.
Teşekkür ederim
Başlık: Ynt: Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma
Gönderen: aliveli - 20 Haziran 2020, 02:04:22
#include <16f877.h>     
#fuses XT,NOWDT,NOLVP
#use delay (clock=4000000) 
#include "lcd.c"   
void main ( )

   int16 zaman=0;
   ext_int_edge(L_TO_H);
   setup_timer_1 ( T1_INTERNAL | T1_DIV_BY_1 );
   lcd_init();   
   printf(lcd_putc,"\f Baslama");
   delay_ms(100);
   while(1) {
      while (!interrupt_active(INT_EXT));
      clear_interrupt(INT_EXT);
      set_timer1(0);
      ext_int_edge(H_TO_L);
      while (!interrupt_active(INT_EXT));
      zaman=get_timer1();
      printf(lcd_putc,"\fZaman=%Lu us",zaman);
      delay_ms(100);
      clear_interrupt(INT_EXT);
      ext_int_edge(L_TO_H);

   }}