Haberler:

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

Ana Menü

rs232 ile haberlesme

Başlatan selvi, 30 Ekim 2013, 15:50:33

selvi

 rs232 protokulu ile cift tarafli(tranceiver) iletiismi yapmak icin verici ve alici programlari yazdim.tek traflida sorun cikmiyor.alici bilgi aldigina dair vericiye geri bildirim yaptiginda program calismiyor.simulasyonda calistirir calistirmaz vericideki led yaniyor onun disinda farkli bir islem yapmiyor.programlar asagidaki sekildedir:
 
verici:
#include <16f628a.h>     

#fuses INTRC,NOWDT,PUT,NOPROTECT,NOLVP,NOBROWNOUT

#use delay (clock=4000000) 

#use fast_io(a)
#use fast_io(b)

#define buton pin_a2
#define led   pin_a0

#use rs232 (baud=9600, xmit=pin_b2, rcv=pin_b1, parity=N, stop=1, stream=iletisim_1)                                                            

#int_rda
void rs232_kesmesi()
{
  disable_interrupts(int_rda);
  delay_us(5);
}

void main ()
{
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   set_tris_a(0b10000100);
   set_tris_b(0b00000010);
  
   output_a(0x00);
   output_b(0x02);

  enable_interrupts(GLOBAL);
 
   while(TRUE) 
   { 
     enable_interrupts(int_rda);
     if(fgetc(iletisim_1)=='b')
     {
       if(fgetc(iletisim_1)=='b')                                                                                                                                     
       {
         if(fgetc(iletisim_1)=='c')
         {
           output_high(led);delay_ms(500);output_low(led);
         }
       }
     }
     
     if (input(buton))
     {
        fputc(0x55,iletisim_1);
        fputc(0x55,iletisim_1);
        fputc(0x55,iletisim_1);
        fputc(0x55,iletisim_1);
        fputc(0x55,iletisim_1);
        
        fputc('c',iletisim_1);
        delay_ms(1);
        fputc('c',iletisim_1);
        delay_ms(1);
        fputc('s',iletisim_1);
        delay_ms(1);
        while(input(buton));
     }
   }
}


alici:
#include <16f628a.h>     

#fuses INTRC,NOWDT,PUT,NOPROTECT,NOLVP,NOBROWNOUT

#use delay (clock=4000000) 

#use fast_io(a)
#use fast_io(b)

#define led pin_b3

#use rs232 (baud=9600, xmit=pin_b2, rcv=pin_b1, parity=N, stop=1, stream=iletisim_1) 
   
int1 a=0;

#int_rda
void rs232_kesmesi()
{
  disable_interrupts(int_rda);
  delay_us(5);
}

void main ( )
{
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   set_tris_a(0b10000000);
   set_tris_b(0b00000010);
  
  output_a(0x00);
  output_b(0x00);
  
  enable_interrupts(GLOBAL);
  
   while(TRUE)
   {
     enable_interrupts(int_rda);
     
     if(a=1)
     {     
        fputc('b',iletisim_1);
        delay_ms(1);
        fputc('b',iletisim_1);
        delay_ms(1);
        fputc('c',iletisim_1);
        delay_ms(1);a=0;
     }
    
     if(fgetc(iletisim_1)=='c') 
     { 
       if(fgetc(iletisim_1)=='c') 
       {
         if(fgetc(iletisim_1)=='s')
         {
         output_high(led);delay_ms(500);output_low(led);delay_ms(500);a=1;
         }
     }
   }
}
}
Yaşam anlamlandırıldıkça kutsaldır....

esensoy

#1
kesme açmışsınız ama kesme içinde uart ı okumuyorsunuz, mantık çok fena,
aynı mcu içinde iki farklı kanal ya da ayara sahip uart kullanacaksanız stream kullanmak anlamlıdır, burada kod kalabalığı olmuş,
ben olsam şu mantıkla yazardım;
kesme içindeki koda dikkat ederseniz, her an uarttan genel son 3 data 3 lü gelen değişkeni içinde saklanmakta,
ana program içindeki while döngüsünde de bu değişkeni sürekli kontrol ediyor,
örnek teşkil etmesi açısından yazdım, eksikleri olabilir,
#include <16f628a.h>     

#fuses INTRC,NOWDT,PUT,NOPROTECT,NOLVP,NOBROWNOUT

#use delay (clock=4000000) 

#use fast_io(a)
#use fast_io(b)

#define buton pin_a2
#define led   pin_a0

#use rs232 (baud=9600, xmit=pin_b2, rcv=pin_b1, parity=N, stop=1)                                                            
char genel[3];
int i=0,j=0;
#int_rda
void rs232_kesmesi()
{
  genel[0]=genel[1];
  genel[1]=genel[2];
  genel[2]=getc();
}

void main ()
{
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   set_tris_a(0b10000100);
   set_tris_b(0b00000010);
  
   output_a(0x00);
   output_b(0x02);

  enable_interrupts(int_rda);
  enable_interrupts(GLOBAL);

   while(TRUE) 
   { 
     if(genel[0]=='b')
         if(genel[1]=='b')
              if(genel[2]==c')
              {
                 output_high(led);delay_ms(500);output_low(led);
              }
     
     if (input(buton))
     {
        for(j=0;j<5;j++)
            putc(0x55);
        printf("ccs");
        while(input(buton));
     }
   }
}

#include <16f628a.h>     

#fuses INTRC,NOWDT,PUT,NOPROTECT,NOLVP,NOBROWNOUT

#use delay (clock=4000000) 

#use fast_io(a)
#use fast_io(b)

#define led pin_b3

#use rs232 (baud=9600, xmit=pin_b2, rcv=pin_b1, parity=N, stop=1) 
   
int1 a=0;

char genel[3];
int i=0,j=0;
#int_rda
void rs232_kesmesi()
{
  genel[0]=genel[1];
  genel[1]=genel[2];
  genel[2]=getc();
}

void main ( )
{
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   set_tris_a(0b10000000);
   set_tris_b(0b00000010);
  
  output_a(0x00);
  output_b(0x00);
  enable_interrupts(int_rda);
  enable_interrupts(GLOBAL);
  
 while(TRUE)
 {
     if(genel[0]=='c')
         if(genel[1]=='c')
              if(genel[2]==s')
              {
                  for(j=0;j<5;j++)
                      putc(0x55);
                  printf("bbs");
                  output_high(led);delay_ms(500);output_low(led);delay_ms(500);a=1;
              }
}
}
En tehlikeli an "zafer" anıdır.

selvi

Alıntı Yap#int_rda
void rs232_kesmesi()
{
  genel[0]=genel[1];
  genel[1]=genel[2];
  genel[2]=getc();
}

bu kesme programindaki dizi mantigini kullanma bicimini anlayamadim.dizilerin birbirine esitleme mantigini cozemedim.mumkunse bu kesme icindeki programin aciklamasini yapabilir misiniz.birde kesme olustugunda kesmenin tekrardan olusmasi icin kesme bayraginin sifirlanmasi gerektigini biliyordum. birde yaptiginiz sekilde programi denedim calismadi.
Yaşam anlamlandırıldıkça kutsaldır....

coderun

Alıntı Yapvoid rs232_kesmesi()
{
  genel[0]=genel[1];
  genel[1]=genel[2];
  genel[2]=getc();
}

anladığım kadarıyla burada sürekli son 3 veri tutuluyor. genel[2] yeni veriyi alan dizi değişkeni. yeni veri alınıp genel[2] kaydedilmeden önce 0 1 2 dizi elemanlarının içerikleri bir sola kaydırılıyor. yani genel[1] içeriği genel[0] aktarılıyor. orta satırdaki işlem de aynı mantıkla işliyor. veriler dizi elemanları arasında sola doğru aktarıldığından sadece genel[0] içindeki veri kaybediliyor. özetle:

genel[0]    genel[1]      genel[2]
      10            11             25            dizi içinde bu veriler varken yeni gelen veri de 66 olsun.

genel[0]    genel[1]      genel[2]
    11              25              66           son durum bu şekilde olur.

(umarım doğru anlayıp doğru aktarmışımdır.)


omereliusuk

#use rs232 (baud=9600, xmit=pin_b2, rcv=pin_b1, parity=N, stop=1, stream=iletisim_1,errors)

selvi

#5
  su sekilde verici ve aliciyi duzenledim.bu sekilde de calismadi.
k yerine yanlislikla i yazmisim.duzeltim.

verici:
#include <16f628a.h>     

#fuses INTRC,NOWDT,PUT,NOPROTECT,NOLVP,NOBROWNOUT

#use delay (clock=4000000) 

#use fast_io(a)
#use fast_io(b)

#define buton pin_a2
#define led   pin_a0

#use rs232 (baud=9600, xmit=pin_b2, rcv=pin_b1, parity=N, stop=1) 
                                                                 
char genel[3];
int i=0,j=0,k=0;                                                 

#int_rda
void rs232_kesmesi()
{
  disable_interrupts(int_rda);
  for(k=0;k<3;k++)
  {
    genel[k]=getc();
    k++;
  }
}

void main ()
{
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   set_tris_a(0b10000100);
   set_tris_b(0b00000010);
  
   output_a(0x00);
   output_b(0x00);

  enable_interrupts(GLOBAL);
  enable_interrupts(int_rda);
 
 while(TRUE) 
 { 
    if(genel[0]=='b')
    {
       if(genel[1]=='b')
       {
          if(genel[2]=='c')
          {
             output_high(led);delay_ms(500);output_low(led);
          }
       }
    }
     
     if (input(buton))
     {
        for(j=0;j<5;j++) putc(0x55);
        
        for(i=0;i<5;i++) printf("ccs");
     
        while(input(buton));
     }
   }
}


alici:
#include <16f628a.h>     

#fuses INTRC,NOWDT,PUT,NOPROTECT,NOLVP,NOBROWNOUT

#use delay (clock=4000000) 

#use fast_io(a)
#use fast_io(b)

#define led pin_b3

#use rs232 (baud=9600, xmit=pin_b2, rcv=pin_b1, parity=N, stop=1) 
 
char genel[3];
int i=0,j=0,k=0,a=0;

#int_rda
void rs232_kesmesi()
{
  disable_interrupts(int_rda);
  for(k=0;k<3;k++)
  {
  genel[k]=getc();k++;
  }
}

void main ( )
{
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   set_tris_a(0b10000000);
   set_tris_b(0b00000010);
  
   output_a(0x00);
   output_b(0x00);
  
   enable_interrupts(GLOBAL);
   enable_interrupts(int_rda);
  
 while(TRUE)
 {
     if(genel[0]=='c')
     {
         if(genel[1]=='c')
         {
              if(genel[2]=='s')
              {
                output_high(led);delay_ms(500);output_low(led);delay_ms(500);a=1;
              }
         }
     }
                
                 if(a==1)
                 {
                  for(j=0;j<5;j++) putc(0x55);
                  
                  for(i=0;i<5;i++) printf("bbc");
                 }
                    
    }
 }
Yaşam anlamlandırıldıkça kutsaldır....

coderun

#6
göz ucuyla baktığımda şunu gördum:

Alıntı Yapvoid rs232_kesmesi()
{
  disable_interrupts(int_rda);
  for(k=0;k<3;k++)
  {
    genel=getc();
    i++;
  }
}

bura da i++ yapıyorsun ama i nin o kesmeye gelindiğinde kaç olduğunu biliyor musun. O kesmeye dallanıldığında belki i=8 belki de i=6.
bu yüzden ya i yerine k değişkenini kullan ya da i yi for yapısından önce sıfırla.

  disable_interrupts(int_rda);
  for(k=0;k<3;k++)
  {
    genel[k]=getc();
   
  }


ya da

  disable_interrupts(int_rda);
  i=0;
  for(k=0;k<3;k++)
  {
    genel[i]=getc();
    i++;
  }


mesaj birleştirme:: 31 Ekim 2013, 17:56:10


  genel[k]=getch(); // getc fonk. yerine getch kullanıldı.

bu şekilde yap birde..

coderun

verici kısmında aşağıdaki kodu yazmışsın.

Alıntı Yapwhile(TRUE)
{
    if(genel[0]=='b')
    {
       if(genel[1]=='b')
       {
          if(genel[2]=='c')
          {
             output_high(led);delay_ms(500);output_low(led);
          }
       }
    }
     
     if (input(buton))
     {
        for(j=0;j<5;j++) putc(0x55);
       
        for(i=0;i<5;i++) printf("ccs");
     
        while(input(buton));
     }
   }
}

1)
butona basılırsa sırasıyla 5 defa 0x55 değerini ardından da 5 defa "ccs" değerini gönderiyorsun. Toplamda 20 değer gönderiyorsun.
5 defa 0x55 değer + "ccs" 3 karakterli ve 5 defa yollanırsa 15 değer.

2)alıcı tarafında ise gelen verilerden yanlızca 3 deger çekmeye çalışmışsın ama bu burda da hata var. yazdığın kod da for yapısını
düzgün kullanmamışsın
  for(k=0;k<3;k++)
  {
    genel[k]=getc();
    k++;
  }
burada hem for içinde ++k var hemde for gövdesi içinde ++k var. bu durumda genel[] dizisinin 0. ve 2. elemanlarına veri aktarırsın.
1. dizi elemanını es geçersin. bu durum da alıcı tarafında sorun yapar.
Alıcı tarafında ki kod:

     
Alıntı Yapif(genel[0]=='c')
     {
         if(genel[1]=='c')
         {
              if(genel[2]=='s')
              {
                output_high(led);delay_ms(500);output_low(led);delay_ms(500);a=1;
              }
         }
     }
               
                 if(a==1)
                 {
                  for(j=0;j<5;j++) putc(0x55);
                 
                  for(i=0;i<5;i++) printf("bbc");
                 }
                   
    }
}

alıcı tarafında ilk if ifadesi hiç bir zaman gerçekleşmeyeceğinden istediğin gibi bir sonuç alamazsın. Alıcı tarafında genel[] dizisi şu şekilde dolar; genel[0]=0x55, genel[1] es geçildiğinden bilinmiyor, genel[2]=0x55 olur.

Bence ilk olarak sadece tek bir karakter yolla ve bu karakteri yakalamaya çalış.

toyo

Rs232'yi yazılımsal olarak kullanırsanız INT_RDA kesmesi çalışmaz.
Gelirken ne getirilir ki giderken ne götürülür.