RS485 Haberleşememe! Problemi

Başlatan musti463, 21 Ağustos 2014, 17:17:42

musti463

Merhaba iki PIC arasında RS485 haberleşme kurmaya çalışıyorum.Sistemi PROTEUS'da çalıştırdım sorunsuz çalıştı fakat. Devreyi gerçekte kurunca aynı sonuç ortaya çıkmadı sizce sebebi ne olabilir?
Bu arada devre şu işi yapıyor:

Master PIC'den;

d2 high olduğunda 82.34 bilgisi gönderilecek
d3 high olduğunda 25.36 bilgisi gönderilecek
d4 high olduğunda 12.56 bilgisi gönderilecek

Slave PIC ise gelen bilgiye 10 ekleyip ekranda gösterecek. Yani Master 82.34 bilgisini gönderdiği zaman ekranda 92.34 bilgisi görünecek.Fakat devreyi gerçekte çalıştırdığımda ekranda 0.00 bilgisi görünüyor.Masterdaki d2,d3,d4 pinlerinden herhangi birini high yaptığımda slave grafik ekranında 10.00 bilgisi görünüyor.

MASTER PIC: 16F877A

#INCLUDE <16f877.H>
#USE DELAY (CLOCK=4000000)
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,stop=1,parity=n)
#include <input.c> 
#use fast_io (b)
#use fast_io (d)
#define use_portb_lcd true
#INCLUDE <LCD420.c>
#define re pin_d0
#define de pin_d1
float x=82.34,y=25.36,z=12.56;
int gb=0;
//
void main()
{
set_tris_b(0x00);
output_b(0x00);
set_tris_d(0x00);
output_d(0x00);
output_high(re);
output_high(de);
delay_ms(50);
lcd_init();
printf(lcd_putc,"\fBilgi: ");

while (1)
{



if(input(pin_d2))
{
   delay_ms(10);
   printf(lcd_putc,"\fBilgi:%f ",x);
   while(input(pin_d2));
   printf("%f",x);
   
}

if(input(pin_d3))
{
   delay_ms(10);
   printf(lcd_putc,"\fBilgi:%f ",y);
   while(input(pin_d3));
   printf("%f",y);
   
}

if(input(pin_d4))
{
   delay_ms(10);
   printf(lcd_putc,"\fBilgi:%f ",z);
   while(input(pin_d4));
   printf("%f",z);
   
}









}
}


SLAVE PIC: 18F4685

#INCLUDE <18F4685.H>
#USE DELAY (CLOCK=4000000)
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,stop=1,parity=n)
#include <input.c> 
#use fast_io (d)

#include <T6963C.c>
#INCLUDE <stdlib.h>
#define re pin_d0
#define de pin_d1

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES PUT                      //Power Up Timer
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
#DEFINE fast_glcd


char gelen_bilgi[10],x_str[10];
int sayac;
float x=0;
//
void main()
{
set_tris_d(0x00);
output_d(0x00);

output_low(re);
output_low(de);

glcd_init(240,128); // Grafik LCD ektran hazırlanıyor
glcd_WriteByte(1, (LCDModeSet|LCDMode_XOR)); // Grafik LCD ekran XOR moda göre ayarlanıyor
glcd_WriteByte(1, (LCDDispMode|LCDDisp_TXT|LCDDisp_GRH)); // Grafik LCD ekran hem metin hem grafik modunda çalışacak şekilde ayarlanıyor

sprintf(x_str,"Bilgi: %f",x);//float to string işlemi gerçekleştiriliyor
glcd_text57(60,55,x_str,2,1);//voltaj_str değeri ekrana yazdırılıyor

//
while (1)
{


   for(sayac=0;sayac<5;sayac++)
      {
         gelen_bilgi[sayac]=getc();
      }




x = atof(gelen_bilgi);

x=x+10;

glcd_init(240,128); // Grafik LCD ektran hazırlanıyor
glcd_WriteByte(1, (LCDModeSet|LCDMode_XOR)); // Grafik LCD ekran XOR moda göre ayarlanıyor
glcd_WriteByte(1, (LCDDispMode|LCDDisp_TXT|LCDDisp_GRH)); // Grafik LCD ekran hem metin hem grafik modunda çalışacak şekilde ayarlanıyor

sprintf(x_str,"Bilgi: %f",x);//float to string işlemi gerçekleştiriliyor
glcd_text57(60,55,x_str,2,1);//voltaj_str değeri ekrana yazdırılıyor

}}


DEVRE ŞEMASI:





BU DA SİMÜLASYON ESNASINDA EKRAN GÖRÜNTÜSÜ:

[IMG]http://oi59.tinypic.com/2jenxoi.png[/img]
Mustafa Emir SADE

sadogan

R6-R7-R8-R9 bunların değerleri çok düşük. Bu dirençlerı çıkarıp test et.

musti463

Çıkarıp denedim zaten önce. Olmayınca takayim dedim yine olmadı
Mustafa Emir SADE

Kabil ATICI

baud hızını düşürerek deneyebilir misin?
4800,2400,1200,600 gibi yakaladığın zaman o hızda kalsın.
ambar7

selimkoc

MikroC ile RS-485 Animasyonu


RS-485 Uygulaması

linkindeki uygulamayı yaparken bazı denemeler yaptım;

RS-485 entegresi olarak max487 kullandım. Yaptığım deneylerde 120 ohm hat sonlandırma direnci koyarak, koymadan, 4k7 pull-up ve pull-down direnç takarak ve takmayarak denedim. Yaklaşım 3m sarmal kablo kullandım. Gayet güzel haberleşti.

Burada en önemli durum frekans. Yani kristal ve konfigurasyon ayarları.

yldzelektronik

#5
@musti

Bende devre şeman ekran görüntüsü falan gözükmüyor.Ancak benim anlamadığım sen karşıya göndermek istediğin veriyi nasıl bir metodla gönderiyorsun?

Ekleme:

printf(lcd_putc,"\fBilgi:%f ",x);

Bu kısımda ise burada yalnızca lcdye veri gönderiyorsun.
Kişinin başına gelen hayır Allah'tandır. Kişinin başına gelen şer nefsindendir. Nefislerimizle kendimize zulüm ediyoruz.

musti463

#6
@yldzelektronik hocam "printf("%f",x);" komutu ile gönderiyorum

mesaj birleştirme:: 22 Ağustos 2014, 11:46:58

@selimkoc hocam uygulama çok güzel fakat web sayfanızda kodlara ulaşmaya çalıştım bulamadım onlarıda paylaşabilirmisiniz acaba? OSC frekansınız ve baudrate niz neydi bu uygulamada?
Mustafa Emir SADE

selimkoc

İnşaalah ileri bir tarihte yayınlayacağım. Baud 9600 ve 2400 ile denedim. Master (PIC18F4550) kristal 20Mhz ile 48Mhz PLL kullandım. Slave(PIC16F628A) 20Mhz kristal kullandım.

Kodlamayı MikroC'nin RS-485 fonksiyonunu kullanarak yaptım.

elektronart

for(sayac=0;sayac<5;sayac++)
      {
         gelen_bilgi[sayac]=getc();
      }

Sanırım sorunun cevabı burada gizli. getc() fonksiyonun nasıl çalıştığı önemli. Eğer gelen bilgi yokken sana cevap dönmüyorsa hatta bekletiyorsa ne ala, ama bilgi yokken 0 dönüyorsa o zaman gördüklerin gayet normal. Gelen karakterleri alma işini rx interruptının içine koymanı öneririm. Böylece sadece bilgi geldiğinde veri almış olursun.
Bir de bir protokol belirlesen iyi olur. Yani gelen veri her ne olursa olsun değil sadece masterdan gelen tertipli düzenli verileri alırsın.
Son olarak, kullanacağın protokolün slaveden gelecek ack'a uygun olması iyi olur. Bunun için RS485 çiplerinin RE DE pinlerini de bir IOya bağlaman gerekir.
Gerisi çorap söküğü :)
Açık Elektronik

musti463

sorunu hallettim nasıl oldu bilmiyorum ama devre çalıştı şöyle bir sorum var.

rs485 veri iletişiminde gönderilen veri karakter haricinde int,float olabilir mi? yoksa karakteri veya stringi gönderip karşıda mı float veya int'e dönüştürmeliyiz?
Mustafa Emir SADE

Kabil ATICI

string olarak gönderdi isen iş kolay,
gelen veri 0x30 ile 0x39 arasında olmalı, nokta hariç.
gelen veriyi nokta haricindeki 0x30'dan çıkart
int veri=0;
int gelen_veri=0;  // seri porttan gelen veri dersek
int nokta_geldi=0;// ondalık nokta geldi

if (nokta_geldi==0)
{
if (gelen_veri !=",")  // ondalık nokta ne ile tanımlanıyorsa burası '.' olabilir emin değilim.
veri=(veri*10)+(gelen_veri-0x30);
else
nokta_geldi=1;
}
else
{
if (nokta_geldi==2)
{
veri=veri+((gelen_veri-0x30)/100);
nokta_geldi=0;// veya bir üçüncü adım olarak veri gelmesi tamam işlemine saklanabilir.
}

if (nokta_geldi==1)
{
veri=veri+((gelen_veri-0x30)/10);
nokta_geldi=2;
}
}

ambar7