Hi Tech C de PCL mantığı nasıl olur?

Başlatan XX_CİHAN_XX, 26 Ağustos 2009, 15:35:55

XX_CİHAN_XX

Asm de şöyle birşey yapabiliyorduk.
DataTable
     ADDWF     PCL,F
     GOTO     CHAR0
     GOTO     CHAR1
     GOTO     CHAR2
     GOTO     CHAR3
     GOTO     CHAR4
     GOTO     CHAR5
     RETURN

     MOVLW     .3
     CALL     DataTable     ;tablodan CHAR3 e zıpla!
     ........


Bunu C de switch lerle yapmak mümkün ancak benim tablom aşağı yukarı 100 karakterden oluşacak. Alt alta 100 tane CASE kullanmak istemiyorum hem görsel açıdan hem hız açısından hemde kod kalabalığı açısından hoş bir durum değil.
Yukarıdaki ASM kodu ile CHAR1 e de aynı hızda, CHAR100 e de aynı hızda gidilebilmektedir. Ve oldukça hızlı gidilebilmektedir.
Bu mantığı Hi Tech C  ile nasıl yapabiliriz ?
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

controller

Görsel açıdan ve kod kalabalığı açısından tartışılabilir ancak HIZ açısından switch-case yapısının yukarıda yazdığınız mantıktan bir farkı yoktur. if-else yapısında hız farkeder.
Hesabım OG tarafından haksız bir şekilde pasif yapılmıştır.

serdararikan

denemiş değilim ama arkadaşımızın dediği gibi ASM blok kullanmak bence switch case yapısı kullanmaktan daha hızlı olacaktır.neticede derleyici muhtemelen her case için içerde BTFSC vey BTFSS yapılarından birisini kullanıyordur.bildiği kadarıyla asm("RETLW 0x04") formatında asm kullanılabiliyor.

picusta

Fonksyon pointer tablosu kullanmayi dene.
istedigin hiz'a ulasilirsin (islemcin pointerlara yatkin ise).

serdararikan

evet pointer kullanmakta mantıklı.bir char sabit dizisi oluşturup liste[index] şeklinde de tablo oluşturabilirsin.dizi oluşturursan işlemcinin pointer uymu sorunun kalmaz.

hasangurlek

Alıntı yapılan: "serdararikan"evet pointer kullanmakta mantıklı.bir char sabit dizisi oluşturup liste[index] şeklinde de tablo oluşturabilirsin.dizi oluşturursan işlemcinin pointer uymu sorunun kalmaz.

Array kullanarak programı nasıl dallandırıyorsunuz ?
http://www.cyber-warrior.org, Although they like whiteness, sometimes twilight is required...  Hala evlilermi bilinmez ama kesinlikle artık uygun değiller !!!

picusta

Zannedersem ne demek istedigimi tam anlamadiniz, veya anlatamadim.

Fonksyon çagririken söyle olacak :
char Idx = 3;
FonksyonListesi[Idx]();

ASM de dnk gelen yer :
MOVLW     .3
CALL     DataTable     ;tablodan CHAR3 e zıpla!

XX_CİHAN_XX

void CHAR_A (void){
	NOP();
}
void CHAR_B (void){
	NOP();
}
void CHAR_C (void){
	NOP();
}
void CHAR_D (void){
	NOP();
}
void CHAR_E (void){
	NOP();
}
void CHAR_F (void){
	NOP();
}
void CHAR_G (void){
	NOP();
}
void CHAR_H (void){
	NOP();
}

     void (*fp[8])(void);


void main (void)
{


      fp[0] = CHAR_A;
      fp[1] = CHAR_B;
      fp[2] = CHAR_C;
      fp[3] = CHAR_D;
      fp[4] = CHAR_E;
      fp[5] = CHAR_F;
      fp[6] = CHAR_G;
      fp[7] = CHAR_H;


		fp[0]();
		fp[1]();
		fp[2]();
		fp[3]();
		fp[4]();
		fp[5]();
		fp[6]();
		fp[7]();




}


Hocam şöyle bir deneme yaptım ve işlev olarak istediğim sonucu aldım. Hız olarakta dediğiniz gibi direk fonksiyona zıplayabiliyorum. Asm deki PCL kadar olmasada oldukça iyi bir hız sayılır. Ancak üretilen asm yide inceledim eklenen her fonksiyon için bir değişken harcıyor. Buda 16F serisi bir pic kullandığım için oldukça sıkıntı oluyor. Zaten denedim, derleyici bu iş için 100 adet değişken kullanmama izin vermiyor. Dolayısıyla okadar yüksek adette fonksiyon ekliyemiyorum bu şekilde olunca.
Ama ram sorunu olmayan işlemciler için çok iyi bir yöntem. Sayenizde bunuda öğrenmiş olduk.

Önerebileceğiniz başka bir alternatif var mı  :roll:
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

picusta

Listeni tanimlarken, asagidaki kismi ROM'a atabilirsin. O zaman her fonksyon için bir RAM yeri harcamazsin :
     fp[0] = CHAR_A;
      fp[1] = CHAR_B;
      fp[2] = CHAR_C;
      fp[3] = CHAR_D;
      fp[4] = CHAR_E;
      fp[5] = CHAR_F;
      fp[6] = CHAR_G;
      fp[7] = CHAR_H;

XX_CİHAN_XX

Hocam nasıl ROM a atıcağımı bulamadım. O tanımlamaları fonksiyon içinde değil dışında yapıyorum (main in dışına çıkarıyorum) bu sefer hata veriyor, derlemiyor.

   void (const *fp[8])(void);


Şeklinde değiştirdim yine birşey farketmedi. Aşağıda gördüğünüz gibi liste tanımlamasını RAM e yapıyor.


186:                     fp[0] = CHAR_A;
  0024    3007     MOVLW 0x7
  0025    00E7     MOVWF 0x67
187:                     fp[1] = CHAR_B;
  0026    300A     MOVLW 0xa
  0027    00E8     MOVWF 0x68
188:                     fp[2] = CHAR_C;
  0028    3001     MOVLW 0x1
  0029    00E9     MOVWF 0x69
189:                     fp[3] = CHAR_D;
  002A    3004     MOVLW 0x4
  002B    00EA     MOVWF 0x6a
190:                     fp[4] = CHAR_E;
  002C    300D     MOVLW 0xd
  002D    00EB     MOVWF 0x6b
191:                     fp[5] = CHAR_F;
  002E    3016     MOVLW 0x16
  002F    00EC     MOVWF 0x6c
192:                     fp[6] = CHAR_G;
  0030    3013     MOVLW 0x13
  0031    00ED     MOVWF 0x6d
193:                     fp[7] = CHAR_H;
  0032    3010     MOVLW 0x10
  0033    00EE     MOVWF 0x6e
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

picusta

Fonksyon listesi ROM'da olmasi ve ROM pointer fonksyonlarina sahip olmasi gerekiyor.
Derleyiciye özel komutlarla ROM'a atilabilir. Hi-Tech'de nasil yapilir bilmiyorum.
Asagidaki koda benzemesi gerekir :
(ROM tanimlayicilari) void ((ROM tanimlayicilari) *fp[MX_FNKSYON])(void) =
{
CHAR_A,
CHAR_B,
CHAR_C,
CHAR_D,
CHAR_E,
CHAR_F,
CHAR_G,
CHAR_H, 
};

XX_CİHAN_XX

Hocam Bahsettiğiniz olayı HiTech C nin manuel inden bulamadım sanırım 16 serisi picler bu işlemleri desteklemiyor ama başka bir yöntem ile yapmaya karar verdim. Fakta bu sefer karşıma başka bir engel çıktı. Yapmaya Çalıştığım şey;
2 yada 3 boyutlu yüksek elemanlı sabit(const) tipli bir dizi oluşturmuk.
16 serisinde ROM bellek 2K lık sayfalar halinde olduğu için, Dizinin boyutu 2K yı geçince hata veriyor. Bende 2K yı geçmeyecek şekilde parçalara ayırdım ama yine 2K yı geçemiyeceğimi belirten bir hata aldım.
Error   [1346] ; 0. can't find 0xB38 words for psect "strings" in segment "CODE" (largest unused contiguous range 0x800)

2 adet 2 boyutlı sabit tipli dizi yaratabilmem gerek.
volatile unsigned char const font57[125][7] = {1,2};

volatile unsigned char const font715[125][15] = {1,2};

Yada bir adet 3 boyutlu dizi
volatile unsigned char const font715[125][15][7];

Fakat bu dizileri parçalasamda bütün yazsamda toplamda 2K yı geçen bir boyuta ulaştığı için derleyici yukarıdaki hatayı veriyor. Manueldende iyice araştırdım ama bu durumu aşamadım bir türlü.
HiTechC PRO da 2K dan büyük sabit tipli dizi tanımlaması yapmak mümkünmüdür PIC16 MCU ları için ?
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.

hasangurlek

Sanırım sizin problem kullandığınız dille, 2K lık bank kapasiteleri ile alakalı değil. 3 boyutlu dizeden bahsediyorsunuz ki 125x15x7=13.125 byte yapar, 16 serisinde remi romu neyi toplarsanız toplayın bu büyüklükte kullanabileceğiniz bir alan yoktur.
http://www.cyber-warrior.org, Although they like whiteness, sometimes twilight is required...  Hala evlilermi bilinmez ama kesinlikle artık uygun değiller !!!

picusta

ROM'da fonksyon listesi çalismasi gerekir zor bir olay değil. Ugrasirsan olur.

linker'a komut verip tablonun yerini degistirebilirsin, böylece tablon BANK basinda baslar ve 2K'lik tablo yapabilirsin.
Su asagidaki satir bana süpheli geldi:
volatile unsigned char const font57[125][7] = {1,2};


Su satirlari derlemeyi dene :
volatile unsigned char const font57[2][2] = {1,2,3,4};


volatile unsigned char const font57[4][4] = {1,2,3,4};

Hangisi hata veriyor ? vermiyor ?

XX_CİHAN_XX

Alıntı yapılan: "hasangurlek"Sanırım sizin problem kullandığınız dille, 2K lık bank kapasiteleri ile alakalı değil. 3 boyutlu dizeden bahsediyorsunuz ki 125x15x7=13.125 byte yapar, 16 serisinde remi romu neyi toplarsanız toplayın bu büyüklükte kullanabileceğiniz bir alan yoktur.
Haklısınız yanlış yazdım benim maksimum ihtiyaç duyduğum alan aşağıdaki kadardır.
volatile const char charTable[125][22] =  {127,2};

Buda 2750 bayt yapmaktadır. Malum 2Kb yi geçince derleyici izin vermiyordu.
Bu sorunu @picusta hocamın dediği gibi linker a müdahale ederek sonunda çözebildim. Ancak bu beni baya uğraştırdı açıkçası. User manuel de anlatmış aslında ama o bana çok karmaşık geldi ve çözene kadar nerdeyse 1 günlük mesaimi vermek zorunda kaldım.
Neyse ki uğraşlarım netice verdi ve 2K sınırını aşabildim :)

Aşağıdaki kodları ekleyince 2K diye bir sınır kalmıyor Program bellekte istediğiniz bir noktadan başlayarak Program belleğinin sonuna kadar istediğiniz kadar sabit değer yükleyebiliyorsunuz.
İşte bunun için gerekli kodlar:
#pragma psect strings=charTable
#asm
       psect charTable,ovrld,abs,delta=2
       org (_ROMSIZE - 3000) 	         //Rom dan 3000 satır geriye gel
#endasm

       volatile const char charTable[125][22] =  {127,2};

Hepsi bukadar :)
Teşekkürler hocam, teşekkürler arkadaşlar.
Yirmi yaşındaki bir insan, dünyayı değiştirmek ister . Yetmiş yaşına gelince , yine dünyayı değiştirmek ister, ama yapamayacağını bilir.