Modbus RTU Haberleşme.

Başlatan rattlesnake, 28 Mayıs 2018, 01:49:11

rattlesnake

Hocalarım merahaba

2 gündür pic16f877a' i slave olarak veri yollamaya, ara bir modül ile bu veriyi rs485' e çevirip rs485 to usb ile modbus pool üzerinden verileri okumaya çalısıyorum. Ne yaptıysam olmadı. Kullandığım kod aşağıda lütfen yazdımcı olun neyi yanlıs yapıyorum, var mı bir öneriniz?

I'm using this hardware
http://elektrotasarim.com/UARTtoRS485_Breakout.html
datasheet
http://elektrotasarim.com/UARTtoRS485_Breakout.pdf





#include <16F877A.h> 
#device ADC=16 

#FUSES NOWDT                    //No Watch Dog Timer 
#FUSES HS
#FUSES NOBROWNOUT               //No brownout reset 
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O 

#use delay(clock=20000000)   // osilatör hızı 
#define MODBUS_TYPE MODBUS_TYPE_SLAVE 
#define MODBUS_SERIAL_TYPE MODBUS_RTU     //use MODBUS_ASCII for ASCII mode 
#define MODBUS_SERIAL_RX_BUFFER_SIZE 64 
#define MODBUS_SERIAL_BAUD 9600 

#ifndef USE_WITH_PC 
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA 
#define MODBUS_SERIAL_TX_PIN PIN_C6 // Data transmit pin 
#define MODBUS_SERIAL_RX_PIN PIN_C7   // Data receive pin 
//The following should be defined for RS485 communication 
#define MODBUS_SERIAL_ENABLE_PIN  PIN_A3   // Controls DE pin for RS485 
#define MODBUS_SERIAL_RX_ENABLE   PIN_A3 // Controls RE pin for RS485 
#endif 

#include <modbus.c> 

#define MODBUS_ADDRESS 3 

int8 swap_bits(int8 c) 
{ 
   return ((c&1)?128:0)|((c&2)?64:0)|((c&4)?32:0)|((c&8)?16:0)|((c&16)?8:0) 
          |((c&32)?4:0)|((c&64)?2:0)|((c&128)?1:0); 
} 

void main() 
{ 
   int8 coils = 0b00000101; 
   int8 inputs = 0b00001001; 
   int16 hold_regs[] = {0x8800,0x7700,0x6600,0x5500,0x4400,0x3300,0x2200,0x1100}; 
   int16 input_regs[] = {0x1100,0x2200,0x3300,0x4400,0x5500,0x6600,0x7700,0x8800}; 
   int16 event_count = 0; 

   setup_adc_ports(NO_ANALOGS); 

   modbus_init(); 

   while(TRUE) 
   { 

    hold_regs[0]=100; 
    
//!    input_regs[1]=0xAA; 
//!    input_regs[2]=0xAA; 
  //  hold_regs[0]=0x55; 
//!    hold_regs[1]=0x55; 
//!    hold_regs[2]=0x55; 
    
      while(!modbus_kbhit()); 
      //check address against our address, 0 is broadcast 
       delay_us(50); 
      if((modbus_rx.address == MODBUS_ADDRESS) || modbus_rx.address == 0) 
      { 
         switch(modbus_rx.func) 
         { 
            case FUNC_READ_COILS:    //read coils 
            case FUNC_READ_DISCRETE_INPUT:    //read inputs 
               if(modbus_rx.data[0] || modbus_rx.data[2] || 
                  modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8) 
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS); 
               else 
               { 
                  int8 data; 

                  if(modbus_rx.func == FUNC_READ_COILS) 
                     data = coils>>(modbus_rx.data[1]);      //move to the starting coil 
                  else 
                     data = inputs>>(modbus_rx.data[1]);      //move to the starting input 

                  data = data & (0xFF>>(8-modbus_rx.data[3]));  //0 out values after quantity 

                  if(modbus_rx.func == FUNC_READ_COILS) 
                     modbus_read_discrete_input_rsp(MODBUS_ADDRESS, 0x01, &data); 
                  else 
                     modbus_read_discrete_input_rsp(MODBUS_ADDRESS, 0x01, &data); 

                  event_count++; 
               } 
               break; 
            case FUNC_READ_HOLDING_REGISTERS: 
            case FUNC_READ_INPUT_REGISTERS: 
               if(modbus_rx.data[0] || modbus_rx.data[2] || 
                  modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8) 
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS); 
               else 
               { 
                  if(modbus_rx.func == FUNC_READ_HOLDING_REGISTERS) 
                     modbus_read_holding_registers_rsp(MODBUS_ADDRESS,(modbus_rx.data[3]*2),hold_regs+modbus_rx.data[1]); 
                  else 
                     modbus_read_input_registers_rsp(MODBUS_ADDRESS,(modbus_rx.data[3]*2),input_regs+modbus_rx.data[1]); 

                  event_count++; 
               } 
               break; 
            case FUNC_WRITE_SINGLE_COIL:      //write coil 
               if(modbus_rx.data[0] || modbus_rx.data[3] || modbus_rx.data[1] > 8) 
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS); 
               else if(modbus_rx.data[2] != 0xFF && modbus_rx.data[2] != 0x00) 
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_VALUE); 
               else 
               { 
                  if(modbus_rx.data[2] == 0xFF) 
                     bit_set(coils,modbus_rx.data[1]); 
                  else 
                     bit_clear(coils,modbus_rx.data[1]); 

                  modbus_write_single_coil_rsp(MODBUS_ADDRESS,modbus_rx.data[1],((int16)(modbus_rx.data[2]))<<8); 

                  event_count++; 
               } 
               break; 
            case FUNC_WRITE_SINGLE_REGISTER: 
               if(modbus_rx.data[0] || modbus_rx.data[1] >= 8) 
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS); 
               else 
               { 
                  hold_regs[modbus_rx.data[1]] = make16(modbus_rx.data[2],modbus_rx.data[3]); 

                  modbus_write_single_register_rsp(MODBUS_ADDRESS, 
                               make16(modbus_rx.data[0],modbus_rx.data[1]), 
                               make16(modbus_rx.data[2],modbus_rx.data[3])); 
               } 
               break; 
            case FUNC_WRITE_MULTIPLE_COILS: 
               if(modbus_rx.data[0] || modbus_rx.data[2] || 
                  modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8) 
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS); 
               else 
               { 
                  int i,j; 

                  modbus_rx.data[5] = swap_bits(modbus_rx.data[5]); 

                  for(i=modbus_rx.data[1],j=0; i < modbus_rx.data[1]+modbus_rx.data[3]; ++i,++j) 
                  { 
                     if(bit_test(modbus_rx.data[5],j)) 
                        bit_set(coils,7-i); 
                     else 
                        bit_clear(coils,7-i); 
                  } 

                  modbus_write_multiple_coils_rsp(MODBUS_ADDRESS, 
                                 make16(modbus_rx.data[0],modbus_rx.data[1]), 
                                 make16(modbus_rx.data[2],modbus_rx.data[3])); 

                  event_count++; 
               } 
               break; 
            case FUNC_WRITE_MULTIPLE_REGISTERS: 
               if(modbus_rx.data[0] || modbus_rx.data[2] || 
                  modbus_rx.data[1] >= 8 || modbus_rx.data[3]+modbus_rx.data[1] > 8) 
                  modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_DATA_ADDRESS); 
               else 
               { 
                  int i,j; 

                  for(i=0,j=5; i < modbus_rx.data[4]/2; ++i,j+=2) 
                     hold_regs[i] = make16(modbus_rx.data[j],modbus_rx.data[j+1]); 

                  modbus_write_multiple_registers_rsp(MODBUS_ADDRESS, 
                                 make16(modbus_rx.data[0],modbus_rx.data[1]), 
                                 make16(modbus_rx.data[2],modbus_rx.data[3])); 

                  event_count++; 
               } 
               break; 
            default:    //We don't support the function, so return exception 
               modbus_exception_rsp(MODBUS_ADDRESS,modbus_rx.func,ILLEGAL_FUNCTION); 
         } 
      } 
  } 
}

deneme_1234

Burada bir örnek mevcut bakabilirsiniz.

gokhangokcen

@rattlesnake üstad , sanırım rx_enable ve tx_enable pinleri ile ilgili sıkıntın var. bu kodu ben defalarca kullandım çalışıyor.

#define MODBUS_BUS SERIAL
#define MODBUS_TYPE MODBUS_TYPE_SLAVE
#define MODBUS_SERIAL_TYPE MODBUS_RTU
#define MODBUS_SERIAL_INT_SOURCE MODBUS_INT_RDA
#define MODBUS_SERIAL_ENABLE_PIN PIN_D4
#define MODBUS_SERIAL_RX_ENABLE PIN_D5
#define MODBUS_SERIAL_BAUD 9600
#define MODBUS_ADDRESS 1
#include "modbus.c"

ben bu şekilde kullanıyorum. RDA kesmesi ilgili pinlere bağlı rx ve tx enable pinleride bu şekilde tanımlı.
Bildiğini paylaşmak, Allah'ın verdiği öğrenme yeteneğinin zekatıdır.