RS-485 Master-Slave

Discussion on projects that are created by users and posted on mikroElektronika website.
Post Reply
Author
Message
Zé do Corote
Posts: 1
Joined: 04 May 2019 18:39
Location: São Carlos, São Paulo, Brasil
Contact:

RS-485 Master-Slave

#1 Post by Zé do Corote » 04 May 2019 19:11

Hello, I am a beginner in C language and need to develop a MODBUS RTU Master-Slave communication project with RS-485.

First I did a Proteus simulation with two PIC16F887, one master and the other slave. The master should send a message requesting some data and the slave should return, so I need to display this data on an LCD display.

I'm programming in C language and with mikroC PRO for PIC.

What I wanted was to write some data (EEPROM) on the slave and adapt the code for the master to read that data and display it on the display.

Please any help is welcome!

The master programming is as follows:

Code: Select all

char dat[10];                          // buffer for receving/sending messages
char i,j;

//configurações de pinagem do LCD
sbit LCD_RS at RD4_bit;
sbit LCD_EN at RD5_bit;
sbit LCD_D7 at RD3_bit;
sbit LCD_D6 at RD2_bit;
sbit LCD_D5 at RD1_bit;
sbit LCD_D4 at RD0_bit;

//direção dos pinos
sbit LCD_RS_Direction at TRISD4_bit;
sbit LCD_EN_Direction at TRISD5_bit;
sbit LCD_D7_Direction at TRISD3_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D5_Direction at TRISD1_bit;
sbit LCD_D4_Direction at TRISD0_bit;

sbit  rs485_rxtx_pin  at RC2_bit;               // set transcieve pin
sbit  rs485_rxtx_pin_direction at TRISC2_bit;   // set transcieve pin direction

// Interrupt routine
void interrupt() {
  RS485Master_Receive(dat);
}

void main(){
  long cnt = 0;

  ANSEL  = 0;                          // Configure AN pins as digital I/O
  ANSELH = 0;
  C1ON_bit = 0;                        // Disable comparators
  C2ON_bit = 0;

  PORTB  = 0;
  PORTD  = 0;
  TRISB  = 0;
  TRISD  = 0;

  Lcd_Init();
  Lcd_Cmd(_LCD_CURSOR_OFF);
  Lcd_Out(1,1,"RS-485 Master-Slave");
  Delay_ms(3000);
  Lcd_Cmd(_LCD_CLEAR);

  UART1_Init(9600);                    // initialize UART1 module
  Delay_ms(100);

  RS485Master_Init();                  // initialize MCU as Master
  dat[0] = 0x29;
  dat[1] = 0xF0;
  dat[2] = 0x0F;
  dat[4] = 0;                          // ensure that message received flag is 0
  dat[5] = 0;                          // ensure that error flag is 0
  dat[6] = 0;

  RS485Master_Send(dat,1,160);


  RCIE_bit = 1;                        // enable interrupt on UART1 receive
  TXIE_bit = 0;                        // disable interrupt on UART1 transmit
  PEIE_bit = 1;                        // enable peripheral interrupts
  GIE_bit = 1;                         // enable all interrupts

  while (1){
                                       // upon completed valid message receiving
                                       //   data[4] is set to 255
    cnt++;
    if (dat[5])  {                     // if an error detected, signal it
      PORTD.B6 = 1;                    //   by setting portd to 0xAA
    }
    if (dat[4]) {                      // if message received successfully
      Lcd_Out(1,1,"MENSAGEM RECEBIDA");
      cnt = 0;
      dat[4] = 0;                      // clear message received flag
      j = dat[3];
      for (i = 1; i <= dat[3]; i++) {  // show data on PORTB
      dat[i-1];
      Lcd_Out(2,1,dat);
      Delay_ms(2000);
      }                                // increment received dat[0]
      dat[0] = dat[0]+1;               // send back to master
      Delay_ms(1);
      RS485Master_Send(dat,1,160);

    }
   if (cnt > 100000) {
      PORTD ++;
      cnt = 0;
      RS485Master_Send(dat,1,160);
      if (PORTD > 10)                  // if sending failed 10 times
      Lcd_Out(4,1,"FALHA");
        RS485Master_Send(dat,1,50);    //   send message on broadcast address
     }
  }

}
Slave code:

Code: Select all

char dat[9];             // buffer for receving/sending messages
char i,j;

sbit  rs485_rxtx_pin at RC2_bit;             // set transcieve pin
sbit  rs485_rxtx_pin_direction at TRISC2_bit;   // set transcieve pin direction

// Interrupt routine
void interrupt() {
 RS485Slave_Receive(dat);
}

void main() {
  ANSEL  = 0;                        // Configure AN pins as digital I/O
  ANSELH = 0;
  C1ON_bit = 0;                      // Disable comparators
  C2ON_bit = 0;

  PORTB = 0;
  PORTD = 0;
  TRISB = 0;
  TRISD = 0;


  UART1_Init(9600);                  // initialize UART1 module
  Delay_ms(100);
  RS485Slave_Init(160);              // Intialize MCU as slave, address 160

  dat[4] = 0;                        // ensure that message received flag is 0
  dat[5] = 0;                        // ensure that message received flag is 0
  dat[6] = 0;                        // ensure that error flag is 0

  RCIE_bit = 1;                      // enable interrupt on UART1 receive
  TXIE_bit = 0;                      // disable interrupt on UART1 transmit
  PEIE_bit = 1;                      // enable peripheral interrupts
  GIE_bit = 1;                       // enable all interrupts

  while (1) {
    if (dat[5])  {                   // if an error detected, signal it by
      PORTD = 0xAA;                  //   setting portd to 0xAA
      dat[5] = 0;
    }
    if (dat[4]) {                    // upon completed valid message receive
      dat[4] = 0;                    //   data[4] is set to 0xFF
      j = dat[3];
      for (i = 1; i <= dat[3];i++){
        PORTB = dat[i-1];
      }
      dat[0] = dat[0]+1;             // increment received dat[0]
      Delay_ms(1);
      RS485Slave_Send(dat,1);        //   and send it back to master
    }
  }
}
Attachments
master-slave.png
master-slave.png (82.65 KiB) Viewed 2998 times

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: RS-485 Master-Slave

#2 Post by filip » 21 Jun 2019 09:35

Hi,

Have you tried using the default RS-485 from the compiler ?

Regards,
Filip.

mmm
Posts: 38
Joined: 28 Apr 2019 18:25

Re: RS-485 Master-Slave

#3 Post by mmm » 17 Oct 2019 10:44

HI,
we want to use MODBUS RTU for PIC16F1526 MCU so please share the working code of MODBUS RTU and what something I should change for other MCUs(PIC16F1526).


Thank you

Post Reply

Return to “User Projects”