hitech usart receive interrupt sorunu

Başlatan nekoist, 22 Aralık 2011, 01:46:46

nekoist

Merhaba arkadaşlar,

hitech'de rx portundan seri olarak datayı alıp lcd'ye yazdıran bir devre kuruyorum. Bunun için usart kesmesini kullanmaya çalıştım. İnternette verilen örneklerden bakarak bir kesme oluşturdum aşağıdaki şekilde. Ancak devre proteusta sorunsuz çalışırken gerçeklediğimde çalışmıyor ve ekranda datayı görememiyorum.
Sorum şu, bu kesmede sıkıntılı bir yer var mı, yardımcı olursanız çok sevinirim..Teşekkürler.

#undef XTAL_FREQ
#define XTAL_FREQ 4MHZ
#define PIC_CLK 4000000
__CONFIG(XT & WDTDIS & PWRTEN & BORDIS & LVPDIS & DUNPROT & WRTEN& DEBUGDIS & UNPROTECT);



unsigned int data=0,pre_data=0;
unsigned int r0=0;
unsigned char goster_flag=0,hata_flag=0,sicaklik;


void interrupt kesme(void)
{
	    if(OERR==1||FERR==1) //overrun veya framing error olusursa
			{  		                 
				CREN=0;    	 // Re-enable receiving           
				CREN=1;  
				hata_flag=1;

	        }
		else
			{
					while(RCIF==1&&RCIE==1)
					{		data=RCREG;		
							if(pre_data=='A')	//baslangic isareti=A ise, lcd'de goster
								{	
									sicaklik=data;
									goster_flag=1;
																		
								}
							else
								{
									goster_flag=0;
								}
					}
			}
	
		pre_data=data;	//data bir onceki dataya aktarılıyor, boylelikle
						//bir sonraki cevrimde pre_data==A sorgusu yapılabiliyor.
						//pre_data='A' ise data lcd'de gosteriliyor			
}


void main()
{   unsigned char sicaklik_1;
	unsigned char sicaklik_dec[];
	TRISD=0x00;     //PORTD'yi cisik yap
	TRISC=0x80;     //PORTC'nin ilk 3 biti cikis, RD7-rx biti giris
    init_comms();
	DelayMs(5);
	lcd_init();      //LCD'yi baslat
	DelayMs(5);
	GIE = 1;  //global interrupt enable
	PEIE = 1;	//peripheral interrupt enable
	RCIE = 1;	//receive interrupt enable

	for(;;)
	{	
	    lcd_goto(0);
        lcd_puts("SICAKLIK 'C"); 
		lcd_goto(0x40);


		if(goster_flag==1)
			{	
				sicaklik_1=sicaklik-32;
				sprintf(sicaklik_dec,"%d",sicaklik_1);
				lcd_putch(sicaklik_dec[0]);
				lcd_putch(sicaklik_dec[1]);	
				goster_flag=0;
			}
		if(hata_flag==1)
			{
				lcd_puts("hata");
				//hata_flag=0;
			}
	
		 DelayMs(150);
         //LCD programı son
		 lcd_clear;
		
	}
}

haydarpasamikro

kesme alt programında while(RCIF==1&&RCIE==1)
yerine receive kesme bayrağını test etmek için if(RCIF==1&&RCIE==1) yazman ve sonra RCIF=0 ile tekrar kesme oluşabilmesi için bayrağı sıfırlaman beklenir.
Mikro Dünyası.Haydarpaşa Teknik ve Endüstri Meslek Lisesi Mikrodenetleyici Atl. Şefi

nekoist

Dediğin şekilde denedim ancak yine sonuç yok. Ama şöyle bir test yaptım, kontrol işareti olarak gönderdiğim 'A' işaretini kaldırıp kesme içinde 'A' gelip gelmediğini kontrol etmediğimde data iletimi oluyor.

yani kod aşağıdaki şekilde çalışıyor ve rf üzerinden data iletebiliyorum. Ama tabi uyandırma ve sencron işaretini de gönderdiğim ve kontrol işareti göndermediğim için ekranda data sürekli değişiyor, gelen tüm datayı sıcaklıkmış gibi ekranda gösteriyor. Kesme içinde kontrol işaretine bakmak dışında bi çözüm bulamadım açıkcası..

void interrupt kesme(void)
{
//	    if(OERR==1||FERR==1) //overrun veya framing error olusursa
//			{  		                 
//				CREN=0;    	 // Re-enable receiving           
//				CREN=1;  
//				hata_flag=1;
//	        }
//		else
//			{
					if(RCIF==1&&RCIE==1)
					{		data=RCREG;		
				//			if(pre_data=='A')	//baslangic isareti=A ise, lcd'de goster
				//				{	
									sicaklik=data;
				//					goster_flag=1;							
				//				}
				//			else
				//				{
				//					goster_flag=0;
				//				}
					}
			//}
		RCIF=0;
		pre_data=data;	//data bir onceki dataya aktarılıyor, boylelikle
						//bir sonraki cevrimde pre_data==A sorgusu yapılabiliyor.
						//pre_data='A' ise data lcd'de gosteriliyor			
}


void main()
{   unsigned char sicaklik_1;
	unsigned char sicaklik_dec[];
	TRISD=0x00;     //PORTD'yi cisik yap
	TRISC=0x80;     //PORTC'nin ilk 3 biti cikis, RD7-rx biti giris
	TRISB=0x00;
    init_comms();
	DelayMs(5);
	lcd_init();      //LCD'yi baslat
	DelayMs(5);
	GIE = 1;  //global interrupt enable
	PEIE = 1;	//peripheral interrupt enable
	RCIE = 1;	//receive interrupt enable

	for(;;)
	{	
	    lcd_goto(0);
        lcd_puts("SICAKLIK 'C"); 
		lcd_goto(0x40);


		PORTB=0x00;
		DelayMs(250);
		PORTB=0xFF;

	//	if(goster_flag==1)
	//		{	
		
				sicaklik_1=sicaklik-32; 
				//bu arada interttupt gelirse deger degisebilir,
				sprintf(sicaklik_dec,"%d",sicaklik_1);
				lcd_putch(sicaklik_dec[0]);
				lcd_putch(sicaklik_dec[1]);	

	//		}
	//	if(hata_flag==1)
	//		{
	//			lcd_puts("hata");
				//hata_flag=0;
	//		}
	
		 DelayMs(150);
         //LCD programı son
		 lcd_clear;
		
	}
}

nekoist

arkadaşlar yardımlarınızı bekliyorum.

haydarpasamikro

devre şemasına ir bakalım. Acaba isis teki devre ile gerçek devre arasında farklılık mı var?
Mikro Dünyası.Haydarpaşa Teknik ve Endüstri Meslek Lisesi Mikrodenetleyici Atl. Şefi

nekoist

farklılık yok, ki zaten rf üzerinden iletişim yapabiliyorum, sorunum preamble+sencron + başlangıç_işareti +data şeklinde gönderim yaptığımda alıcı tarafında kesme içinde "başlangıç_işareti" den sonra gelen bilgiyi al ve ekrana yazdır olayını becerememem.