pointer

Başlatan OptimusPrime, 06 Kasım 2009, 10:29:25

OptimusPrime

..pointer kullanılmadan

.................... i++; 
0066:  INCF   10,F				
.................... if(i>7) i=0; 
0068:  MOVF   10,W						
006A:  SUBLW  07				
006C:  BTFSS  FD8.0				
006E:  CLRF   10				



..pointer kullanılarak

.................... (*p)++; 
0076:  MOVFF  11,FE9				
007A:  MOVFF  12,FEA				
007E:  INCF   FEF,F				
.................... if((*p)>7) i=0; 
0080:  MOVFF  12,03					
0084:  MOVFF  11,FE9				
0088:  MOVFF  12,FEA
008C:  MOVF   FEF,W
008E:  SUBLW  07
0090:  BTFSS  FD8.0
0092:  CLRF   10



yukarıdaki kod örneğinde pointer kullanılarak ve kullanılmadan yapılmış 2 örnek ve buna karşılık gelen asm kodları var.

görülen o ki pointer işlemi programın akışını ciddi şekilde yavaşlatmış.

peki pointer ı ne tür bir işte kullanıp program akışını hızlandırabilirim.
bir örnek verebilir misiniz? böyle bir uygulama yapan varmı?
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

azimli

örnek vermeye şu anda müsait değilim ama kullandığım bir iki yeri yazabilirim ansi C89 komut kümesiyle C30 derleyicisinde 10 bitlik adc kullanımında buf0 dan buf15 kadar adc bufferlerini doldurup toplam rakkamı 4 kere sağa kaydırıp (16 ya bölüp) filtreli bir yazılımla okuma yapıldığını düşün örneklemeyi 16 dan fazla yapsak adc buflerle işlemi kotarmak zamanı uzatıyor ve kaliteli örnekleme almak zorlaşıyor örnekleme sayısı 16 olsa bile adc bufleri kullanmak işlmeciye angarya oluyor burda adresleme pointeri kullanmak olayı çok kolaylaştırıyor işlemci yükünü azaltıyor ve daha hızlı etkin bir örnekleme elde ediliyor.

aynı şekilde işlemci aynı anda aynı saykıllarda tek değilde 2 ve 4 adet adc kanal okumasıda yapabiliyor burda da deneme amaçlı bir kez pointerlerle kullanmıştım ama ticari bir projede böyle bir uygulama yapmadım

spi buffere HC595 IC sine seri bilgi gönderirken (kayan yazı ve display sürmede) bilgileri bir düzene koyup işlem sırasını hızlandırmak ve etkin bir display taramasını işlemeciyi beklemeye sevketmeden interrupt içine direkt pointerleri göndermek işime gelmişti.

kod okunurluğunda pointer kullanımı işi zorlaştırıyor ama işlemi bir kere başarıp artık hep onu hazır kullanmaksa mantık işlemleri kolaylaştırıyor.

yeni kod yazımında pointerlerden hep çekinirim ama daha sonra vaktim olup kodlarla oynamaya kaktığımda pointerleri gerekli görürsem önemini orda farkedersem kullanırım.

azimli

aşağıda 10 bit 1000 ksps bir adc kanalın yazılımsal olarak peş peşe 16 kez okunup ortalaması alınıyor adres ve pointer yapısı kullanılıyor.
ve adc registerlerdeki en fazla bekleme süreleri kullanılarak ve maksimum adc pin giriş direnci kullanılarak (500R)
aslında 16 adet adc bufferde tanımlanabilir ama ben bu kodu kullanmayı kendi açımdan daha iyi gördüm işlemler toplamı 30Mips de 10mikro saniye tutmuyor çünkü makine koduna yakın bir yapı kullanılıyor iş C ram değişkenlerine bırakılmıyor kodun asm çevrimi makineye daha yakın çıkıyor.

program bu fonksiyonu çağıran yere ilgili adc kanalının (pininin) ölçülmek istenen zamandaki değerini gönderiyor.


unsigned char count=0;

unsigned int POT_VOLTAJ_ANALOG_DEGER(void)
{
   ADCHS  = 0x0000;
   ADCON2 = 0x003C;
   
   unsigned int *ADC16Ptr=0;   
   unsigned int ADCValue=0;

   ADC16Ptr = &ADCBUF0;          
   IFS0bits.ADIF = 0;         
   ADCON1bits.ASAM = 1;            
   while (!IFS0bits.ADIF);       
   ADCON1bits.ASAM = 0;          
   for (count = 0; count < 16; count++)
   {
      ADCValue = ADCValue + *ADC16Ptr++;   
   }
   ADCValue = ADCValue >> 4;
      
   return ADCValue;
}

OptimusPrime

anlamadım.

anlamadığım yerleri kısaca yazayım.
- unsigned int *ADC16Ptr=0;
pointer a bildiğim kadarıyla char tipi olmadıkça ilk değer atanamıyor. yani benim bildiğim derleyicinin bu ifadeye hata vermesi gerekir.
hata vermiyorsa bu ifadenin anlamı nedir?

- ADC16Ptr = &ADCBUF0;
pointer adc sonucunu veren registere işaret etti. fakat ortalamasını alan döngüde yani
for (count = 0; count < 16; count++) ADCValue = ADCValue + *ADC16Ptr++;
kısmında. ADC16Ptr++ her çağırılışında o an gösterdiği adresin 2 byte altına işaret ediyor. o zaman bu döngü ADCBUF0 registerinin altındaki registerlerin değerleri toplayıp bitmez mi?
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

azimli

pointeri ve diğer değişkenleri ne olarak tanımlarsam tanımlayayım ilk tanımlamada değer atayabilirim genelde normal değişkense sıfır atarım
aslında derleyici defaultunda ben bir değer atamazsam sıfır atıyor biliyorum ama yinede sıfırı kendim atarım

işaretçinin 16 bit olarak adresleri 16 kez kaydırıp okuduğu doğru ama her seferinde aynı ADCBUF0 registerini okuyor işlemin hızlanmasının en önemli nedenide bu zaten

kod Microchip dsPIC C30 derleyici kodudur ve çalışıyor.

OptimusPrime

http://ww1.microchip.com/downloads/en/devicedoc/70065D.pdf
her seferinde aynı ADCBUF0 registeri okumuyormuş gibi duruyor.
https://donanimveyazilim.wordpress.com || Cihân-ârâ cihân içredir ârâyı bilmezler, O mâhîler ki deryâ içredir deryâyı bilmezler ||

controller

@OptimusPrime

bu konuda aşağıdaki linki inceleyebilirsin. pointer hakkındaki diğer sorularını da buradan cevaplamaya çalışırız.

http://picproje.org/index.php/topic,20911&highlight=
Hesabım OG tarafından haksız bir şekilde pasif yapılmıştır.