Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H

Ana Menü

CC5X ve interrupt

Başlatan nuwanda, 24 Mart 2007, 11:07:31

nuwanda

CC5X compilerında interrupt nasıl yapıyoruz ?

Yani datasheetten ilgili registerları falan inceledim, nereye ne atanması gerektiği,ne olduğunda interrupt olacağı vs. Ama bir türlü toparlayıp düzgün bir koda dökemedim. Benim öğrenmek istediğim, mesela ; timer'ı 5 saniyeye ayarlayayıp, bu 5 saniye dolduğunda bir fonksiyonun çalışması. Nasıl yapabiliriz bunu ? Basit bir şekilde buna benzer bir program yazarsanuz veya varsa örnek program yollarsanız çok sevinirim.


Herkese iyi çalışmalar ;)

Macera

Aşağıdaki gibi kesme başlığını ekleyeceksin
#include "int16CXX.H"
değişken tarifinden sonrada kesme rutinini yazacan
interrupt int_server( void)
{
   int_save_registers    // W, STATUS (and PCLATH)
//   swPCLATH = PCLATH;
   if ( INTF)  
   {
      .....

       INTF = 0;  /* reset flag */
    }
   int_restore_registers // W, STATUS (and PCLATH)
 //  PCLATH = swPCLATH;
}
sonrada main rutini yazacan

CC5X in içinde örnek bir kod var.
"Art without engineering is dreaming; engineering without art is calculating." -- Steven K. Roberts

nuwanda

Şimdi böyle birşey yazdım ;

interrupt int_server( void)
{

	int_save_registers    // W, STATUS (and PCLATH)
	
    if ( T0IF)  {
        /* TMR0 overflow interrupt */
        TMR0 = 255;

		
    
			if(led==0)
				led=1;
			 else 
				led=0;

	   T0IF = 0;  /* reset flag */
    

 
    }
    int_restore_registers // W, STATUS (and PCLATH)
}


Burda interrupt'a girme süresi TMR0 ile ayarlanıyor di mi ?

Ve bu 8 bitlik bir sayaç sanırım..Peki ben bu süreyi 2 saniyeye çıkarmak istesem mesela bu değişkeni ne olarak ayarlamalıyım ?

nuwanda

Tamam anladım, option registerını ayarlamak gerekiyormuş prescalar için ;) Teşekkürler..

nuwanda

Programın son hali böyle birşey oldu, yararlanmak isteyen arkadaşlar olursa diye eklemekte fayda gördüm.

Böyle bir fonksiyonla , TMR0 sayacını kullanarak her 2 saniyede bir ledimizi yakıp söndürebiliyoruz.

interrupt int_server( void)
{
	int mod;
	int_save_registers    // W, STATUS (and PCLATH)
	
    if ( T0IF)  {
        /* TMR0 overflow interrupt */
        TMR0 = 150;
		sayac++;
		mod=sayac%53;
    	if(mod==0){
			if(led==0)
				led=1;
			 else 
				led=0;
		}
	   T0IF = 0;  /* reset flag */
    

 
    }
    int_restore_registers // W, STATUS (and PCLATH)
}


Tabi bunun çalışabilmesi için birkaç registerı da ayarlamamız gerekiyor ;

 OPTION = 0x07; /* prescaler divide by 256 */
    TMR0 = 150;  /* 150 * 256 = 90 periods */
    T0IE = 1;   /* enable TMR0 interrupt */
    GIE = 1;    /* interrupts allowed */


Bir de global bir sayac değişkeni tanımlar ve main içinde bunu sıfırlarsanız 2 saniyelik süreyi elde etmiş oluyorsunuz.

Süreyi ayarlamak için şöyle bir yol izleniyor ;

4 Mhz'lik bir kristalde her cycle 1 mikro saniye oluyor. TMR0 değerini 150 'e ayarladığımızda 150 mikrosaniyelik bir değer veriyor bize. Bunu daha da arttırmak için prescalar'ı da 256 olarak ayarlıyoruz. Bu durumda bekleme süresi 150x256 oluyor ki bu da 65 ms kadar ediyor yaklaşık. Bu  süreyi de 53 kere dönücek bir döngüye soktuğumuzda yaklaşık 2 saniyeyi elde etmiş oluyoruz..

Umarım bu yazdıklarım birilerine faydalı olur ;)