Haberler:

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

Ana Menü

CCS C alıştırma Turlarım

Başlatan Mucit23, 10 Şubat 2012, 15:29:51

Mucit23

Baudrate ilk başta 9600 dü ama sonradan 2400'e düşürdüm. Birazcık hata azaldı.  Birazda alıcıdaki mantığı degistirdim. Önceden gelen datayı direk çıkışa veriyordum. Şimdi geken data A ise şunu yap, B ise bunu yap, C ise onu yap diyorum. Böylece hatalı sonuçlardan kurtuldum.

Mesafeyi daha test etmedim ama aynı ortamda çalışıyorlar.. Tahminimce 4-5 metre rahat alır. Mesafenin fazla artacağını da sanmıyorum çünkü ledin artısına pwm uygulayıp ledin eksisinden ise usart datalarını yolluyorum. Yani Led 20 ma den fazla birşey çekemez.

Mucit23

En son CCS nin versiyonunu 5.019'a yükseltmiştim. Fakat olmadık problemlerle karşılaşıyorum. Hiç memnun değilim.
Timer1 ve Timer0 ile devir okumaya çalışıyorum. Timer 0 ile 10ms aralıklarla kesme oluşturmam gerekiyor. Kodumu yazdım, isiste test ediyorum neredeyse 2 sn aralıklarla kesme oluşuyor.

Kodlarda göze çarpan bir problem varmı?
#include <16F877A.h>
#device ADC=10
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES XT

#use delay(crystal=4000000)

#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)

#include <lcd_driver.c>

unsigned int16 devir=0;
unsigned int8  tim_syc=0;

//****************** Timer0 Kesmesi *****************************
#int_timer0 // Timer0 kesmesi
void Timer0_kesmesi () // Kesme fonksiyonu ismi
{
  if(tim_syc>100)
  {
    devir=(get_timer1()/20)*60;
    set_timer1(0);
    tim_syc=0;
  }
  output_toggle(pin_d0);
  tim_syc++;
  set_timer0(99); // TM0 değeri belirleniyor
}

void main()
{
   set_tris_a(0x01);
   set_tris_b(0x00);
   set_tris_c(0x01);
   set_tris_d(0x00);
   set_tris_e(0x07);
   output_a(0x00);
   output_b(0x00);
   output_c(0x00);
   output_d(0x00);
   output_e(0x00);
   
   setup_adc(ADC_CLOCK_DIV_32);
   setup_adc_ports(AN0);
   setup_ccp1(CCP_PWM);
   setup_ccp2(CCP_OFF);
   setup_spi(SPI_DISABLED);
   setup_timer_0(T0_INTERNAl | T0_DIV_64 );
   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1);
   setup_timer_2(T2_DIV_BY_4,24,1);
   enable_interrupts(INT_timer0);
   enable_interrupts(GLOBAL); 
   set_timer0(99);
   set_timer1(0);
   set_pwm1_duty((unsigned int16)50);
   
   lcd_init();
   lcd_gotoxy(1,1);
   printf(lcd_putc,"Test");
   lcd_gotoxy(1,2);
   printf(lcd_putc,"Devir=%4ld",devir);
   
   while(TRUE)
   {
      //TODO: User Code
   }

}

aliveli


Mucit23

Bir konuda sıkıntım var.

CCS C de pointer'lerin yapısını bir türlü anlayamadım. C deki pointer yapısını biliyorum ama CCS C bana bu konuda kök söktürüyor.

128x64 Grafik LCD ye Resim basmaya çalışıyorum.
Resim datalarını aşağıdaki gibi bir dizide tutuyorum.
  const unsigned char  Resim[1024]={
      0XFF,0XFF,0X7F,0XBF,0X5F,0XAF,0X57,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
      0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
      0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
      0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
      0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
      0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
      0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
      0X55,0XAB,0X55,...........................................


Bu diziyi aşağıdaki yazdığım fonksiyona göndermem gerekiyor.
void glcd_write_image(unsigned char img_data[]){
   unsigned int Xaxis=0,Yaxis=0;
   
     for(Yaxis=0;Yaxis<8;Yaxis++)
     {
       for (Xaxis=0;Xaxis<128;Xaxis++)
       {
         glcd_write(Yaxis,Xaxis, img_data[((unsigned int16)Yaxis*128)+Xaxis]);
       }
     }  
}


Yazdığım fonksiyonun kullanım şeklide böyle
glcd_write_image(&Resim);
Derlemede sıkıntı yok ama çalışmıyor kodum. Yani ekranda saçma iki kutucuktan başka birşey görünmüyor. Üstelik aynı yapıyı yine grafik LCD için keilde kullanabiliyorum. Resim basma rutinlerinde sıkıntı yok. Tek sıkıntı diziyi fonksiyona göndermekte.
Geçen sene P10 panellerle uğraşırkende bu konuda çok başım ağrımıştı

Yukarıda yanlış yaptığım birşey varmı. Doğrusu nasıl olmalı bu işin? Bu konuyu acilen çözmem gerekiyor.

Mucit23

#199
Arkadaşlar konuyu hala çözemedim.

Ccs c de fonksiyona dizi gönderemiyorum. Su pointer ların nasıl çalıştığını anlayamıyorum.

String kütüphanelerinin içerisinde her yerde pointer kullanılıyor.  Aynı yapıları bile düzgün çalıştıramıyorum.  >:(

Bana fonksiyona dizi gonderme ile ilgili bir örnek gösterirmisiniz.

baran123

@Mucit23 hocam bu link işinizi görebilir fonksiyonlarla da örnekler ve açıklamalar var.Bir bakın derim ben de bu konuyu anlamadım hala uğraşıyorum.Kolay gelsin.

http://www.kadirga.k12.tr/egitim/c_programlama/ders.php-id=10.htm


Mucit23

Aynı şeyler bendeki kitaplardada anlatılıyor.  Konuyu biliyorum fakat nedense bir türlü olmuyor.  Dedigim gibi bir örnek olsa süper olacak.
Örnek verebilecek kimse yokmu?

RaMu

#202
glcd_write(Yaxis,Xaxis, img_data[((unsigned int16)Yaxis*128)+Xaxis]);

yerine

glcd_write(Yaxis,Xaxis, Resim[((unsigned int16)Yaxis*128)+Xaxis]);

img_data yerine Resim yazarak deneyebilir misin?
Birde tam kod ve isis simülasyonu varsa paylaşırsan bende deneyip yazabilirim,
kodların sadece glcd ile ilgili olan kısımlarıda yeterli olur.



Birde glcd ye resim basmak için glcd_pixel( a,b, ON );
pixel on off komutunu kullanmak gerekebilir,
örnek; https://www.picproje.org/index.php/topic,44032.15.html

Buradaki mucit23 sen misin hocam?
https://320volt.com/i2c-eeprom-kullanarak-128x64-glcdye-resim-basma/

Ben glcd ye resim basma uygulaması yapmıştım ama asm kullanmıştım,
sonuçta pixel on of kullanmak zorunda olduğum için benim yöntem pixel ile yapmaktı.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

ahmets

void glcd_write_image(const unsigned char img_data[]){

veya
void glcd_write_image(const unsigned char* img_data){
yazmayi dener misin.

Mucit23

@Ramu

Evet o linkteki yazıyı yazan benim, Biraz abes bir durum gibi ama ozaman protonla yapıyordum. Protonda zaten pointer meseleleri yok.

Her bir resmi basmak için aşağıdaki kodları kullanıyordum
     for(Yaxis=0;Yaxis<8;Yaxis++)
     {
       for (Xaxis=0;Xaxis<128;Xaxis++)
       {
         glcd_write(Yaxis,Xaxis, img_data[((unsigned int16)Yaxis*128)+Xaxis]);
       }
     } 

Yukarıdaki rutinler çalışıyor. Yani bu kodları mainde çalıştırıp img_data yerine Resim yazsam dizi içerisindeki datalar sorunsuz bir şekilde LCD de görüntüleniyor.

Yani anlayacağınız benim GLCD ye resim basmakta sıkıntım yok. Sıkıntı bu iş için hazırladığım bir fonksiyona boyutu belli bir dizi yollamakta. Bunu beceremiyorum.

@ahmets, Denedim fark eden birşey olmuyor malesef.

ahmets

Uzun zamandır CCS C kullanmadım, hatırlamıyorum. const yazman diziyi rom'da tanımlamak için değil mi?

http://www.ccsinfo.com/forum/viewtopic.php?t=45132
Bu adreste rom keyword'ü kullanarak V4.119 için çalışan bir örnek var.
#include <16F1824.h> 
#fuses INTRC_IO,NOWDT 
#use delay(clock=4000000) 
#use rs232(baud=9600, UART1, ERRORS) 

char rom version[] = "PRODUCT ID V1.01"; 
char rom *ptr; 

void display_string(rom *str) 
{ 
   printf("%s \r", str); 
} 

//===================== 
void main() 
{ 
   ptr = version; 

   printf("ptr = %lx \r", ptr); 

   display_string(version); 
   display_string(ptr); 
    
   while(1); 
}

Mucit23

Sizin kodları denemedim henüz. Sabah bakayım artık.

Bu arada ben bir iki deneme yaptım.

Biri pointer diğer 3 elemanlı bir dizi olmak üzere iki adet char tipi değişken tanımladım

   unsigned char *p;
   unsigned char i[3]={25,30,78};

Sonra i dizisinin adresinin p pointerine kopyaladım.
  p=(char *)&i;

Sonra P pointerinin değerlerine bakıyorum. 

P[0]=25
P[1]=30
P[2]=78

Hiçbir sıkıntı yok.

Ama mesela 1024 elemanlı Resim dizisinin adresini p pointerine kopyalıyorum aynı şekilde

  p=(char *)&Resim;

Dizinin içeriği aşağıdaki gibi

  const unsigned char  Resim[1024]={
      0XFF,0XFF,0X7F,0XBF,0X5F,0XAF,0X57,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,0XAB,
      0X55,0XAB,0X55,0XAB,0X55,0XAB,0X55,........................................

Sonuç olarak yine p pointerinin sırayla değerlerine bakıyorum

p[0]=0x00
p[1]=0x00
p[2]=0x00
p[3]=0x00
       .
       .
       .

Yanlış birşeyler var. Çünkü Resim Dizisinin ilk iki elemanı 0xFF, 3. eleman 0x7F, 4. 0xBF şeklinde gidiyor. İşte burada gelip takılıyorum.

Henüz fonksiyona dizi göndermeye çalışmıyorum bu dediklerimin hepsi main içerisinde gerçekleşiyor. Sadece Resim dizisi ayrıca bir c dosyası içerisinde. Bunuda main programına include etmişim. Çözemedim meseleyi ??? ???

Acaba Resim dizisi Const olmasındamı kaynaklanıyor? Yardım ederseniz sevinirim.

RaMu

Alıntı YapDerlemede sıkıntı yok ama çalışmıyor kodum. Yani ekranda saçma iki kutucuktan başka birşey görünmüyor.

Hocam şimdi senin kod ccs c de sıkıntısız resim basabiliyor mu basamıyor mu?
Yani bu sorunu çözdün mü?
Birde glcd_write fonksiyonunuda sen yazdın sanırım,
verdiğin kodda bu kısmın nasıl çalıştığını göremiyoruz.

Sorun artık sadece pointer ise
maalesef o konuda benimde kafam karışıyor,
pointer ı tek kullanabildiğim dil asm oldu.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Mucit23

#208
Hocam yok basabiliyorum elbette. Benim resim basmada hiçbir zaman sıkıntım olmadı. O dediğim kutucuklar pointer üzerinden resim basarsam gerçekleşiyor. Resim basma rutinlerinde direk dizi'yi kullanırsam resim basmada problem olmuyor. Zaten glcd_write fonksiyonunuda ben yazdım. Çalışması protondaki glcd write fonksiyonuyla aynı
İçeriği böyle
void glcd_write(unsigned int Ypos, unsigned int Xpos, unsigned int Data)
#ifdef FAST_GLCD
{
   int16  temp=(unsigned int16)Ypos*64;
  
   if(Xpos>63)
   {
     displayData.Right[temp+(Xpos-64)]=Data;
   }
   else
   {
      displayData.Left[temp+Xpos]=Data;
   }
}
#else
{
  output_low(GLCD_DI);                            // Set for instruction
  if(Xpos<64)
  {
      glcd_writeByte(GLCD_LEFT, Xpos | 0x40);     // Set horizontal address to 0
  }
  else
  {
      glcd_writeByte(GLCD_RIGHT, Xpos | 0x40);     // Set horizontal address to 0
  }
  
  glcd_writeByte(GLCD_LEFT, Ypos | 0xB8);   // Set page address
  glcd_writeByte(GLCD_RIGHT, Ypos | 0xB8);
  output_high(GLCD_DI);                     // Set for data
  
  if(Xpos<64)
  {
     glcd_writeByte(GLCD_LEFT,Data);
  }
  else
  {
    glcd_writeByte(GLCD_RIGHT,Data);
  }
}
#endif 


Benim şuanda iki problemim var

1-) Uzun boyutlu bir diziyi başka bir pointer'a kopyalamak. (Sanırım temel problem bu)
2-) Fonksiyona dizi göndermek.

Tahminimce 1. sorunu çözersem 2. problemde kendiliğinden çözülecek.

Sizce problem ne olabilir?

Edit;

@ahmets, sizin mesajınızda anlatılan rom yazma yönteminide denedim. Tanımladığım dizileri aşağıdaki gibi yaptım

   unsigned char rom *p;
   unsigned char rom i[3]={25,30,78};

Değişen birşey yok, i dizisindeki değerleri p pointeri üzerinden alabiliyorum . Aslında problemi buldum.

Bundan önceki mesajımıda 3 elemanlı bir i dizisi tanımlamıştım.

unsigned char i[3]={25,30,78};

Bu dizi bu şekilde MCU'nun Ram'inde yer kaplar. Ama ben başına Const ekleyince (Resim dizisinde olduğu gibi), Dizi program hafızasına gömülür. Ben yukarıdaki i dizisini const türünden tanımlayınca yine 0x00 alıyorum hep. Demekki Resim dizisi const türünden olduğu için bu sorunlar yaşanıyor.

Const dizileri kopyalamakta neden sıkıntı yaşanıyor olabilir. Dizinin program hafızasına yazılması ne gibi bir problem yaratıyor olabilir?

ahmets

Const dizi tanımlama ile rom keyword'u CCS'de ayni şeyi yapıyor galiba.

Hangi işlemci için kod yazıyorsun?
Bu işlemcide page boyu ne kadar?
Derleyici versiyonun ne?

"Uzun boyutlu bir diziyi başka bir pointer'a kopyalamak" demişsin, ROM'dan ROM'a kopyalamaya çalışıyorsan olmaz. ROM, sadece okunabilir anlamına geliyor, işlemciyi programlarken yazılıyor. Const ile tanımladığın diziyi const olmayan bir diziye kopyalayabilirsin.

Derleyici yapamayacağın bazı şeylere uyarı vermeli. CCS C uyarı vermeyip hatalı kod üretiyor olabilir.
Fazlalıkları çıkararak sadece dizini tanımlayıp adresini kopyalayıp ilk üç değerini yazdırdığın kodu kullan. Bu kod için derleyiciye asm kod ürettirip bak bakalım, dizi için PCLATH değerlerini doğru set ediyor mu? Dizi bir page içinde mi yoksa daha geniş bir alana mı yayılmış ve doğru kullanılıyor mu?