Picproje Elektronik Sitesi

DERLEYİCİLER => CCS C => Konuyu başlatan: isa_olcer - 09 Şubat 2021, 21:55:41

Başlık: <CR> <LF> string sorunu
Gönderen: isa_olcer - 09 Şubat 2021, 21:55:41
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?
Başlık: Ynt: <CR> <LF> string sorunu
Gönderen: isa_olcer - 09 Şubat 2021, 23:47:31
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
  }           
}
Başlık: Ynt: <CR> <LF> string sorunu
Gönderen: 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.
Başlık: Ynt: <CR> <LF> string sorunu
Gönderen: fide - 12 Şubat 2021, 23:59:29
ş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.
Başlık: Ynt: <CR> <LF> string sorunu
Gönderen: mufitsozen - 13 Şubat 2021, 01:25:27
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.
Başlık: Ynt: <CR> <LF> string sorunu
Gönderen: fahri- - 13 Şubat 2021, 08:58:29
CCS C de RS232 için timeout seçeneği var. Kullanımını araştırın. Çözüm olabilir.
Başlık: Ynt: <CR> <LF> string sorunu
Gönderen: isa_olcer - 14 Şubat 2021, 00:43:27
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.

}