Haberler:

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

Ana Menü

<CR> <LF> string sorunu

Başlatan isa_olcer, 09 Şubat 2021, 21:55:41

isa_olcer

gets() komutu ile ölçüm cihazının RS232 çıkışından veri almaya çalışıyorum. Cihaz gönderdiği bilginin sonuna <CR><LF> (0D 0A) karakteri ekliyor. Normalde bilgisayardan denediğimde sadece CR gönderince sorunsuz çalışıyor. Fakat cihaz en son LF de gönderince kesme kilitleniyor. Araştırdığım kadarıyla bu sorun için getc() komutuyla bilgi almak gerekiyor. Birkaç yöntem denedim ama sıralama sürekli değişiyor getc() ile düzgün bir şekilde string nasıl alabilirim?

isa_olcer

#1
Kullandığım döngü bu. Gelen karakterin sıralaması sürekli değişiyor.

#int_RDA
void RDA_isr()
{
disable_interrupts(int_rda);
   char c;
   c=getc();
   bilgi[index++] = c;  // store data
      if (index>=MAX_BUFFER) // Got all the data
      {
        index=0;
       }
    }


#define MAX_BUFFER 13
char bilgi[MAX_BUFFER];
int8 index=0;
int Data[6];

void display()
{              
   Data[0]=digit[((bilgi[2])-32)];
   Data[1]=digit[((bilgi[3])-32)];
   Data[2]=digit[((bilgi[4])-32)];
   Data[3]=digit[((bilgi[5])-32)];
   Data[4]=digit[((bilgi[6])-32)];
   Data[5]=digit[((bilgi[7])-32)];  
   write_expanded_outputs(Data); //Bilgi 74HC595'e gönderiliyor
} 

#int_RDA
void RDA_isr()
{
disable_interrupts(int_rda);
   char c;
   c=getc();
   bilgi[index++] = c;  // store data
      if (index>=MAX_BUFFER) // Got all the data
      {
        index=0;
       }
    }

void main()
{
set_tris_a(0x00);
set_tris_b(0b00000010);
bilgi[2]="1";  // test
bilgi[3]="2";
bilgi[4]="3";
bilgi[5]="4";
bilgi[6]="5";
bilgi[7]="6";
enable_interrupts(GLOBAL);  // Aktif edilen tüm kesmelere izin ver 

while(TRUE)     
  {
  display();
  clear_interrupt(int_rda);    
  enable_interrupts(int_rda); // int_rda kesmesi aktif 
  }            
}

Murat Mert

#define MAX_BUFFER 13
char bilgi[MAX_BUFFER];
int8 index=0;
int Data[6];

void display()
{              
   Data[0]=digit[((bilgi[2])-32)];
   Data[1]=digit[((bilgi[3])-32)];
   Data[2]=digit[((bilgi[4])-32)];
   Data[3]=digit[((bilgi[5])-32)];
   Data[4]=digit[((bilgi[6])-32)];
   Data[5]=digit[((bilgi[7])-32)];  
   write_expanded_outputs(Data); //Bilgi 74HC595'e gönderiliyor
} 

#int_RDA
void RDA_isr()
{
disable_interrupts(int_rda);
   char c;
   c=getc();
   bilgi[index++] = c;  // store data
      if (index>=MAX_BUFFER) // Got all the data
      {
        index=0;
        clear_interrupt(int_rda); 
       }
      enable_interrupts(int_rda); // int_rda kesmesi aktif 
    }

void main()
{
set_tris_a(0x00);
set_tris_b(0b00000010);
bilgi[2]="1";  // test
bilgi[3]="2";
bilgi[4]="3";
bilgi[5]="4";
bilgi[6]="5";
bilgi[7]="6";
enable_interrupts(GLOBAL);  // Aktif edilen tüm kesmelere izin ver 

while(TRUE)     
  {
  display();
     

  }            
}

Böyle uygulamak bile sıkıntı. Rx kesmenin yani gelen dataların bittiğini algılaman lazım ama verinin sonunu bildiren bir işaretciyle yada rx bufferin almasının ardından zamanla kontrol ederek.
mert07

fide

#3
şunu deneseniz?

#int_RDA
char bilgi[50];

void RDA_isr()
{
disable_interrupts(int_rda);
char c=0;

for (i=0;i<50;i++)
{
   bilgi[i]=0;
}   
   i=0;
while(c!=10)
{
c=getc();
bilgi[i]=c;
i++;

}
bilgi[i]=0;

}

bu kodu kullanmak tehlikelidir. Çünkü verinin sonunda lf(0A) gelmezse döngüden çıkamaz. Ama lf kesin geliyorsa gelene kadar veriyi alır. 50 değerini buffer ile değiştirin.
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

mufitsozen

Alıntı yapılan: Murat Mert - 12 Şubat 2021, 21:10:50
#define MAX_BUFFER 13
char bilgi[MAX_BUFFER];
int8 index=0;
int Data[6];

void display()
{              
   Data[0]=digit[((bilgi[2])-32)];
   Data[1]=digit[((bilgi[3])-32)];
   Data[2]=digit[((bilgi[4])-32)];
   Data[3]=digit[((bilgi[5])-32)];
   Data[4]=digit[((bilgi[6])-32)];
   Data[5]=digit[((bilgi[7])-32)];  
   write_expanded_outputs(Data); //Bilgi 74HC595'e gönderiliyor
} 

#int_RDA
void RDA_isr()
{
disable_interrupts(int_rda);
   char c;
   c=getc();
   bilgi[index++] = c;  // store data
      if (index>=MAX_BUFFER) // Got all the data
      {
        index=0;
        clear_interrupt(int_rda); 
       }
      enable_interrupts(int_rda); // int_rda kesmesi aktif 
    }

void main()
{
set_tris_a(0x00);
set_tris_b(0b00000010);
bilgi[2]="1";  // test
bilgi[3]="2";
bilgi[4]="3";
bilgi[5]="4";
bilgi[6]="5";
bilgi[7]="6";
enable_interrupts(GLOBAL);  // Aktif edilen tüm kesmelere izin ver 

while(TRUE)     
  {
  display();
     

  }            
}

Böyle uygulamak bile sıkıntı. Rx kesmenin yani gelen dataların bittiğini algılaman lazım ama verinin sonunu bildiren bir işaretciyle yada rx bufferin almasının ardından zamanla kontrol ederek.


disable_interrupts(int_rda);
enable_interrupts(int_rda);

Komutlari gereksiz ve tehlikeli. Bu komutlar normal programda
'critical section' icin kullanilmali.

ISR fonksiyona girerken/cikarken bu isi otomatik olarak yapiyor. Onun isleyisini bozmamak lazim.
Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

fahri-

CCS C de RS232 için timeout seçeneği var. Kullanımını araştırın. Çözüm olabilir.

isa_olcer

Cevaplar ve tavsiyeleriniz için teşekkür ederim. Bu kodla sorunu çözdüm.

#define BUFFER_SIZE 13 // gelen karakter adeti
BYTE bilgi[BUFFER_SIZE];
BYTE next_in=0;
BYTE next_out=0;
char veri[13]; // gelen verinin kayıt edileceği değişken


#INT_RDA
void  RDA_isr(void)
{
  int t;
  bilgi[next_in] = getc();
  t = next_in;
  next_in =(next_in + 1) % BUFFER_SIZE;

  if(next_in == next_out)
      next_in = t;
}
#define bkbhit (next_in!=next_out)
BYTE bgetc()
{
  BYTE c;
  while( ! bkbhit);
  c = bilgi[next_out];
  next_out =(next_out + 1) % BUFFER_SIZE;
  return(c);
}

void my_get_string(char* s)
{
  unsigned int8 len;
  char c;
  len = 0;

  do
  {
      c = bgetc();// Call bgetc()
      if((c >= ' ')&&(c <= '~'))
      {
        s[len++] = c;
        putc(c);
        
      }
  }
  while(c != 13);
  s[len] = 0;
}


while(TRUE)    
{

my_get_string(veri); // alınan değer "veri" değişkenine kaydediliyor.

}