rs232 (485 dönüştürücü ile) pic pc haberleşme sorunu

Başlatan hacamat, 19 Kasım 2012, 19:51:33

hacamat

arkadaşlar pcden yolladığımız sayılara göre picte bir röleyi kontrol etmek istiyoruz. Sistem rs232 to rs485 dönüştürücü kullanılmakta. sistem isiste normal olarak çalışmakta fakat uygulamada hiçbir tepki vermiyor. sanırım veri türlerinden bir sorun yaşanıyor.
pic kodu
#include <16f877a.h>
#fuses xt,nowdt,nowrt,nodebug,nolvp,nocpd,noput,noprotect,nobrownout
#use delay(clock=4M)
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,parity=N,stop=1)


char veri[10];
int yak=1;
int son=0;
int sayac;




#int_rda   // RX ucuna veri gelince meydane gelen kesme
void serihaberlesme_kesmesi ()
{
  disable_interrupts(int_rda); // int_rda kesmesini pasif yap134751
  for (sayac=0;sayac<4;sayac++)
  {
  veri[sayac]=getchar();
  }
  if (veri[0]=='1' && veri[1]=='2' && veri[2]=='3' && veri[3]=='4')
   {
   output_high(pin_B1);
   printf("%d",yak);
   delay_ms(100);
   }

   else if (veri[0]=='5' && veri[1]=='6' && veri[2]=='7' && veri[3]=='8')
   {
   output_low(pin_B1);
   printf("%d",son);
    delay_ms(100);
   }
   
}

void main ( )
{
  // SET_TRIS_A( 0xFF );
   //output_a(0x00);
   enable_interrupts(GLOBAL);  // Aktif edilen tüm kesmelere izin ver

   while(1) // Sonsuz döngü
   {
      enable_interrupts(int_rda); // int_rda kesmesi aktif
     
   }
}


c sharp kodu

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;



namespace uzak
{
    public partial class Form1 : Form
    {
        static SerialPort USB_RS485;
        byte port_open = 0;

        public Form1()
        {
            InitializeComponent();
            USB_RS485 = new SerialPort();

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            foreach (string s in SerialPort.GetPortNames())
            {
                Ports.Items.Add(s);
            }
            Ports.Text = "Select Port";
        }

        private void Ports_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (port_open != 0)
            {
                USB_RS485.Close();
                port_open = 0;
            }
            USB_RS485.PortName = Ports.Text;                         //Ports.Text from combo box i.e. COM3
            USB_RS485.Parity = 0;
            USB_RS485.BaudRate = 38400;
            USB_RS485.StopBits = StopBits.Two;
            USB_RS485.DataBits = 8;
            USB_RS485.ReadTimeout = 500;
            USB_RS485.WriteTimeout = 500;
            USB_RS485.Open();
            if (USB_RS485.IsOpen == true) port_open = 1; 

        }

        private void button1_Click(object sender, EventArgs e)
        {
           char[] buff = new char[4];

            if (port_open == 0) return;
            else
            {
                USB_RS485.BreakState = true;                             //if break is required use these two lines
                USB_RS485.BreakState = false;
                buff[0] = '0';
                buff[1] = '1';
                buff[2] = '2';
                buff[3] = '3';
                // buff[4] = 4;
                //buff[5] = 5;
                USB_RS485.Write(buff, 0, 4);                                 //write to COMx (array, start, length)
                // while (USB_RS485.BytesToRead < 4) ;                   //wait for expected read data length, i.e 4
                //USB_RS485.Read(buff, 0, 4);                                 //read from COMx (array, start, length)
                // label1.Text = string.Format(" Data returned = {0},{1},{2},{3}", buff[0], buff[1], buff[2], buff[3]);
            }
        }
    }
}

Klein

Sorunun yazılımda olduğuna emin miyiz?
PC'den gönderilen veri  PIC'in bacağına kadar ulaşıyr mu?
sinyalde bozulma var mı?
Rs485 alıcınızın  bağlantıları doğru mu?

hacamat

rs485'in bağlantıları doğru. iki pc arasında veriyi gönderip alabiliyorum.

sinyalde bozulma yok bunu pcde denediğimde veriler doğru olarak gidiyor.

pcden gelen veri pic'in bacaklarına kadar geliyor.

onu şöyle denedim

if (veri[0]=='1' && veri[1]=='2' && veri[2]=='3' && veri[3]=='4')
   {
   output_high(pin_B1);
   printf("%d",yak);
   delay_ms(100);
   }

   else 
   {
   output_high(pin_B2);
   printf("%d",son);
    delay_ms(100);
   }


dediğimde verileri eşleştiremediği için ikinci ledi yakıyor.

sorunun veri türlerinde olduğunu düşünüyorum ama hala bir çözüm bulamadım.

Klein

RS485 çipiniz nedir? (75176? , MAX485)
PIC Programında RS485 RXEN,TXEN pinlerini kontrol eden pinleri göremedim. Programın başka bir yerinde mi kontrol ediyorsunuz? 

hacamat

sistemde pc tarafında usb to 485 çevirici devre (hazır aldım) pic tarafında ise 485 to rs232 dönüştürücü mevcut.

bunların ikiside hazır kitler. kitler kendi aralarında pcye bağlandığında haberleşiyor. pice veri gönderdiğimde pic bunlardan gelen verileri anlamıyor.

Klein

RS485/232 çeviricinin çıkışlarını direk PIC'e bağlamadınız umarım.
PIC girişi RS232 değil. TTL. bunun için en azından bir invertör kullanmanız , potansiyelleri uyumu hale getirecek diyot, zener, transistör vs.. kullanmanız gerek.

Şemanızı yüklermisiniz. Sanırım donanımda bir hata yapıyorsunuz. 

esensoy

pic in rs232 arayüzü ile pc nin ki aynı değil,
yani pc de olan rts cts dtr dsr uçları her picte yok, rs485-232 çeviriciler de genelde dtr dsr uçlarını kullanır,
şema eklerseniz daha kolay yorum yapılabilir.
En tehlikeli an "zafer" anıdır.

Klein


esensoy

haklısınız, düzelteyim ben,

pic + max232 (veya benzeri) ile oluşturduğunuz  rs232 arayüzü ile pc nin ki aynı değil,
yani pc de olan rts cts dtr dsr uçları her picte yok, rs485-232 çeviriciler de genelde dtr dsr uçlarını kullanır,
şema eklerseniz daha kolay yorum yapılabilir.
En tehlikeli an "zafer" anıdır.

Klein

Bir an , kullandığım tüm işlemcilerden soğumuştum :)

hacamat

tabi arada ttl seviyesine indirmek için max232 var.

devre ile ilgili resim ve şemaları yolluyorum.

Klein

Donanımda hata görmedim. İlk bakışta programın çalışmaması için bir sebep göremedim.

Kullanılan kütüphanedeki getchar() fonksiyonunun nasl çalıştığını bilmediğim için soruyorum.
getchar() fonksiyonu çağırıldığında   RX  tamponundaki hazır veriyi mi getiriyor? 
veri gelene kadar döngüde mi bekliyor?

Eğer döngüde bekleyip gelen ilk veriyi sunuyorsa, bu durumda  RX kesmesine ilk girdiğinizde tampona girmiş veriye ne oluyor? Böyle çalışıyorsa ilk veriyi kaybederiz. 

veri[0]=='1' && veri[1]=='2' && veri[2]=='3' && veri[3]=='4'

yerine

veri[0]=='2' && veri[1]=='3' && veri[2]=='4' şeklinde denemekte fayda var.


hacamat

evet doğru yaklaşım teşekkürler. getchar fonksiyonu getc fonksiyonu gibi çalışıyor. sadece fark olarak karakter çekiyor. getchar fonksiyonun baktığımda kbhit ile kontrol edilmesi gerektiği yazıyor user manuel'de.

sizin yazdığınızı da deneyeceğim yarın. birde pic programını kbhit kontrollü yapıp deneyeceğim. umarım sorun çözülür.

İlginize teşekkürler.

skara1214

4 veri almak yerine sadece 1 veri alıp deneyin onu çalıştırın daha sonra diğerlerine bakın.Ayrıca pic tarafında rx e 10 ile pull up yapıp deneyin.
Herkes ölür ama herkes gerçekten yaşamaz

sadogan

#include <16f877a.h>
#fuses xt,nowdt,nowrt,nodebug,nolvp,nocpd,put,noprotect,nobrownout
#use delay(clock=4M)
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,parity=N,stop=1)
char veri[10];
int yak=1;
int son=0;
int sayac;
#int_rda   // RX ucuna veri gelince meydane gelen kesme
void serihaberlesme_kesmesi ()
{
   disable_interrupts(int_rda);
   putc(getc());
   enable_interrupts(int_rda);
}

void main ( )
{
  // SET_TRIS_A( 0xFF );
   //output_a(0x00);
   setup_psp(PSP_DISABLED);       
   setup_spi(SPI_SS_DISABLED);    
   set_tris_c(0b11100000);
   enable_interrupts(int_rda);
   enable_interrupts(GLOBAL);  // Aktif edilen tüm kesmelere izin ver

   while(1) // Sonsuz döngü
   {
       
     
   }
}

Bu yazılımı devrenize yükleyip donanımsal bir hata varmı test edin.
pc den yolladıgınız veriyi tekrar pc ye yollar.