Timer_1 ve Harici kesme kullanarak bir kare dalganın periyodunu bulma

Başlatan samedkutuk, 18 Haziran 2020, 01:31:08

samedkutuk

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

samedkutuk

RaMu

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.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

samedkutuk

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?
samedkutuk

RaMu

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
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

samedkutuk

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
samedkutuk

RaMu

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.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

yas

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.

samedkutuk

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
samedkutuk

samedkutuk

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
samedkutuk

sadogan


samedkutuk

@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



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

samedkutuk

sadogan

Tmr1 için clock seçmen ve ön bölücüyü ayarlaman gerek


10f200.h

Kesme içerisinde timer1 e tekrar 3035 değerini yüklemen gerekir.

samedkutuk

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
samedkutuk

samedkutuk

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
samedkutuk