Merhaba arkadaşlar;
DS1302 kullandığımda iki çeşit kesmeyi çalıştıramıyorum.
DS1302 RTC yardımı ile lcd'yi de kullanarak her sabah saat sekizde b1 ledini aktive eden bir program yaptım ve bu ledi dış kesme yardımı ile iki saniye boyunca söndürüp aynı zamanda b2 ledini iki saniye boyunca yaktım. Kesme komutum aşağıdaki gibi.
void ext_kesmesi()
{
output_low(pin_b2);
output_high(pin_b1);
delay_ms(2000);
output_low(pin_b1);
output_high(pin_b2);
}
saat sekizde b2 led'ini yaktığım kodu da aşağıdaki gibi yazım.
void main()
{
lcd_init();
rtc_init();
rtc_set_datetime(29,03,14,7,8,00);
while(1)
{
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_1(T1_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);
rtc_get_time(saat,dakika,saniye);
rtc_get_date(gun,ay,yil,haftanin_gunu);
printf(lcd_putc,"\fTARIH:%02d/%02d/20%02d ",gun,ay,yil);
printf(lcd_putc,"\n >S:%02d:%02d:%02d",saat,dakika,saniye);
switch(haftanin_gunu)
{
case 1: printf(lcd_putc,"\nPAZ"); break;
case 2: printf(lcd_putc,"\nPZT"); break;
case 3: printf(lcd_putc,"\nSAL"); break;
case 4: printf(lcd_putc,"\nCRS"); break;
case 5: printf(lcd_putc,"\nPER"); break;
case 6: printf(lcd_putc,"\nCUM"); break;
case 7: printf(lcd_putc,"\nCTS"); break;
}
delay_ms(1000);
if(saat==8&&dakika==00&&saniye==00)
{
set_tris_b(0b00000001);
output[b]_b(0x00);
output_high(pin_b2);
ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
}
Buradaki ilk sorum kesme bittikten sonra sistem ana programa dönüp b2 ledini yakmıyor bu yüzden kesme programının sonunda ana programdaki b2 ledini tekrar yak demek zorunda kalıyorum. Bu sorunu nasıl giderebilirim? Kesme bittikten sonra ana programa nasıl dönebilirim?
ikinci sorum;
5 kesme oluştuktan sonra kesmeleri iptal et ve b4 pininde bulunan ledi yak demek istiyorum fakat bunu timer1 ile yapmaya çalıştığımda program timer 1 kesmesini aktive etmedi.
Nasıl bir timer kullanmalıyım? Ya da 5 dış kesmeyi sayabileceğim bir yol var mıdır?
Kullandığım yöntem aşağıdaki gibi fakat işe yaramadı.
#int_timer1
void timer1_kesme()
{
set_timer1(65531);
kesme++;
output_high(pin_b4);
}
{set_tris_c(0x01);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
set_timer1(65531);
ext_int_edge(H_TO_L);
enable_interrupts(INT_timer1);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);}
}
Yardımcı olabilirseniz çok sevinirim. Yardımlarınız için şimdiden çok teşekkürler.
kesmeleri o kadar meşgul etmek yerine bayrak kullan. Kesme geldiğinde bayrağını 1 yaparsın ana program çevriminde bu bayrağın 1 olup olmadığını kontrol edersin ve sonrada bayrağı 0 yaparsın. Bu arada bu bayrak dış kesme için ise istediğin gibi de atadığın bir sayacını saydırırsın.
Yardımcı olduğunuz için çok teşekkür ederim. Özür dileyerek söylemeliyim ki bu işte yeniyim ve bayrak daha önceki prijelerimde kullanmadım. Rica etsem bayrak kullanımıyla ilgili bir örnek veya bayrak kullanımına ait bir döküman önerme şansınız olabilir mi?
Değişken tanımlamayı biliyorsun.
diyelim ki (değişken) bayrağımızın adı dis_kesme
ilk değeri de
dis_kesme=0;
olsun
void ext_kesmesi()
{
dis_kesme=1;
}
ana program döngüsünün içinde;
if (dis_kesme==1)
{
// kesme ile ne yacaksan..
dis_kesme=0;
}
Tavsiyeniz için tekrar çok teşekkürler. Söylediğiniz gibi yaptım ve dış kesmem çalışıyor. Tek sorunum kaldı o da dış kesmeyi saydırmayı başaramamam.
5 kesme meydana gelince kesmeleri iptal edip diğer ledleri söndürüp sadece b4 pinine bağlı ledi yakmak istiyorum, fakat ilk kesme meydana geldiğinde b4 pini yanıyor, diğer ledler sönüyor ve kesmeler devre dışı kalıyor bu yüzden 5 kesme saydıramıyorum sanırım. Aşağıdaki gibi yazdım fakat belirttiğim gibi çalışmadı. Bu sorunu nasıl aşabileceğim ve 5 kesmeyi nasıl saydırabileceğim konusunda bir tavsiyeniz olabilir mi?
Teşekkürler.
if(dis_kesme==1)
{
dis_kesme=dis_kesme++;
if(dis_kesme==5)
disable_interrupts(INT_EXT);
disable_interrupts(GLOBAL);
output_low(pin_b2);
output_low(pin_b1);
output_high(pin_b4);
{
dis_kesme=0;
}}
Parantezlere dikkat edin:
void ext_kesmesi()
{
dis_kesme++;
}
if( dis_kesme == 5 )
{
disable_interrupts( INT_EXT );
disable_interrupts( GLOBAL );
output_low( pin_b2 );
output_low( pin_b1 );
output_high( pin_b4 );
dis_kesme = 0;
}
@mechanicalengine
Dikkat et. Burada biz "dis_kesme" bayrak olarak kullandık. Sayaç olarak değil. Eğer sayaç istiyorsan kendine "dis_kesme_say" gibi bir değişken oluşturmalısın.
Hatta programda karışıklık olmasını istemiyorsan, bayrak olarak kullandığın değişkeni örneğin
"dis_kesme_bay" şeklinde kullanabilirsin.
Değişkenlerini birbirine karıştırırsan programında içinden çıkılamayacak şekilde karışır...
Tavsiyeleriniz için tekrar teşekkür ederim, dünden beri uğraşıyorum fakat kesmeleri saydırmayı bir türlü başaramıyorum.
yaptıklarımı aşağıda açıklamaya çalıştım;
önce;
int dis_kesme=0;
int dis_kesme_say=0;
şeklinde iki değişken tanımladım. Daha sonra bu değişkenleri kesme programının içerisinde belirttim.
void ext_kesmesi()
{
dis_kesme=1;
dis_kesme_say++;
}
ana program içerisinde
if(dis_kesme==1)
{
output_low(pin_b2);
output_high(pin_b1);
delay_ms(2000);
output_low(pin_b1);
output_high(pin_b2);
dis_kesme=0;
}
if(dis_kesme_say==5);
{
disable_interrupts( INT_EXT );
disable_interrupts( GLOBAL );
output_low( pin_b2 );
output_low( pin_b1 );
output_high( pin_b3 );
dis_kesme = 0;
}
şeklinde belirttim. Program if(dis_kesme==5) koşulunu dikkate almadan direk sonuca gidip kesmeleri iptal edip sadece b3 pinini yakarak çalışmaya başlıyor.
if(dis_kesme_say==5) kısmını silersem programda kesmeler çalışıyor fakat bu kısmı eklediğimde program direk b3 pinini yakarak çalışmaya başlıyor ve kesmeler iptal oluyor, if komutları dikkate alınmıyor. Program if koşulunu bir şekilde atlayıp direk sadece komut içerisindeki b3 pinini yakarak çalışmaya başlıyor. Bir yerde mantık hatası mı yapıyorum anlayamadım.
Kesmeleri saydırma ve if koşullarını nasıl hesaba kattırabileceğim konusunda yardımcı olabilirseniz çok sevinirim.
Şimdiden teşekkürler.
void ext_kesmesi()
{
dis_kesme=1;
}
if(dis_kesme==1)
{
output_low(pin_b2);
output_high(pin_b1);
delay_ms(2000); //>>olay burada
output_low(pin_b1);
output_high(pin_b2);
dis_kesme=0;
dis_kesme_say++;
}
if(dis_kesme_say==5);
{
disable_interrupts( INT_EXT );
disable_interrupts( GLOBAL );
output_low( pin_b2 );
output_low( pin_b1 );
output_high( pin_b3 );
dis_kesme_say = 0;
}
senin yaptığın gibi yaparsan kesme delay_ms(2000); //>>olay burada satırında iken
gelirse 2 kere sayar ve dis_kesme_say senin ölçüm sınırın dışına çıkar....
onun için yukarıdaki gibi yapabilirsin... Dışarıdan gelen kesme 1 saniye ise o delay yerine kod üzerinde bir düzenleme ile de işlemi yapabilirsin. Sadece biraz uğraştırır o kadar.
örneğin diyelim ki yak_son_say diye bir sayaç açtık
yak_son_say=0; ilk değeri
if(dis_kesme==1)
{
dis_kesme=0;
dis_kesme_say++;
yak_son_say++;
if (yak_son_say==1)
{
output_low(pin_b2);
output_high(pin_b1);
}
if (yak_son_say==3)
{
output_low(pin_b1);
output_high(pin_b2);
yak_son_say=0;
}
}
Merhaba;
Sanıyorum bir anlaşmazlık var, aşağıda da açıklamak istedim;
Devrede b1,b2 ve b3 ledleri bulunuyor. Bunlardan b2 ledi her gün saat 8'de yanıyor. Kesme verdiğim zaman b2 led'i sönüp b1 ledi'i 2 saniye süre ile yanıyor ve daha sonra b1 led'i sönüp b2 led'i yanmaya devam ediyor. Buraya kadar sorun yok.
Benim yapmaya çalıştığım yukarıdaki döngü veya kesme 5 defa meydana gelince her iki led'in (b1,b2) yanmasını da devre dışı bırakıp b3 ledini yakmak.
ilk sorum;
Delay komutunu kallanmadan 2 saniye yanmayı nasıl kontrol edebilirim? sizin önerdiğiniz şekilde yaparsam ledlerin yanıp sönmesini kesmeye göre kontrol etmiş olmuyor muyum?
ikinci sorum;
Sayacı nasıl tanımlamam gerekiyor? int şeklinde mi tanımlamalıyım yoksa başka bir yöntem önerebilir misiniz?
Teşekkürler.