Haberler:

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

Ana Menü

CCS C string sorunu!

Başlatan Lenin, 03 Kasım 2017, 22:13:46

Lenin

Merhabalar.. rs232 üzerinden string olarak kirmizi, yeşil ve mavi değerlerini alıyorum. Kesmeyede giriyor çıkıyor düzgün bir biçimde ve gelen veriyi tekrar rs232 üzerinden yollayıp veriyi kontrol edebiliyorum. Yani giden gelen veri doğru gözüküyor. Fakat kesme içindeki if'lerin içine girmiyor ledleri yakamıyorum. Sorun ne olabilir?
#include <led.h>

#include <input.c>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char gelen[10];
/*
char renk1[]="kirmizi";
char renk2[]="yesil";
char renk3[]="mavi";
char islem[]="sondur";
*/
#INT_RDA
void  RDA_isr(void) 
{
   fscanf(mavidis,"\f%s",gelen);
      if(gelen=="kirmizi")
      {
         output_high(ledr);
         output_low(ledg);
         output_low(ledb);
      }
      if(gelen=="yesil")
      {
         output_low(ledr);
         output_high(ledg);
         output_low(ledb);
      }
      if(gelen=="mavi")
      {
         output_low(ledr);
         output_low(ledg);
         output_high(ledb);
      }
      output_toggle(kesme);
      fprintf(mavidis,"%s\r\n",gelen);
}

#INT_TIMER1
void  TIMER1_isr(void) 
{
   output_toggle(dongu);
}

void main()
{
   //setup_wdt(WDT_ON);
   //setup_wdt(WDT_576MS);      //~576 ms reset

   setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);      //131 ms overflow

   output_b(0x00);
   enable_interrupts(INT_RDA);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
      //restart_wdt();
   }

}


Ayrıca böyle if içinde karşılaştırma komutu ile kullandığım zaman çalışıyor.

#include <led.h>

#include <input.c>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

char gelen[10];

char renk1[]="kirmizi";
char renk2[]="yesil";
char renk3[]="mavi";
char islem[]="sondur";

#INT_RDA
void  RDA_isr(void) 
{
   fscanf(mavidis,"\f%s",gelen);
      if(!strcmp(gelen,renk1))
      {
         output_high(ledr);
         output_low(ledg);
         output_low(ledb);
      }
      if(!strcmp(gelen,renk2))
      {
         output_low(ledr);
         output_high(ledg);
         output_low(ledb);
      }
      if(!strcmp(gelen,renk3))
      {
         output_low(ledr);
         output_low(ledg);
         output_high(ledb);
      }
      if(!strcmp(gelen,islem))
      {
         output_low(ledr);
         output_low(ledg);
         output_low(ledb);
      }
      output_toggle(kesme);
      fprintf(mavidis,"%s\r\n",gelen);
}

#INT_TIMER1
void  TIMER1_isr(void) 
{
   output_toggle(dongu);
}

void main()
{
   //setup_wdt(WDT_ON);
   //setup_wdt(WDT_576MS);      //~576 ms reset

   setup_timer_1(T1_INTERNAL|T1_DIV_BY_2);      //131 ms overflow

   output_b(0x00);
   enable_interrupts(INT_RDA);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);

   while(TRUE)
   {
      //restart_wdt();
   }

}

sifirzero

Ledlerde zaman kullansan yanip yanmadigini gör istersen delay_ms(500);
sifirzero.blogspot.com [email]sifirrzero@gmail.com[/email] iman hem nurdur hem kuvvettir

vitruvius

Sorun temel C bilgisi. string dedigin sey C dilinde nedir?

sifirzero

Char harf tir. String kelime dir.
sifirzero.blogspot.com [email]sifirrzero@gmail.com[/email] iman hem nurdur hem kuvvettir

Lenin

2. Gosterdegim kodda zaman olmamasına rağmen ledler yanıp sönüyor. Kitapda incelediğimde string ifadeler karakter grubu seklinde gösterilmiş. Örneğin char veri[]:"ccs" şeklinde bende gelen veriyi aynı şekilde alıyorum ama if de şartı saglamiyor.

Lenin

Alıntı yapılan: serkancetin - 04 Kasım 2017, 13:09:02
Ledlerde zaman kullansan yanip yanmadigini gör istersen delay_ms(500);

İkinci yazdığım kodda da bekleme yok ama ledlerin yanıp yanmadigini görebiliyorum.

Lenin

Alıntı yapılan: vitruvius - 04 Kasım 2017, 14:10:55
Sorun temel C bilgisi. string dedigin sey C dilinde nedir?

Kitapda string ifadeleri karakter grubuyla ifade etmiş. Mesela char veri[]:"kirmizi" gibi.

vitruvius

#7
Alıntı yapılan: Schutzengel - 04 Kasım 2017, 17:42:14
Kitapda string ifadeleri karakter grubuyla ifade etmiş. Mesela char veri[]:"kirmizi" gibi.

Guzel. Az daha detay vermek gerekirse string dedigin NULL karakteri ile biten tek boyutlu char dizisidir.

Mesela asagidaki ornege bakalim:

#include <stdio.h>

int main()
{
  char myStr1[] = "Merhaba";
  char myStr2[8] = {'M', 'e', 'r', 'h', 'a', 'b', 'a', '\0'};
  char myStr3[7] = {'M', 'e', 'r', 'h', 'a', 'b', 'a'};

  printf("myStr1: %s\n", myStr1);
  printf("myStr2: %s\n", myStr2);
  printf("myStr3: %s\n", myStr3);

  return 0;
}


myStr1: Merhaba
myStr2: Merhaba
myStr3: Merhaba


Burada bir sey demem lazim: myStr3 char dizisini NULL karakteri ile bitirmedim ama o da "Merhaba" yazdi. O zaman neden NULL karakteri ile bitiriyoruz diye dusunebilirsin. Eger NULL ile bitirmezsen "Undefined behavior" yani tanimsiz bir davranis olur ve programin ne yapacagini tahmin edemezsin. Evet bu sefer "Merhaba" yazdi ama bu her defasinda "Merhaba" yazacak anlamina gelmez. Ya da printf yerine baska fonksiyonlarda kullanirsan bu degiskeni (strcpy() gibi) sorun yasarsin.

Bir de string'in hafizada nasil saklandigina bakmak lazim.

Index  |    0   |    1   |    2    |    3   |    4    |    5   |    6   |    7    |
Deger  |   M   |    e    |    r    |    h   |    a    |    b   |    a   |   \0   |
Adres  | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 |

Gibi. Yani "string = kelime" diye dusunmemek lazim. Mesajimin en basinda dedigim gibi NULL ile biten bir karakter dizisidir.

Bu hafizada saklama olayi onemli. Ona bir sonraki mesajimda gelecegim :) Ama once baska bir soruya daha bakmak lazim hatanin nedenini anlamak icin. O soru da su: "Dizi" dedigin sey C dilinde nedir?

Lenin

Alıntı yapılan: vitruvius - 04 Kasım 2017, 22:47:50
Guzel. Az daha detay vermek gerekirse string dedigin NULL karakteri ile biten tek boyutlu char dizisidir.

Mesela asagidaki ornege bakalim:

#include <stdio.h>

int main()
{
  char myStr1[] = "Merhaba";
  char myStr2[8] = {'M', 'e', 'r', 'h', 'a', 'b', 'a', '\0'};
  char myStr3[7] = {'M', 'e', 'r', 'h', 'a', 'b', 'a'};

  printf("myStr1: %s\n", myStr1);
  printf("myStr2: %s\n", myStr2);
  printf("myStr3: %s\n", myStr3);

  return 0;
}


myStr1: Merhaba
myStr2: Merhaba
myStr3: Merhaba


Burada bir sey demem lazim: myStr3 char dizisini NULL karakteri ile bitirmedim ama o da "Merhaba" yazdi. O zaman neden NULL karakteri ile bitiriyoruz diye dusunebilirsin. Eger NULL ile bitirmezsen "Undefined behavior" yani tanimsiz bir davranis olur ve programin ne yapacagini tahmin edemezsin. Evet bu sefer "Merhaba" yazdi ama bu her defasinda "Merhaba" yazacak anlamina gelmez. Ya da printf yerine baska fonksiyonlarda kullanirsan bu degiskeni (strcpy() gibi) sorun yasarsin.

Bir de string'in hafizada nasil saklandigina bakmak lazim.

Index  |    0   |    1   |    2    |    3   |    4    |    5   |    6   |    7    |
Deger  |   M   |    e    |    r    |    h   |    a    |    b   |    a   |   \0   |
Adres  | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 |

Gibi. Yani "string = kelime" diye dusunmemek lazim. Mesajimin en basinda dedigim gibi NULL ile biten bir karakter dizisidir.

Bu hafizada saklama olayi onemli. Ona bir sonraki mesajimda gelecegim :) Ama once baska bir soruya daha bakmak lazim hatanin nedenini anlamak icin. O soru da su: "Dizi" dedigin sey C dilinde nedir?

Dizi c dilinde bellekte ayrılan paketler değil midir?  Verdiğim örnekte scanf kullanarak gelen ifadeyi string ifadeye çevirdim. CCS C nin index kısmında yazıyordu. Sonra strcmp yaparak 2 adet string ifadeyi karşılaştırdığımda if şartını sağladı.

vitruvius

Oncelikle gec cevabim icin ozur dilerim. Gelen maili kacirmisim heralde.

Konu daha fazla uzamasin diye bu mesajda sonuca gidecegim. Zaten demek istediklerimi onceki mesajlarimda soylemistim bu mesajimin bitirici nitelekte olacagini dusundugum icin. Belki senin icin net olmayan bir kisim olabilir o da "pointer"lardir. Eger "pointer"lar hakkinda cok bilgin yoksa arastirmani oneririm zira ilerde cokca karsilasirsin.

Kisaca bir tanim yapmak gerekirse pointer dedigin sey bir degiskenin hafizadaki adresini tutan baska bir degiskendir.

Dizinin tanimi senin de dedigin gibi ama ufak bir puf noktasi var. Eger ki diziyi yalnizca ismi ile kullanirsan, dizinin ilk elemanina constant pointer atamis olursun. Demek istedigimi ufak bir ornekle gostermem gerekirse:

#include <stdio.h>

int main()
{
  char myStr[] = "Merhaba";

  char * pArray = myStr; // Dizi ismini kullanarak bir pointer tanimliyorum

  printf("pArray: %c\n", *pArray);
  return 0;
}


Bu kodun ciktisi asagidaki gibidir:
pArray: M


Cunku yukarda dedigim gibi tanimladigin diziyi yalnizca ismi ile kullanirsan bu "Dizinin ilk elemaninin adresini isaret eder". Mesela burdan yola cikarak dizinin ucuncu elemanini yazdirmak istiyorsan kodda ilgili yeri asagidaki gibi degistirip programi calistirabilirsin.

printf("pArray: %c\n", * (pArray + 2)); // pArray dizinin ilk elemanini gosteriyor. Iki eleman daha ilerlersek dizinin ucuncu elemanina ulasiriz.


Program ciktisi:
pArray: r


Tekrar ediyorum diziyi yalnizca ismi ile kullanirsan elinde dizinin ilk elemanini isaret eden bir pointer yani hafizadaki bir adres olur.

Senin ilk kodundaki sorun bu.

if(gelen=="kirmizi")


Burada "gelen" hafizadaki bir alani isaret eden bir pointer'dan baska bir sey degil. Bu karsilastirmanin baktigi sey acaba "gelen" ve "kirmizi" hafizada ayni bolgeye mi isaret ediyorlar sorusu. Degiskenlerin icerikleri bakmaz.

Bu yuzden string karsilastirirken strcmp() kullanmalisin.

Umarim aciklayici olmustur. Olmadiysa sorularini bekliyorum :) Kolay gelsin.

Lenin

İlk olarak sorun üzerine uğrastiginiz için çok teşekkür ederim. Dediğiniz gibi string ifadeler ccs c kendi örneklerinde bile pointer cinsinden almış. Ufkumu açtığınız için teşekkür ederim. İyi günler dilerim.

fide

Merhaba.
Seri porttan gelen veriyi xctu gibi yada ascii kodlarıyla beraber takip edebileceğin bir programla takip etöeni öneririm. Gelen veri ardında chr13 chr10 (enter, line feed) yada boşluk gibi bir karakter daha geliyor olabilir.
Diğer taraftan interrupt içinde özellikle bekleme ve karşılaştırma yapma. Hem gecikmeye hem de gelen verinin alınmamasına sebep olur. İnt içinde bir değişkeni 1 yap. Ana prg bloğu içinde de bu değişkenin 1 olup olmadığını sorgula. Eğer 1 ise karşılaştırma işlemine başla ve sonunda int içinde set ettiğin değişkeni sıfırla ki bir sonraki interruptta yine kontrol sağlayasın.
Diğer bir konu, renk gibi değişmeyecek olanları const olarak tanımla ramden yemesin.
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

Lenin

Merhabalar. Cevabınız için teşekkür ederim. Dediklerinizi uygulamaya çalışacağım. İyi çalışmalar dilerim.

gokhangokcen

Merhabalar, benimde benzer bir sorum olacağı için farklı konu açmak istemedim. Yukarıdaki örnekleri inceledim fakat sonuca varamadım. Benim takıldığım nokta ise şöyle;

int16 hold_regs[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
char *data[];

sprintf(data,"%ld%ld%ld%ld",hold_regs[0],hold_regs[1],hold_regs[2],hold_regs[3]);


16bit hold_regs adında değişkenlerim var 8 adet , bunları tek bir string olarak birleştirmek istiyorum. Bu şekildemi yapılıyor emin olamadım. Başka şekli varmıdır? Böyle yapılırsa sorun oluşur mu?
Bildiğini paylaşmak, Allah'ın verdiği öğrenme yeteneğinin zekatıdır.

vitruvius

Alıntı yapılan: gokhangokcen - 17 Kasım 2017, 09:43:41
Merhabalar, benimde benzer bir sorum olacağı için farklı konu açmak istemedim. Yukarıdaki örnekleri inceledim fakat sonuca varamadım. Benim takıldığım nokta ise şöyle;

int16 hold_regs[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
char *data[];

sprintf(data,"%ld%ld%ld%ld",hold_regs[0],hold_regs[1],hold_regs[2],hold_regs[3]);


16bit hold_regs adında değişkenlerim var 8 adet , bunları tek bir string olarak birleştirmek istiyorum. Bu şekildemi yapılıyor emin olamadım. Başka şekli varmıdır? Böyle yapılırsa sorun oluşur mu?

sprintf() ya da snprintf() olur evet, bir sakinca yok.