C51 (Silabs-C8051F120) Makro Tanımlama

Başlatan bymrz, 22 Ocak 2013, 09:57:42

bymrz

Merhaba arkadaşlar,

Keil C51 ile çalışıyorum ve işlemci olarak, başlıkta belirttiğim gibi Silabs marka C8051F120 kullanıyorum. Bu işlemcinin şöyle gıcık bir durumu var ki, diğer 8051 tabanlı işlemciler gibi SFR(Özel fonksiyon register) 'lerine direk olarak erişilemiyor. Önce o registerın (mesela "PCON ") hangi sayfada olduğunu seçiyorsunuz, daha sonra PCON değerine erişiyorsunuz(okuyorsunuz veya yazıyorsunuz)...

Örnek verecek olursak :

   [b]char SFRPAGE_SAVE = SFRPAGE;[/b]     // Save Current SFR page

   [b]SFRPAGE = CONFIG_PAGE;[/b]           // set SFR page

   OSCICN = 0x83;                   // set internal oscillator to run
                                    // at its maximum frequency

   CLKSEL = 0x00;                   // Select the internal osc. as
                                    // the SYSCLK source
   //Turn on the PLL and increase the system clock by a factor of M/N
   PLL0CN  = 0x00;                  // Set internal osc. as PLL source
   [b]SFRPAGE = LEGACY_PAGE;[/b]
   FLSCL   = 0x30;                  // Set FLASH read time for 100 MHz clk
   [b]SFRPAGE = CONFIG_PAGE;[/b]

   PLL0CN |= 0x01;                  // Enable Power to PLL

   PLL0DIV = 0x01;                  // Set Pre-divide value to N (N = 1)
   PLL0MUL = 0x04;                  // Multiply SYSCLK by M (M=4)
   PLL0FLT = 0x01;                  // Set the PLL filter register for
                                    // a reference clock from 12.2 - 19.5 MHz
                                    // and an output clock from 65 - 100 MHz
   for (i=0; i < 256; i++) ;        // Wait at least 5us
   PLL0CN  |= 0x02;                 // Enable the PLL
   while(!(PLL0CN & 0x10));         // Wait until PLL frequency is locked
   CLKSEL  = 0x02;                  // Select PLL as SYSCLK source

   [b]SFRPAGE = SFRPAGE_SAVE[/b];          // Restore SFR page




Ben de diyorum ki, bu işi şöyle bir makro yardımıyla çözsem de, her seferinde ben hangi register hangi sayfada bunu akılımda tutmak zorunda kalmasam... Bir SFR değişkenine herhangi bir değer yüklemek istediğimde aşağıdaki makroyu kullansam...

SfrLoad(PCON , 0xF0);



Makro şu şekilde:
#define SfrLoad(sfr_name, sfr_val) \
    do {\
        if (sfr_name == P0) \
                SFRPAGE=P0_PAGE;P0 = sfr_val;\
        elif (sfr_name ==SP )\
				{SFRPAGE=SP_PAGE;		SP=sfr_val;}\
        elif (sfr_name ==PCON )\
				{SFRPAGE=PCON_PAGE;		PCON=sfr_val;}\
    } while (0)



Bu makro(ya da fonksiyon da yapabilirim), benim işimi görüyor, fakat aslında makro içinde gördüğünüz bu "if else" ler çok daha fazla. Ve dolayısıyla bu karşılaştırma işlemlerinin tamamlanması için oldukça fazla süre geçiyor. Benim bu süreyi kısaltmam lazım. Bunu içinde asıl yapmak istediğim şu !

Kod satırına
SfrLoad(PCON, 0xF0);


yazdığımda, derleyici, bu kod satırı için, ilgili makroya gitsin ve hangi registerı seçtiysem sadece onunla ilgili karşılaştırmaya ait kodlar buraya yazılsın. Yani derleyici benim kodumu yazdığım satısı şu şekle çevirsin...

SFRPAGE=PCON_PAGE;
PCON=0xF0;





Bunu nasıl yapabilirim... Şimdiden yardımlarınız için teşekkürler...



fgokcegoz

Bir zamanlar, bende 8051 kullanmıştım. Diğer 8051 tabanlı işlemcilerde, SFR lere değer yüklemek için öyle SFR sayfa seçimi bir durum ile karşılaşmadım. Bahsettiğiniz mesele Silabs a has bir durum galiba...
"Vicdanın ziyası, ulûm-u diniyedir. Aklın nuru, fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder." (Bediüzzaman Said Nursi)

bymrz

#2
Alıntı yapılan: fgokcegoz - 22 Ocak 2013, 10:06:50
Bir zamanlar, bende 8051 kullanmıştım. Diğer 8051 tabanlı işlemcilerde, SFR lere değer yüklemek için öyle SFR sayfa seçimi bir durum ile karşılaşmadım. Bahsettiğiniz mesele Silabs a has bir durum galiba...

Hocam, Silabs'ın da hepsinde yok ta, bu işlemci, kapasite ve donanım bakımından yüksek bir işlemci olduğundan, adamlar registerları 128 byte'a sığdıramamışlar, haliyle böyle bir yöntem seçmişler. :)    Aslında bu durum PIC serisinin "bank" seçim olayına benziyor. Yalnız onda derleyiciler bu işi kendileri yapıyor. C51 de böyle bir durum yok sanırım ya da ben bilmiyorum.

mesaj birleştirme:: 22 Ocak 2013, 10:44:42

Bu arada aşağıdaki şekilde her bir register için ayrı ayrı makro tanımlarsam oluyor gibi.

#define Sfr(P0,a)\
	do{\
		SFRPAGE=P0_PAGE;\
		P0=a;\
	}while(0)


mesaj birleştirme:: 22 Ocak 2013, 11:18:10


Alıntı YapBu arada aşağıdaki şekilde her bir register için ayrı ayrı makro tanımlarsam oluyor gibi.

#define Sfr(P0,a)\
	do{\
		SFRPAGE=P0_PAGE;\
		P0=a;\
	}while(0)




Böyle de olmuyormuş...

#define Sfr(P0,a)\
	do{\
		SFRPAGE=P0_PAGE;\
		P0=a;\
	}while(0)


#define Sfr(P1,a)\
	do{\
		SFRPAGE=P1_PAGE;\
		P1=a;\
	}while(0)




Bu şekilde iki makro tanımladığımda(P0 ve P1 için), iki makronun adı da Sfr olduğu için hata veriyor...

Napcaz ?  :)