Sonsivri
 
*
Welcome, Guest. Please login or register.
Did you miss your activation email?
November 10, 2024, 07:50:04 19:50


Login with username, password and session length


Pages: [1]
Print
Author Topic: Multidrop using RS485  (Read 13170 times)
0 Members and 1 Guest are viewing this topic.
Husanto
Newbie
*
Offline Offline

Posts: 10

Thank You
-Given: 0
-Receive: 1


« on: November 27, 2007, 10:51:35 10:51 »

Hi,

   Can anybody give me a sample mikrobasic code for multidrop (RS485) programming between several PIC micro??
Logged
bogdantk
Active Member
***
Offline Offline

Posts: 100

Thank You
-Given: 40
-Receive: 18


« Reply #1 on: November 27, 2007, 12:10:32 12:10 »

Hello
First you have to use a RS485 driver circuit (SN75176 example) and control the circuit tri-state by a dedicated PIC pin.
When you want to send data just turn the pin on. But for arbitration of the RS485 bus you will need some kind of protocol
(at the logic level of data control) or one master device to control the bus access.
Here you will find an example . bRC3 is the control bit. The device only respond to messages to its address. The whole communication is on the control of a master who is innitiating the dialogue with a device.
The code is for Forrest Electronic PIC compiler but is in plain C.

#include "E:\\Relee1\\Relee_Auto.h"
#include<Delays.h>
//#include<PIC.h>
#include<PortBits.h>
unsigned char ReceptBuf; // buffer receptie serial
unsigned char Rece; // caracterul receptionat
unsigned char Numar; // numar caractere din mesaj
unsigned char R1;//Sir de caractere receptionate pe serial mesaj
unsigned char R2;
unsigned char R3;
unsigned char R4;
unsigned char ADRESA;// Adresa de bus
unsigned char SerieL;// Serie echipament
unsigned char SerieH;
unsigned char Clipeste;//Fanion receptie date
unsigned char Durata=5;//Durata in secunde de clipire verde la receptie date
unsigned char Dur_clip;//Durata de cand clipeste
unsigned char Relee;//relee actionate 1
unsigned char Paza;// Paza=0 normal Paza=1 bitul 0 este alarma de watch dog
unsigned char Marker=0x41; // Marker reset alarma
unsigned char Alarma;// Alarma=0 nu este declansata 1 este declansata
unsigned char Timp_al;//Interval alarmare intre 1 si 60 minute
unsigned char Timp1;//Timpul curent de alarmare
unsigned char secund; // contor secunde

#pragma __config _FCMEN_OFF & _CPD_OFF & _PWRTE_ON & _CP_ON & _WDT_OFF & _HS_OSC & _IESO_OFF & _MCLRE_OFF & _BOD_OFF


void UserInterrupt()
{
 #asmline SETPCLATH UserIntReturn,-1  ; SETPCLATH for interrupt routine
 #asmline goto UserIntReturn         ; Assembler - go back to interrupt routine
}

//*******************************************************************************

void SetRel()
{
unsigned char i;
unsigned char date;

bRA0=0;
bRA1=0;
bRC0=0;

date=Relee;

for(i=0x01;i<=8;++i)
   {
   if((date & 0x80)==0)bRA1=0;
   else bRA1=1;
   date=date<<1;
   Wait(1);
   bRA0=1;
   Wait(1);
   bRA0=0;
   }
Wait(1);
bRC0=1;
Wait(1);
bRC0=0;
}


void UserInitialise()
{
//WriteEEData(0x01,0x31);//Test serie hard L
//WriteEEData(0x02,0x31);//test serie hard H
//WriteEEData(0x04,0xAA);//Test continut relee
WriteEEData(0x06,0x31);//Test adresa bus
//WriteEEData(0x07,0x01);//Test watch-dog
//WriteEEData(0x08,0x02);//Test interval wdt
//WriteEEData(0x09,0x00);//Alarma
unsigned char PazaE;
unsigned char AlarmaE;
unsigned char Timp_alE;

//Wait(600);
secund=0x3C;
SerieL=ReadEEData(0x01);
SerieH=ReadEEData(0x02);
ADRESA=ReadEEData(0x06);
Relee=ReadEEData(0x04);
PazaE=ReadEEData(0x07);
if(PazaE>0x01)Paza=0;
else Paza=PazaE;
AlarmaE=ReadEEData(0x09);
if(AlarmaE!=0&&AlarmaE!=1)Alarma=0;
else Alarma=AlarmaE;
Timp_alE=ReadEEData(0x08);
if(Timp_alE>=1&&Timp_alE<=60)Timp_al=Timp_alE;
else Timp_al=10;
Timp1=Timp_al;
//AddTx("1");
SetRel();
//Dur_clip=Durata;
bRC3=0;
bRA2=0;
bRC2=1;
//Wait(500);
//bRC2=0;
//Wait(500);
//bRC2=1;
//Wait(500);
//bRC2=0;
//Wait(500);
//bRC2=1;
//Wait(500);
//bRC2=0;
//Wait(500);
//bRC2=1;
}

//*******************************************************************************

void UserLoop()
{
}

// User occurrence code

void Verifica_al()
{
if(Paza==0 || Alarma==0x01)return;
else
   {
   Timp1=Timp1 - 0x01;
   if(Timp1 == 0x00)
      {
      Alarma=1;
      WriteEEData(0x09,Alarma);
      Wait(5);
      Relee=Relee|0x01;
      SetRel();
      }
   }
}

void Verificare()
{
if(R2==SerieL && R3==SerieH)
   {
   ADRESA=R4;
   WriteEEData(0x06, ADRESA);
   Wait(5);
   //Clipeste=1;
   }
return;
}

void Setare_init()
{
if(R1=='S') Verificare();
else return;
}

void Versiune()
{
unsigned char VE;

VE=ReadEEData(0x03);
Wait(2);
bRC3=1;
Wait(4);
AddTx(VE);
AddTx(SerieL);
AddTx(SerieH);
Wait(850);
bRC3=0;
}

void RecRel()
{
if(R3!=R4)
   {
   bRC3=1;
   Wait(4);
   AddTx('E');
   AddTx('R');
   AddTx(ADRESA);
   Wait(850);
   bRC3=0;
   return;
   }
else
   {
   if(Paza==0x01)
      {
      Relee=R3;
      if (Alarma==1)
         {
         Relee=Relee|0x01;
         }
      else
         {
         Relee=Relee&0xFE;
         }
      }
   else
      {
      Relee=R3;
      }
   WriteEEData(0x04,R3);
   Wait(5);
   SetRel();
   bRC3=1;
   Wait(4);
   AddTx('O');
   AddTx('K');
   AddTx(ADRESA);
   AddTx(Relee);
   Wait(950);
   bRC3=0;   
   }
}

void Sch_adr()
{
if(R3==R4)
   {
   ADRESA=R3;
   WriteEEData(0x06,ADRESA);
   Wait(5);
   }
}


void Raspund_Test()
{
unsigned char tte;
bRC3=1;
Wait(4);
AddTx('O');
AddTx('K');
Wait(2);
AddTx(ADRESA);
AddTx(Relee);
Wait(850);
bRC3=0;
}

void Set_alarma()
{
if(R3=='S')
   {
   if(R4>=1&&R4<=60)Timp_al=R4;
   else Timp_al=10;
   WriteEEData(0x08,Timp_al);
   Wait(5);
   Timp1=Timp_al;
   Paza=0x01;
   WriteEEData(0x07,Paza);
   Wait(5);
   Alarma=0;
   WriteEEData(0x09,Alarma);
   Wait(5);
   Relee=Relee&0xFE;
   WriteEEData(0x04,Relee);
   Wait(5);
   SetRel();
   return;
   }
if(R3=='R')
   {
   Paza=0;
   WriteEEData(0x07,Paza);
   Wait(5);
   Alarma=0;
   WriteEEData(0x09,Alarma);
   Wait(5);
   Relee=Relee&0xFE;
   WriteEEData(0x04,Relee);
   Wait(5);
   SetRel();
   return;
   }
if(R3=Marker && R4=Marker)
   {
   Timp1=Timp_al;
   }
}


void Setare_f()
{
if(R2==ADRESA)
   {
   switch(R1)
      {
      case 'S': Verificare();break;
      case 'V': Versiune();break;
      case 'T': Raspund_Test();break;
      case 'A': Sch_adr();break;
      case 'R': RecRel();break;
      case 'W': Set_alarma();break;
      default: break;
      }
   //Clipeste=1;
   }
}


void Setare()
{
if(ADRESA==0) Setare_init();
else Setare_f();
}

void TestChar()
{
switch(Numar)
   {
   case 1: R2=Rece; Numar++;break;
   case 2: R3=Rece; Numar++;break;
   case 3: R4=Rece; Numar=0; Setare();break;
   default: Numar=0;
   }
}

void Update()
{
//if(Clipeste==1)
//   {
//   bRC2=0;
//   Wait(250);
//   bRC2=1;
//   Dur_clip=Dur_clip-1;
//   if(Dur_clip==0)
//      {
//      Clipeste=0;
//      Dur_clip=Durata;
//      }
//   }
secund=secund-1;
if (secund==0)
   {
   secund=0x3C;
   Verifica_al();
   }
}



void Receptie()
{
unsigned char f;

ReceptBuf=GetRxSize();
for(f=0;f<ReceptBuf;f++)
   {
   Rece=WaitRx();
   }
if (Numar==0)
   {
   switch(Rece)
      {
      case'A': Numar=1;R1='A';break;//
      case'V': Numar=1;R1='V';break;//
      case'S': Numar=1;R1='S';break;//
      case'T': Numar=1;R1='T';break;//
      case'R': Numar=1;R1='R';break;//
      case'W': Numar=1;R1='W';break;//
      default: TestChar();//
      }
   return;
   }
else TestChar();
}
Logged
Marineland
Active Member
***
Offline Offline

Posts: 149

Thank You
-Given: 18
-Receive: 124



« Reply #2 on: November 27, 2007, 12:46:53 12:46 »

hi,

You can find examples for RS485 (Master and Slave) in "C:\Program files\Mikroelektronika\mikroBasic\Examples\EasyPIC4\extra examples\RS485_Master_Example" and "..\RS485_Slave_Example".
It's working perfectly...
Btw: The forum of Mikroelektronika is very active: fo to http://www.mikroe.com/forum/ ... Smiley

Regards
Logged
Pages: [1]
Print
Jump to:  


DISCLAIMER
WE DONT HOST ANY ILLEGAL FILES ON THE SERVER
USE CONTACT US TO REPORT ILLEGAL FILES
ADMINISTRATORS CANNOT BE HELD RESPONSIBLE FOR USERS POSTS AND LINKS

... Copyright © 2003-2999 Sonsivri.to ...
Powered by SMF 1.1.18 | SMF © 2006-2009, Simple Machines LLC | HarzeM Dilber MC