Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

HI-TECH Interrupt Sorunu

Başlatan ICETEA, 28 Temmuz 2009, 09:56:27

ICETEA

Arkadaşlar HI-TECH derleyicisinde PIC16F877A kullandığım bir devrede
{
veri=getch(); 
if(veri=='A')
	{   
		led_yak_son();   
	}   
else
	{     
		efekt();   
	}
}  

gibi bir fonksiyonu interrupt olarak nasıl kullanabiliriz??yada seri porttan aldığımız herhangi bir bilgiyi interrupt olarak kullanarak ama interrupt olana kadar programın akışını bozmadan nasıl kullanabiliriz?

yazdığım şekliyle çalıştığında programın akışında bekleme yapıyor bilgi gelene kadar..beklemden program akışının interrupt gelene kadar devam etmesi lazım.

ANA PROGRAM

#include <pic.h>
#include <htc.h>
#include <stdio.h>
#include <math.h>
#include "usart.h"
#include "delay.h" 
void karasimsek(void)
{
	char i,j;
	for(j=0;j<4;j++)
	{
		for(i=1;i<11;i++)
		{
			switch(i)
			{
				case 1  : PORTD=0x01; RC1=0; RC0=0; break;
				case 2  : PORTD=0x02; RC1=0; RC0=0; break;
				case 3  : PORTD=0x04; RC1=0; RC0=0; break;
				case 4  : PORTD=0x08; RC1=0; RC0=0; break;
				case 5  : PORTD=0x10; RC1=0; RC0=0; break;
				case 6  : PORTD=0x20; RC1=0; RC0=0; break;
				case 7  : PORTD=0x40; RC1=0; RC0=0; break;
				case 8  : PORTD=0x80; RC1=0; RC0=0; break;
				case 9  : PORTD=0x00; RC1=0; RC0=1; break;
				case 10 : PORTD=0x00; RC1=1; RC0=0; break;
			}
			DelayMs(30);
		}
		for(i=9;i>1;i--)
		{
			switch(i)
			{
				case 1  : PORTD=0x01; RC1=0; RC0=0; break;
				case 2  : PORTD=0x02; RC1=0; RC0=0; break;
				case 3  : PORTD=0x04; RC1=0; RC0=0; break;
				case 4  : PORTD=0x08; RC1=0; RC0=0; break;
				case 5  : PORTD=0x10; RC1=0; RC0=0; break;
				case 6  : PORTD=0x20; RC1=0; RC0=0; break;
				case 7  : PORTD=0x40; RC1=0; RC0=0; break;
				case 8  : PORTD=0x80; RC1=0; RC0=0; break;
				case 9  : PORTD=0x00; RC1=0; RC0=1; break;
				case 10 : PORTD=0x00; RC1=1; RC0=0; break;
			}
		DelayMs(30);
		}
	}
	PORTD=0x00; RC1=0; RC0=0;
}

void led_yak_son(void)
{
	unsigned char i;
	for(i=0;i<4;i++)
	{	
		PORTD=0xFF; RC1=1; RC0=1;
		DelayMs(100);
		PORTD=0x00; RC1=0; RC0=0;
		DelayMs(100);
	}
}

void efekt (void)
{
	karasimsek();
	led_yak_son();
}

void main(void)
{
	unsigned int deger=0;
	
	PORTB=0xFF;
	TRISC=0xF0;
	TRISD=0x00;
	
	PORTB=0x00;
	PORTD=0x00;
	PORTC=0x00;
	usart_init();
	for(;;)
	{	
		efekt();
	}
}


burada seriportla gelecek bir bilgi sonucu programın akışını durdurmadan sadece interrupt geldiğinde led_yak_son fonksiyonu çalışacak yapmaya çalıştığım bu..

yardımcı olabilecek arkadaşlara şimdiden teşekkürler..

arslan74

Merhaba,

Aşağıdaki konuları inceleyiniz.

Hi-Tech PIC C Eğitim Dökümanların Önemi http://picproje.org/index.php/topic,19213

Hi-Tech PIC C Eğitim Dökümanı 1 http://picproje.org/index.php/topic,19127

Hi-Tech PIC C Eğitim Dökümanı 2 http://picproje.org/index.php/topic,18561

Hi-Tech PIC C Eğitim Dökümanı 3 http://picproje.org/index.php/topic,19152

Hi-Tech PIC C Eğitim Dökümanı 4 http://picproje.org/index.php/topic,19169

Hi-Tech PIC C Eğitim Dökümanı 5 http://picproje.org/index.php/topic,19170

Hi-Tech PIC C Eğitim Dökümanı 6 http://picproje.org/index.php/topic,19214

Hi-Tech PIC C Eğitim Dökümanı 7 http://picproje.org/index.php/topic,19225

Hi-Tech PIC C Eğitim Dökümanı 8 http://picproje.org/index.php/topic,19247

Hi-Tech PIC C Eğitim Dökümanı 9 http://picproje.org/index.php/topic,19268

Hi-Tech PIC C Eğitim Dökümanı 10 http://picproje.org/index.php/topic,19320


Not: Kodlarını [code] tagleri içerisine alarak yazın.[/b][/u] [/color]

Selamlar

ICETEA

static void interrupt kesme(void);
	{ 
		if(RCIF) 
		{ 
			GIE=1; 
			RCIF=1; 
			veri=getch(); 
			if(veri=='A') 
				{ 
					led_yak_son(); 
				} 
			else 
				{ 
					efekt(); 
				} 
					GIE=1; 
		} 
	} 
}


HASAN HOCAM BU ŞEKİLDE BİR INTERRUPT OLUŞTURDUM SENİN GÖNDERDİKLERİNİ OKUDUKTAN SONRA AMA KLAVYEDEN "A" HARFİNİ GİRİNCE DURUYOR PROGRAM HİÇ BİR ŞEY YAPMIYOR..NERDE HATA YAPTIĞIMI SÖYLEYEBİLECEK BİR ARKADAŞ VAR MI ACABA??

arslan74

Merhaba,

Neden hata verdiğini inceleyim. interrupta ilgili bit set edilmesiyle oluşur. Sende interrupt aldında bu bit set edildimi diye bakarsın. işlem bitikten sonra  bu bit tekrar silinirki bilgi geldiğinde tekara set edebilsin.
Ama senin programında bu bit silinmemiştir, aksine set etmişin. Ama bit silme işlemini hemen başında yaparsan o zaman da getch() fonsiyonunda takılı kalacak. kesme programında getch() çağrılmaz. Fonksiyonu incelediğinizde getch() fonksiyonunun neden çağrılmaması gerektiği belli olacaktır.

unsigned char 
getch() {
	/* retrieve one byte */
	while(!RCIF)	/* set when register is not empty */
		continue;
	return RCREG;	
}


Onun yerinde fonsiyonun yaptığı RCREG içini okumayı fonsiyon okumadan yapmış olsan daha mantıklı ve sağlıklı bir programın olmuş olacaktır.

Bunun aşağıdakine benzer cok kod var. Onlardan birini alıp kullanabilirsin.

if ((RCIE)&&(RCIF))	{	/*receive interrupt routine*/
	
		unsigned char rx_data;
		
		rx_data = RCREG;
            
     /*

       Kendi kodunu buraya yaz.

     */
       
		RCIF = 0;			// uart kesmesini kabul et. 
		
	}


Selamlar.

ICETEA

teşekkürler hocam yardımınız için ;

fonksiyon çağırmak yerine fonksiyonda kullandığım kodu yazdım gösterdiğiniz aralığa ama gene klavyeden herhangi bir tuşa basınca rani rx den bilgi geldiğinde program durdu ve ledlerin ışığı tamamen söndü..


yazdığım kod aşağıdak,i gibidir..
static void interrupt kesme(void);
	if ((RCIE)&&(RCIF))  
 	{   
      unsigned char rx_data;
		
		rx_data = RCREG;
		
		unsigned char i;
	    for(i=0;i<4;i++)
	{	
		PORTD=0xFF; RC1=1; RC0=1;
		DelayMs(100);
		PORTD=0x00; RC1=0; RC0=0;
		DelayMs(100);
	}
		

		RCIF = 0;
       
   } 
}

arslan74

Merhaba,

Yavaş yavaş olacak yazdığın kod. Şimdilik mükemmel bir kod olmasa da yazdıkça kendini geliştireceksin. Kendi geliştirme işini önce sana söylenenleri yapmadan geçer. Bundan önceki mesajımda sana bir dip not düştüm. Kodlarını kod bloku içine al diye, ama şimdi görüyorum ki bir şey değişmemiş. Ya bizi dikkate almıyorsun yada bilmediğin için yapmıyorsun. Eğer bilmiyorsan, burada bilmediğin konuda sor, sana yardımcı olalım.

Selamlar

ICETEA

Hocam "Bundan önceki mesajımda sana bir dip not düştüm. Kodlarını kod bloku içine al diye, ama şimdi görüyorum ki bir şey değişmemiş. Ya bizi dikkate almıyorsun yada bilmediğin için yapmıyorsun." demişsin..

bunun cevabı bilmemem yoksa sizi dikkate almamak gibi bir durumum söz konusu olamaz..Kodlarını kod bloğu içine al demişsiniz Hocam ama bunun ne demek olduğunu anlamadım.lütfen yanlış anlamayın tekrar belirtiyorum sizi dikkate almamam gibi bir durum söz konusu değil öğrenmeye çalışıyorum.

KAZIMUGUR

Cevap ve ya mesaj yazma sayfasında # ile gösterilen butona iki kere tıklayıp arasına kodlarınızı yazabilirsiniz.
Ya da doğrudan kendiniz yazabilirsiniz.
[code] kodlar [/code]  


İki köşeli parantez arasındakiler özel olarak gösterilir ve dikkat çeker.

arslan74

Alıntı yapılan: "ICETEA"Hocam "Bundan önceki mesajımda sana bir dip not düştüm. Kodlarını kod bloku içine al diye, ama şimdi görüyorum ki bir şey değişmemiş. Ya bizi dikkate almıyorsun yada bilmediğin için yapmıyorsun." demişsin..

bunun cevabı bilmemem yoksa sizi dikkate almamak gibi bir durumum söz konusu olamaz..Kodlarını kod bloğu içine al demişsiniz Hocam ama bunun ne demek olduğunu anlamadım.lütfen yanlış anlamayın tekrar belirtiyorum sizi dikkate almamam gibi bir durum söz konusu değil öğrenmeye çalışıyorum.

Yazıdan alıntı almak için cevap yazılan kutunun sağ üst kenarında "alıntı" butonu var. Alıntı ile cevap vermek istiyorsanız "cevap yaz" basmayın "alıntı" tuşuna basarak cevap verin.

Hatalı gönderdiğiniz mesajı  düzeltmek için "edit" butonuna basarak düzeltebilirsiniz.

ICETEA

Alıntı yapılan: "arslan74"
Alıntı yapılan: "ICETEA"Hocam "Bundan önceki mesajımda sana bir dip not düştüm. Kodlarını kod bloku içine al diye, ama şimdi görüyorum ki bir şey değişmemiş. Ya bizi dikkate almıyorsun yada bilmediğin için yapmıyorsun." demişsin..

bunun cevabı bilmemem yoksa sizi dikkate almamak gibi bir durumum söz konusu olamaz..Kodlarını kod bloğu içine al demişsiniz Hocam ama bunun ne demek olduğunu anlamadım.lütfen yanlış anlamayın tekrar belirtiyorum sizi dikkate almamam gibi bir durum söz konusu değil öğrenmeye çalışıyorum.

Yazıdan alıntı almak için cevap yazılan kutunun sağ üst kenarında "alıntı" butonu var. Alıntı ile cevap vermek istiyorsanız "cevap yaz" basmayın "alıntı" tuşuna basarak cevap verin.

Hatalı gönderdiğiniz mesajı  düzeltmek için "edit" butonuna basarak düzeltebilirsiniz.



if ((RCIE)&&(RCIF)) 
{ 
unsigned char rx_data; 

rx_data = RCREG; 

unsigned char i; 
for(i=0;i<4;i++) 
{ 
PORTD=0xFF; RC1=1; RC0=1; 
DelayMs(100); 
PORTD=0x00; RC1=0; RC0=0; 
DelayMs(100); 
} 


RCIF = 0; 

} 
}


bu şekilde oldu herhalde hocam..kusura bakmayın bilmiyordum bu şekilde yazmayı..şimdi problemime gelecek olursak bu şekilde yazınca da virtual terminalde herhangi bir klavye tuşuna basınca program tamamen duruyor bütün akşam uğraştım ama bu sorunu bir türlü çözemedim..bir bilgi geldiği zaman yazdığım koddaki işlemi yapıp flaş yapması gerekiyor sürekli ama olmadı.

arslan74

Kesme programı altında öyle bekleme yapılmaz.Led flash işini ana program altında yaparsın. Kesme programında sadece bilgiyi al.

ICETEA

Alıntı yapılan: "arslan74"Kesme programı altında öyle bekleme yapılmaz.Led flash işini ana program altında yaparsın. Kesme programında sadece bilgiyi al.

if ((RCIE)&&(RCIF))   {   /*receive interrupt routine*/ 
    
      unsigned char rx_data; 
       
      rx_data = RCREG; 
            
     /* 

       Kendi kodunu buraya yaz. 

     */ 
        
      RCIF = 0;         // uart kesmesini kabul et. 
       
   }


demiştiniz hocam bende kendi kodunu buraya yaz dediğiniz kısımda flaş işlemini yapacağız diye düşündüm..benim ana progrma ve kesme programım aşağıdaki gibi burda nasıl bir değişiklik yapmam gerekiyor?

void main(void)
{
	unsigned int deger=0;
	
	PORTB=0xFF;
	TRISC=0xF0;
	TRISD=0x00;
	
	PORTB=0x00;
	PORTD=0x00;
	PORTC=0x00;
	
	RCIE=1;
	GIE=1;
	PEIE=1;
	 
	usart_init();
	efekt();

static void interrupt kesme(void);
	if ((RCIE)&&(RCIF))  
 	{   
		unsigned char rx_data;
		rx_data = RCREG;
		unsigned char i;
		for(i=0;i<4;i++)
		{	
			PORTD=0xFF; RC1=1; RC0=1;
			DelayMs(100);
			PORTD=0x00; RC1=0; RC0=0;
			DelayMs(100);
		}
		
		RCIF=0;
       
   } 
}

ICETEA

tamam hocam çalışmalarınızı okudum ve sorunu çözdüm şu anda istediğim gibi çalışıyor devre.main programı yazarken } ile sonlandırmayı atlamışım ondanmış sanırım ana problem.çok teşekkür ederim yardımınız için.

son kod ;

void efekt (void)
{
	karasimsek();
	led_yak_son();
}

void main(void)
{
	unsigned int deger=0;
	
	PORTB=0xFF;
	TRISC=0xF0;
	TRISD=0x00;
	
	PORTB=0x00;
	PORTD=0x00;
	PORTC=0x00;
	
	RCIE=1;
	PEIE=1;
	GIE=1;
	 
	usart_init();
	efekt();
}
void interrupt kesme(void)
{
	if ((RCIE)&&(RCIF))  
 	{   
		unsigned char rx_data;
		rx_data = RCREG;
		for(;;)
		{	
			led_yak_son();
		}
		
		RCIF=0;
		RCIE=1;
       
   } 
}



son olarak yapmak istediğim bişey var.program bu haldeyken USART tan bir kesme alınca flaş yapıyor.usart tan kesme geldikten sonra flaş yaparken benim 10 adet butonum var bunlardan herhangi birine basıldığında sadece o ledi yakmak istiyorum.

bunun için ne yapmam gerekiyor?

ICETEA

void klavye_degeri_al(void)
{
	unsigned int okunan=0;
	okunan=(PORTB)+(RC4*256)+(RC5*512);
	DelayMs(5);
	if(okunan!=(PORTB)+(RC4*256)+(RC5*512))
	{
		switch(okunan)
		{
			case 1  : putch(sayilar[0]); PORTD=0x01; RC1=0; RC0=0; break;
			case 2  : putch(sayilar[1]); PORTD=0x02; RC1=0; RC0=0; break;
			case 4  : putch(sayilar[2]); PORTD=0x04; RC1=0; RC0=0; break;
			case 8  : putch(sayilar[3]); PORTD=0x08; RC1=0; RC0=0; break;
			case 16 : putch(sayilar[4]); PORTD=0x10; RC1=0; RC0=0; break;
			case 32 : putch(sayilar[5]); PORTD=0x20; RC1=0; RC0=0; break;
			case 64 : putch(sayilar[6]); PORTD=0x40; RC1=0; RC0=0; break;
			case 128: putch(sayilar[7]); PORTD=0x80; RC1=0; RC0=0; break;
			case 256: putch(sayilar[8]); PORTD=0x00; RC1=0; RC0=1; break;
			case 512: putch(sayilar[9]); PORTD=0x00; RC1=1; RC0=0; break;
		}
	}
}



Bu şekilde yazdığımda butonlarla led yakma işlemim gerçekleşiyor..

Sadece tek bir sorunum kaldı klavyeden bilgi girildikten sonra flaş yaparken butona basıldığında led yakmam lazım burda sıralamada ana programda nasıl yerleştirmem gerekiyor?? bir interrupt daha mı oluşturmam gerekir acaba? yardımcı olabilirseniz sevinirim hocam..

ANA PROGRAM

void main(void)
{
	unsigned int deger=0;
	
	PORTB=0xFF;
	TRISC=0xF0;
	TRISD=0x00;
	
	PORTB=0x00;
	PORTD=0x00;
	PORTC=0x00;
	
	RCIE=1;
	PEIE=1;
	GIE=1;
	 
	usart_init();
	efekt();
}
void interrupt kesme(void)
{
	if ((RCIE)&&(RCIF))  
 	{   
		unsigned char rx_data;
		rx_data = RCREG;
		for(;;)
		{	
			led_yak_son();
		}
		
		RCIF=0;
		RCIE=1;
       
   } 
}

arslan74

Merhaba,

Ne yapmak istediğiniz anlamış değilim. Anlamam o kadarda önemli değil. Ama Kodlarına bakınca anlaşılan bir mantık hatası yaptığın belli. Hangi versiyonun kullandığını bilmiyorum. Ama derleyici de bir sorun var gibi, bu kodu derle'memesi gerek bir hata veya en azından uyarı mesajı vermeli.

Hatalarına gelince, çok hata var. Bunları anlatmaya kalkmak için en az iki sayfa yazı yazılması gerek. Bunları ben yeniden anlatmak yerine siz bu işi professiyonel mana da yapmak isterseniz. Önce örnek verilen küçük projeleri inceleyin ve kendinizde bizzat yaparak öğrenmenizi pekiştirin. Bu şekilde taban'dan temel inerek, hem benim anlatmak, hemde senin için anlamak çok zor bir yol. O yüzden, önce temeli anlatalım ve anlayalım, sonrası üstüne eklemesini kendin kimseden yardım almadan da yapabilirsin.

Selamlar