Haberler:

Forum kuralları güncellendi LÜTFEN  okuyunuz:  https://bit.ly/2IjR3ME

Ana Menü

CCS C'de pointer kullanımı

Başlatan 50Cal, 23 Haziran 2010, 14:00:58

Mucit23

Selamlar,
Bu konuda bir sıkıntım problemim var.

lcd ekrana ccs de text basmaya çalışıyorum. Her bir karaktere göre font dosyasına bir dizi parçası göndermem gerekiyor. STM32'de çalışan kodumu bir türlü CCS C ortamında 18F46K22 için çalıştıramadım.

aşağıdaki gibi bir font dosyam var.

/* ASCII Table: each character is 16 column (16dots large) and 24 raw (24 dots high) */
const unsigned int16 ASCII_Table[2688] = {
  /* Space ' ' */
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  /* '!' */
  0x0000, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180,
  0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0180, 0x0000, 0x0000,
  0x0180, 0x0180, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  /* '"' */
  0x0000, 0x0000, 0x00CC, 0x00CC, 0x00CC, 0x00CC, 0x00CC, 0x00CC,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  /* '#' */
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0C60, 0x0C60,
  0x0C60, 0x0630, 0x0630, 0x1FFE, 0x1FFE, 0x0630, 0x0738, 0x0318,
  0x1FFE, 0x1FFE, 0x0318, 0x0318, 0x018C, 0x018C, 0x018C, 0x0000,
  /* '$' */
  0x0000, 0x0080, 0x03E0, 0x0FF8, 0x0E9C, 0x1C8C, 0x188C, 0x008C,
  0x0098, 0x01F8, 0x07E0, 0x0E80, 0x1C80, 0x188C, 0x188C, 0x189C,
  0x0CB8, 0x0FF0, 0x03E0, 0x0080, 0x0080, 0x0000, 0x0000, 0x0000,
  /* '%' */
  0x0000, 0x0000, 0x0000, 0x180E, 0x0C1B, 0x0C11, 0x0611, 0x0611,
  0x0311, 0x0311, 0x019B, 0x018E, 0x38C0, 0x6CC0, 0x4460, 0x4460,
  0x4430, 0x4430, 0x4418, 0x6C18, 0x380C, 0x0000, 0x0000, 0x0000,
  /* '&' */
  0x0000, 0x01E0, 0x03F0, 0x0738, 0x0618, 0x0618, 0x0330, 0x01F0,
  0x00F0, 0x00F8, 0x319C, 0x330E, 0x1E06, 0x1C06, 0x1C06, 0x3F06,
  0x73FC, 0x21F0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  /* ''' */
  0x0000, 0x0000, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C, 0x000C,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,


Bu font dosyasında her bir karakter 24 elemandan oluşmakta. Basılacak olan karaktere göre bu tablodan ilgili karakterin başlangıç adresini alıp basma fonksiyonuna göndermem lazım. Kısaca yapmaya çalıştığım şey budur.

Basım için iki adet fonksiyon kullanıyorum.

/******************************************************************************
* Disply character on given line                                              *
*   Parameter:     c :        ascii character                                 *
*                  ln:        line number                                     *
*   Return:                                                                   *
******************************************************************************/
void LCD_DisplayChar(unsigned int16 x, unsigned int16 y, char  c) {
  c -= 32;
  LCD_DrawChar(x, y, ASCII_Table[c*24]);
}


Buraya gelen karakterler ilk önce 32 den çıkarılıp sonra tablodan ilgili karakterin başlangıç adresini fonksiyona göndermem gerekiyor. ASCII_Table dizisini göndermek için başına adres operatörü koymak gerekiyor aslında (LCD_DrawChar(x, y, &ASCII_Table[c*24]);) ama CCS buna hata veriyor. Buşekilde derleniyor

Diğer fonksiyon ise basım fonksiyonu Burada sıkıntı yok. Karakterlerin adresini doğru bir şekilde gönderebilsem ekrana basım yapacam.

/******************************************************************************
* Draw character on given position (line, coloum                              *
*   Parameter:     x :        horizontal position                             *
*                  y :        vertical position                               *
*                  c*:        pointer to color value                          *
*   Return:                                                                   *
******************************************************************************/
void LCD_DrawChar(unsigned int16 x, unsigned int16 y, unsigned int16 *c) {
  unsigned int index = 0;
  int  i = 0;
   
  LCD_WindowMax(x,y,x+16,y+20);
  LCD_SetCursor(x,y);

  Clr_Cs;
  wr_cmd(0x22);              /* Prepare to write GRAM */
  for(index = 0; index < 20; index++)
  {
    for(i = 0; i < 16; i++)
    {
      if((c[index] & (1 << i)) == 0x00) {
        wr_dat(BackColor);
      } else {
        wr_dat(TextColor);
      }
    }
  }
  Set_Cs;
}


Sorum şu;

CCS için yüksek boyutlu örnekteki gibi bir dizinin ilgili elemanının adresini bir fonksiyona nasıl gönderirim? Gönderdiğimizi varsayarsak, başlangıç adresini gönderdiğim fonksiyonda pointeri nasıl dizi gibi kullanırım?

Pointer konusunu biliyorum ama CCS de problem yaşıyorum.

Gökhan BEKEN

LCD_DrawChar(x, y, &ASCII_Table[c*24]);
kullanımı doğru fakat const değişken yerine rom türü kullanılıyor sanırım.
fonksiyonun giriş parametrelerini de güncellemek gerekebilir.
http://www.ccsinfo.com/forum/viewtopic.php?t=52298
https://www.ccsinfo.com/forum/viewtopic.php?p=146207
Özel mesaj okumuyorum, lütfen göndermeyin.

cripple

hocam sorun ccs nin pointer adresi atamasında, siz bir fonksiyonda dizi tanımlıyorsunuz öreneğin 170. adresten 190. adrese kadar, ikinci fonksiyonun pointer adresi tutuyor 180. adresten başlıyor dolayısıyla çakışma oluyor
bi abimizin başına gelmişti çözümü mplab kullanmak oldu

Mucit23

ROM konusunu bir deneyeyim ama şuanda platformu matlab'a taşıma ihtimalim yok.

O halde alternatif çözümler üretmem gerekecek.

Şunu sorayım. Yukarıda font dizisini verdim. İlgili karaktere [c*24] indisi ile ulaşıyorum. Ben eğer 24 elemanlı global bir dizi tanımlayıp font dizisini doğrudan fonksiyona göndermek yerine [c*24] 'inci elemandan sonraki 24 elemanı ayrı bir global diziye kopyalarsam sorunu çözerim diye düşündüm. Daha hızlı çalışacak bir öneriniz var mı?

Gökhan BEKEN

Çok kasmana gerek yok.
LCD_DrawChar fonksiyonunun içindeki "c" dizisi yerine "ASCII_Table" dizisini kullan.
Adres isteyen kısmı da index numarası alacak şekilde değiştir, sorun çıkmaz.
Özel mesaj okumuyorum, lütfen göndermeyin.

Mucit23

CCS 'de boyut meselesine çok dikkat etmek gerekiyor. 8 Bit mikro işlemci olduğundan dolayı &ASCII_Table[c*24] işleminin doğru çalışmadığını gördüm. İndis içerisine 16 bit işlem yapılacağını belirtmek gerekiyor.
&ASCII_Table[(int16)c*24]
Buna benzer birkaç hata vardı. Yinede pointer meselesini çözemedim. Dediğim gibi global bir diziye taşıyarak çözdüm. Çalıştı elbette ama pointer işi hala aklımda.

Alıntı yapılan: Gökhan BEKEN - 15 Aralık 2015, 13:58:08
Çok kasmana gerek yok.
LCD_DrawChar fonksiyonunun içindeki "c" dizisi yerine "ASCII_Table" dizisini kullan.
Adres isteyen kısmı da index numarası alacak şekilde değiştir, sorun çıkmaz.

Aklıma geldi aslında ama sürekli c*24 işlemi ile sürekli indisin yeniden hesaplanması aklıma yatmadı.

RaMu

Alıntı yapılan: Mucit23 - 15 Aralık 2015, 11:37:00
ROM konusunu bir deneyeyim ama şuanda platformu matlab'a taşıma ihtimalim yok.
...
Matlab değil, MPLab.
Ama Mplab kullanılınca değişecek bir şey olmaz sanırım.

Muhtemelen yapabiliyorsundur ve tam istediğin değil ama
şu konunun sonucunda
https://www.picproje.org/index.php/topic,55630.0/nowap.html
yapabildiğim kadarıyla
şöyle bir örneğim var:
https://rmtulay.wordpress.com/category/ccsc/ccsc-rom-dizilerine-pointer-atama/
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Mucit23

Matlap yazmışım farkında olmadan. Mplab olacaktı