Rs232 gelen verinin kayması sorunu

Başlatan ziyaretci, 06 Şubat 2017, 08:22:42

ziyaretci

Merhaba, bir uygulamamda 2 pic arası(16f877,18f452) usart ile iletişim sağlıyorum.

-- 16f877'den belirsiz aralıklarda 18f452'ye veri geliyor.

Sorunum şu; eğer tek tek veri gönderirsem(250ms) 18f452'ye sorun yok gayet güzel alıyorum. Fakat printf("%Lu",x), şeklinde belirsiz zamanlı veri gönderirsem, 18f452 ilk veriyi düzgün alıyor, diğer verileri 2 basamak sağa kaydırarak alıyor. Verim 7 basamaklı bir sayı.

Örneğin; gönderdiğim veri "1234567" olsun.

  1- Rda kesmesinden ilk veri alımı sonucu => "1234567"
  2- Rda kesmesinden ikinci veri alımı sonucu => "3456712"
  3- ve sonrası yine =>"3456712"

#use komutunda errors kullanmazsam zaten 1 tane alıyor tıkanıyor. Bende şimdilik çözümü  dizi elemanlarının yerini değiştirerek yapıyorum biraz gülünç ama elde çare yok.

ALICI TARAF KOD:
  
#use rs232(baud=19200,xmit=pin_c6,rcv=pin_C7,parity=N,stop=1,ERRORS)
char gelen_agirlik[7]; 

#int_rda
Void arayuz(){
disable_interrupts(int_rda);
clear_interrupt(int_rda);
kesme_durumu=1;

}

Void main(){

for(;;){
//eğer veriyi ana döngüde almazsam yukarıda bahsettiğim kaydırılmış veri okuma kararlılığınıda alamıyorum.
if(kesme_durumu==1){
t=0;
while(t<7){gelen_agirlik[t]=getc(); t++;}
glcd_rect(0,12,63,23,yes,off);
sprintf(KARAKTER_BAS,"%c%c%c%c%c%c%c",GELEN_AGIRLIK[2],GELEN_AGIRLIK[3],
GELEN_AGIRLIK[4],GELEN_AGIRLIK[5],GELEN_AGIRLIK[6],GELEN_AGIRLIK[0],GELEN_AGIRLIK[1]);
glcd_text57(5,12,KARAKTER_BAS,1,ON);
enable_interrupts(int_rda); kesme_durumu=0;
  
  }

 }
}

ziyaretci

Ek 1:

16F877 20MHz, 18F452 40MHz de çalışıyor.

sadogan

Merhaba,
Sorun bence gönderen mcu nun başlangıcını yakalıyamıyorsunuz.
Son 2 karekter de aslında,sonraki dizinin elemanları.

kantirici


JKramer

Alıntı yapılan: erkantr67 - 06 Şubat 2017, 08:22:42
#use komutunda errors kullanmazsam zaten 1 tane alıyor tıkanıyor.
Okuyamadan yenisi geldiğinden tıkanıyor. Bakarsanız overrun bit'i de set edilmiştir.

ziyaretci

Alıntı yapılan: sadogan - 06 Şubat 2017, 09:18:09
Merhaba,
Sorun bence gönderen mcu nun başlangıcını yakalıyamıyorsunuz.
Son 2 karekter de aslında,sonraki dizinin elemanları.



Evet %90 galiba dediğiniz gibi. Nasıl çözerim bu durumu? İletişim hızını 4800 yaptım yine aynı.

Alıntı yapılan: JKramer - 06 Şubat 2017, 09:53:01
Okuyamadan yenisi geldiğinden tıkanıyor. Bakarsanız overrun bit'i de set edilmiştir.

Evet. Rx ucuna 1k ile pull-up yapmam değiştirir mi durumu?

Önereceğiniz çözümler nedir?  İletişim protokolünü şuan değiştirmem olanaksız.

ziyaretci

#6
Alıntı Yap15 dakikaya 18f452'nin kristalini 20MHz'ye düşüreceğim. Birde öyle deneyeyim.

Değişme olmadı.

Murat Mert

gelen veri=#123456 olsun
#int_RDA
void  RDA_isr(void) 
{
   Disable_interrupts(INT_RDA);
   temp=getc();
   if(temp=='#'){i=0;}
   gelen_data1[i]=temp;
   uart_kon=1;
   i++;
   enable_interrupts(INT_RDA);
}


aklıma hızlıca gelen
mert07

JKramer

Pull up ile ilgisi yok. Çip hızıyla da ilgisi yok; zaten baud rate ile transfer hızını belirliyorsunuz. Alıcı ve göndericinin baud rate'lerinin eşit olması yeterli.

- printf kullanmayıp datayı byte byte gönderip-alacaksınız.
- En kötü ihtimalle datanın başını ve sonunu belirleyen byte'lar eklemelisiniz. Alıcı kesmesinde her gelen byte'da bunları kontrol edip durumu değiştireceksiniz. Yani normal durum, data'nın başlangıç byte(lar)ı geldikten sonra alım durumu, vs. gibi.

ziyaretci

Alıntı yapılan: Murat Mert - 06 Şubat 2017, 13:30:06
gelen veri=#123456 olsun
#int_RDA
void  RDA_isr(void) 
{
   Disable_interrupts(INT_RDA);
   temp=getc();
   if(temp=='#'){i=0;}
   gelen_data1[i]=temp;
   uart_kon=1;
   i++;
   enable_interrupts(INT_RDA);
}


aklıma hızlıca gelen

Alıntı yapılan: JKramer - 06 Şubat 2017, 13:32:57
Pull up ile ilgisi yok. Çip hızıyla da ilgisi yok; zaten baud rate ile transfer hızını belirliyorsunuz. Alıcı ve göndericinin baud rate'lerinin eşit olması yeterli.

- printf kullanmayıp datayı byte byte gönderip-alacaksınız.
- En kötü ihtimalle datanın başını ve sonunu belirleyen byte'lar eklemelisiniz. Alıcı kesmesinde her gelen byte'da bunları kontrol edip durumu değiştireceksiniz. Yani normal durum, data'nın başlangıç byte(lar)ı geldikten sonra alım durumu, vs. gibi.


Allah razı olsun. Sorun çözüldü.

#int_rda
Void arayuz(){
disable_interrupts(int_rda);

   temp=getc();
   if(temp=='#'){
    for(l=0;l<6;l++){
   gelen_agirlik[l]=getc();
   
   }
  }
 
  
   
enable_interrupts(INT_RDA);
}

Murat Mert

#10
Amin cümlemize. İşinize yaradığına sevindim. Ama doğrulama koysanız daha iyi olur. Ara sıra yine şaşabilir.
mert07

dursuncemal

haberlesmenin her iki kiisminida siz yaziyor iseniz dogrulama koymak her zaman sorunlari minimuma indirir.
:=