rs485 iletimde sorun

Başlatan fm, 11 Nisan 2013, 22:19:50

fm

Merhaba. Forumda çok dolaştım ama bir türlü çalışmadı program ve tasarım istediğim gibi. Daha öncede buna benzer bir kou açtım ancak gerçek anlamda soruma cevap alamadım. Devreyi ve kodları ekte paylaştım. Lütfen birisi nerde yanlış yaptığımı söyleyeblir mi?


Master Kodu(Sağdaki pic)
// BU PROGRAMDA KESMEYE GEREK YOKTUR.

#include <16F877A.h>
#include <string.h>

#FUSES NOWDT                    
#FUSES XT                       
#FUSES NOBROWNOUT               
#FUSES NOLVP                    
#FUSES NOPUT
#FUSES NODEBUG
#FUSES WRT_50%
#FUSES NOCPD
#FUSES NOPROTECT

#use delay(clock=4000000)

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

#define use_portb_lcd TRUE
#include <lcd.c>

#use rs232(baud=9600, xmit=pin_C6, rcv=pin_C7, parity=N, uart1, stop=1) // iletişimleri ayarlamak için isim verildi.
//#use rs232(baud=9600, xmit=pin_C6, rcv=pin_C7, enable=pin_C5, parity=N, uart1, stop=1)

char giris[80]; 
int i,t,kb;
char *k;

void main()
{
   setup_adc_ports (NO_ANALOGS) ;
   setup_adc (ADC_OFF) ;
   setup_psp (PSP_DISABLED) ;
   setup_timer_0 (RTCC_INTERNAL | RTCC_DIV_1) ;
   setup_timer_1 (T1_DISABLED) ;
   setup_timer_2 (T2_DISABLED, 0, 1) ;
   setup_comparator (NC_NC_NC_NC) ;
   setup_vref (FALSE) ;
   setup_CCP1 (CCP_OFF) ;
   setup_CCP2 (CCP_OFF) ;
   
   set_tris_a (0xF1) ;
   output_a (0x00) ;
   
   set_tris_b (0x00) ;
   output_b (0x00) ;
   
   //set_tris_c (0x80);
   
   set_tris_d (0x03);
   output_d (0x00);
   
   lcd_init ();

   
   i=0;
   t=0;
   
   printf(lcd_putc,"\fLutfen");
   printf(lcd_putc,"\nBekleyiniz");
   delay_ms(900);
   printf(lcd_putc,"\fVeriler Aliniyor");
   delay_ms(2);

   while (1)
   {
      putc(0);
       
      kb=kbhit(); 
      
      if(kb==1)
      {    
         gets(giris);
         delay_ms(100);
         
         k =giris; // yukarda veri1'e "gonder" stringi atandı. Burada k="gonder oluyor".
         
         do
         {
            putc(*k);   // veri dizisinin tüm elemanlarını yolla
         } while(*(++k) != '\0');
         
         putc(13); // gets için sonlandırma kodu. klavyedeki Enter tuşu
         
         printf(lcd_putc,"\f%d numarali",i);
         printf(lcd_putc,"\nslave okunuyor");
         delay_ms(500);
         printf(lcd_putc,"\f%s",giris);
         delay_ms(1500);
  
       } 
   }   
}

 


Slave Kodu(Soldaki pic)
#include <16F877A.h>

#device ADC=10    // adc çevirme ileminin kaç bitle yapılacağını söyler.

#include <string.h>  // string kütüphanesi programa tanıtılıyor.

#FUSES NOWDT                    
#FUSES XT                       
#FUSES NOBROWNOUT               
#FUSES NOLVP                    
#FUSES NOPUT
#FUSES NODEBUG
#FUSES WRT_50%
#FUSES NOCPD
#FUSES NOPROTECT

#use delay(clock=4000000)

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

#define use_portb_lcd TRUE
#include <lcd.c>

#use rs232(baud=9600, xmit=pin_C6, rcv=pin_C7, parity=N, stop=0)

char bayrak,data[50];
//char veri[] = "picsifir";
//char giris[20]; 
char *k; //pointer olrakk alınıyor.

unsigned long int gerilim_bilgi_a,gerilim_bilgi_b,sicaklik_bilgi_ust,sicaklik_bilgi_alt;   // işaretsiz 16 bitlik tamsayı tipinde değişken tanımlanıyor
float voltaj_a,voltaj_b, sicaklik_ust,sicaklik_alt; 
int secici;
float svoltaj1,svoltaj2; // sıcaklık hesabında kullanılan voltaj.

#int_rda //seri haberleşme kesmesi
void seri_haberlesme()
{  
   enable_interrupts(int_rda);
   secici=getc();
   
   if (secici == 0) // giris ve veriye atanan string ifadeler aynı ise sonuc 0 döndürür.
      {
         bayrak = 1;
      }
}

   
void main()
{
   setup_psp (PSP_DISABLED) ;
   setup_timer_0 (RTCC_INTERNAL | RTCC_DIV_1) ;
   setup_timer_1 (T1_DISABLED) ;
   setup_timer_2 (T2_DISABLED, 0, 1) ;
   setup_CCP1 (CCP_OFF) ;
   setup_CCP2 (CCP_OFF) ;
   setup_adc(adc_clock_div_32);
   setup_adc_ports(ALL_ANALOG);
   
   set_tris_a(0x0F);
 
   set_tris_b(0x00);
   output_b (0x00);
   
   set_tris_c (0x80);
   
   set_tris_d (0x00);
   output_d (0x00);
   
   enable_interrupts (int_rda);
   enable_interrupts (GLOBAL);
   
   bayrak = 0;
   
   lcd_init ();
   printf(lcd_putc,"\fOlcum Yapiliyor");
   printf(lcd_putc,"\nLutfen Bekleyin.");
   delay_ms(300);
   
   while (1)
   {
   delay_ms(20);
      
      output_low(pin_d1);
      
      //panel üstü sıcaklık
      set_adc_channel(0);
      delay_us(20);
      sicaklik_bilgi_ust=read_adc();
      svoltaj1=(sicaklik_bilgi_ust*0.0048828125)*1000; // Dijitale çevirme işlemine uğrayan sinyalin mV cinsinden gerilim değerini hesaplar. O yüzden 1000 ile çarpıyoruz.
      sicaklik_ust=(svoltaj1/10);  // her 10mV'ta 1 derece artma.
      delay_ms(2);
      
      //panel altı sıcaklık
      set_adc_channel(1);
      delay_us(20);
      sicaklik_bilgi_alt=read_adc();
      svoltaj2=(sicaklik_bilgi_alt*0.0048828125)*1000; // Dijitale çevirme işlemine uğrayan sinyalin mV cinsinden gerilim değerini hesaplar. O yüzden 1000 ile çarpıyoruz.
      sicaklik_alt=(svoltaj2/10);  // her 10mV'ta 1 derece artma.
      delay_ms(2);
      
     
      if (bayrak == 1)
      {
         output_high(pin_d1);
         delay_ms(300);
         output_low(pin_d1);
         
         sprintf(data,"%f,%f",sicaklik_ust,sicaklik_alt); //bilgiyi paket haline getirdik.
         //printf("%s\n\r"data);
         
         k = data; // yukarda veri1'e "data" stringi atandı. Burada k="data" oluyor.
         
         do
         {
            putc(*k);   // veri dizisinin tüm elemanlarını yolla
         } while(*(++k) != '\0');
         
         putc(13); // gets için sonlandırma kodu. klavyedeki Enter tuşu
         
      }
      
      bayrak=0;
  }

}

camby

Çalışmayan nedir ?

- LCD 'ler çalışıyor mu ?
- Master'ın Rx - Tx hatları çalışıyor mu ( 485 olmadan )

fm

Arada 485ler olmadan rs232 ile slaveden okunan sıcaklık değerlerini master pice alıp lcdde yazdırabiliyorum. Ama araya 485 eklediğimde slave masterda gelen sinyali alıyor ama master slaveden gelen sıcaklık değerlerini almıyor. Çalıştıramadığım kısım master picin veriyi alması..
Rs232 ile denediğimde her iki picinde rx ve tx uçları çalışıyor.

camby

Güzel o zaman çok bir sorun yok , gözden ufak bir şey kaçmıştır.

- Sağdaki  485 'in De pini boşta ?

fm

Onuda RE ile birleştirip C5 pinene bağladım ama yine bi sonuç alamadım..

camby

Master datayı yolladıktan sonra , hemen alıcı moduna geçmeli , bunu yaptınız mı ?

Benzer olarak da slave , sürekli alıcı modunda beklerden data geldikten sonra cevap veririken verici modunda datayı gönderecek ve tekrar dinlemeye geçecek.

fm

Hocam önce şunu sorayım size. Master ve iki tane slave kullandığım bir devrem var. Slaveler masterdan aldıkları adres bilgilerini eşleştirip sırası ile mastera okudukları değerleri gönderiyorlar. Bunu rs232 kullanarak yaptım. Sormak istediğim bu aşamada rs232 ile rs485 arasında kodda ve  tasarımda(bağlantılarda) ne gibi farklılıklar olmalı?

Benim amacım 1 master ve 20 slave arasında iletişi kurmak. Ancak 1 master 1 slave ile bile iletişim kuramadım. Dediğiniz gibi master veriyi almak için dinleme durumuna geçmeli yazdığım kodu eklemiştim. Sizden rica etsem koda bakıp eksik bir kısım varsa, masterın dinleme durumuna geçmesi için, bana söyleyebilir misiniz?

Saygılarımla..

skara1214

valla çok ayrıntılı bakamamakla beraber master datayı yollamadan önce de pinini higha almalı-beklerken lowa almalı aynı şekilde slavede aynısını yapmalı ama yazılımda o pinleri değiştiren birşey göremedim?
Herkes ölür ama herkes gerçekten yaşamaz

camby

rs232 poınt to ponıt ıletısım ıcındır , rs485 multı poınt ıletısım saglar. 485 aynı zamanda 232 den farklı olarak sınyalı dıferansıyel olarak ıletır , ve avantajı coktur. Forumda ve nette bolca kaynak var ben sadece su an ıcın anahtar kelımelerı yazıyorum.

Slaveler datayı alıp ısleyıp sırayla gondermelerı sıkıntılı bır durum , hangısı once hangısı sonra derken ısler karısır. Bunun yerıne her bır slave ın belırlı bır adresı olursa , master sırayla ıstedıgı slave e ıstek yollar ve bu slave ona cevap verırse daha ıyı bır yol secılmıs olur. Bundan sonrası data alısverısnın nasıl olacagı , hata kontrollerı vs protokol ısı...

Tabıkı baslangıc ıcın 1 master 1slave calısması dogru yol. 485 de ıletım hattı tek oldugu ıcın (half dublex) Rx tx modlarına dıkkat etmek gerek data alıp verırken. Musaıt bı ara ben de bakarım kodlarınıza.

camby

485'in yön seçim satırı hangisi ? eğer yok ise onu eklemeniz lazım

fm

@skara1214, hocam dediğiniz gibi dün gece konuyu açtıktan sonra gerekli eklemeleri yaptığımı düşünüyorum ama sanırım yanlış yaptım.
Sizce nasıl yapmalıyım ve kodun neresine eklemeliyim.

@camby, hocam 485 entegresi için bu dediğinizi nasıl yapacağım..

camby

DE ve Re pinleri birleştikten sonra bir pin'e girilmiş. Bu pin sanırım sağdaki pic için C3. Şimdi C3 çıkışına 1 verirseniz 485 veri gönderme modunda olur , 0 verirseniz veri alma modunda olur. 485 datasheetine de dikkatlice bir göz atın , şemasından kolayca anlaşılır bu işin nasıl yapıldığı.

fm

Hocam dediklerinizi yaptım ama hiçbir şekilde yapamadım. müsait bir zamanınızda kodda ve tasarımda yapmam gerekenleri anlatırsanız çok sevinirim.
Saygılarımla..

camby

Master :

- Veri Gönderme moduna al
- Datayı gönder
- Veri Alma moduna al


Slave :

- Veri alma moduna al ve bekle
- Data geldiğinde
     - Veri Gönderme moduna geç
     - Veriyi gönder
     - Veri alma moduna geri dön ve beklemeye devam et.


max485'lere giden kontrol pininin çalıştığından emin oldun.
Sistemi adım adım çalıştırıp datanın gönderilip gönderilmedeğine bakabilirsiniz. Picler olmadan simülasyonda sadece 485 leri de kontrol edebilirsiniz. Hatayı bulmada yardımcı olur.

Devre fiziksel olarak var mı ? Sadece proteus ortamında mı çalışyıor.

fm

Proteusta bile çalışmıyor tasarım. Devresi de fiziksel olarak var ama oda çalışmadı. Dediklerininizide harfiyen yaptığımı düşünüyorum. Nafile çalıştıramadım.  ???