11 Aralık 2018, 18:09:14

Haberler:

Foruma Resim Yükleme ve Boyut Sınırlaması ( ! )  https://bit.ly/2GMFb8H


CCS C modbus rtu sorunum

Başlatan gokhangokcen, 07 Eylül 2017, 18:04:49

gokhangokcen

Merhaba üstadlar,
Modbus RTU üzerine çalışmalar yapmaktayım.Program üzerinde deneme yanılma üzerine ilerliyorum. Elimde Delta VFD-USB01 RS485 çevirici var. Şu an devre board üzerine kurulu olduğu için şema paylaşamıyorum. Öncelikle kod üzerinde bariz hatalarım var ise ya da şu şekilde ilerle diyebileceğiniz noktalar var ise oradan adım adım düzenleyip ilerlemek istiyorum. Kodlarım şu şekilde;
Kod Seç

//--------------------------40 pin MCU PIN_diagram
//                        _____________
//MCLR/VPP----------------|1         40|-------RB7/PGD
//RA0/AN0-----------------|2         39|-------RB6/PGC
//RA1/AN1-----------------|3         38|-------RB5
//RA2/AN2/VREF-/CVREF-----|4         37|-------RB4
//RA3/AN3/VREF+-----------|5         36|-------RB3/PGM
//RA4/T0CKI/C1OUT---------|6         35|-------RB2
//RA5/AN4/SS/C2OUT--------|7         34|-------RB1
//RE0/RD/AN5--------------|8         33|-------RB0/INT
//RE1/WR/AN6--------------|9         32|-------VDD
//RE2/CS/AN7--------------|10        31|-------VSS
//VDD---------------------|11        30|-------RD7/PSP7
//VSS---------------------|12        29|-------RD6/PSP6
//OSC1/CLKI---------------|13        28|-------RD5/PSP5
//OSC2/CLKO---------------|14        27|-------RD4/PSP4
//RC0/T1OSO/T1CKI---------|15        26|-------RC7/RX/DT
//RC1/T1OSI/CCP2----------|16        25|-------RC6/TX/CK
//RC2/CCP1----------------|17        24|-------RC5/SDO
//RC3/SCK/SCL-------------|18        23|-------RC4/SDI/SDA
//RD0/PSP0----------------|19        22|-------RD3/PSP3
//RD1/PSP1----------------|20        21|-------RD2/PSP2
//                        |____________|


#include <main.h>
#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_C5
#define MODBUS_SERIAL_RX_ENABLE PIN_C4
#define MODBUS_SERIAL_BAUD 9600
#define MODBUS_OUR_ADDRESS 10
#include "modbus.c"

//#use fast_io(a)
//#use fast_io(b)
//#use fast_io(c)
//#use fast_io(d)
//#use fast_io(e)

#define LCD_ENABLE_PIN  PIN_D1
#define LCD_RS_PIN      PIN_D2
#define LCD_RW_PIN      PIN_D3
#define LCD_DATA4       PIN_D4
#define LCD_DATA5       PIN_D5
#define LCD_DATA6       PIN_D6
#define LCD_DATA7       PIN_D7

#include "lcd.c"

#define MODBUS_ADDRESS 0x05

#define OUT1   PIN_C0
#define OUT2   PIN_C1
#define OUT3   PIN_C2
#define OUT4   PIN_C3

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;


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()
{

   
//set_tris_a(0xFF);
   //set_tris_e(0b111);
   //set_tris_b(0x00);
   //set_tris_c(0b10000000);
   //set_tris_d(0x00);
   
   
modbus_init();
   
lcd_init();
   
delay_ms(1000);
   
   
lcd_gotoxy(1,1);
   
delay_ms(100);
   
lcd_putc("GOKHAN");
   
delay_ms(100);


   while(
TRUE)
   {
   
output_toggle(OUT1);
   
delay_ms(500);
      if (
bit_test(coils,0) == 1)
         
OUTPUT_HIGH(OUT1);
      else
         
OUTPUT_LOW(OUT1);
         
      if (
bit_test(coils,1) == 1)
         
OUTPUT_HIGH(OUT2);
      else
         
OUTPUT_LOW(OUT2);
         
      if (
bit_test(coils,2) == 1)
         
OUTPUT_HIGH(OUT3);
      else
         
OUTPUT_LOW(OUT3);
         
      if (
bit_test(coils,3) == 1)
         
OUTPUT_HIGH(OUT4);
      else
         
OUTPUT_LOW(OUT4);
   
      while(!
modbus_kbhit());

      
delay_us(50);

      
//check address against our address, 0 is broadcast
      
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] >= || 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_coils_rsp(MODBUS_ADDRESS0x01, &data);
                  else
                     
modbus_read_discrete_input_rsp(MODBUS_ADDRESS0x01, &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] >= || 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] >= || 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=0modbus_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] >= || 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=5modbus_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);
         }
      }
  }
}


Başlangıçta lcd ekranı ve modbus kütüphanesini init edip ekrana GOKHAN yazdırıyorum. Sonrasında modbus işliyor diye düşünüyorum. Bağlantılarım ise şu şekilde;

16F877A                   SN75176

RX>>>>>>>>>>>>4 nolu pin
TX>>>>>>>>>>>>1 nolu pin
PIN_C5>>>>>>>>>3 nolu pin
PIN_C4>>>>>>>>>2 nolu pin

A-B uçları direkt olarak 75176'ya bağlı arada herhangi bir direnç vs yok.


Bildiğini paylaşmak, Allah'ın verdiği öğrenme yeteneğinin zekatıdır.

gokhangokcen

Belki bir arkadaşa faydası dokunur. Şu anda program 2x16 lcd ekranın 2. satırına Modbus RTU'dan gelen yazma isteği üzerine yazılan değişkeni göstermektedir. Slave ID 5'dir. İstenildiği taktirde program içerisinden müdahale edilebilir. CCS'nin default kütüphane kodudur. İnclude dosyalarını kendi klasöründen rahatlıkla bulabilirsiniz. Program default olarak 16bit 8 adet değişken adresi, 8 adet output,8 adet input barındırmaktadır. Programda tanımlandığı gibi outputları istediğiniz pinlere yönlendirebilirsiniz. Örnekte 0. adresteki output pini PIN_C0  şeklindedir.

Kod Seç

//--------------------------40 pin MCU PIN_diagram
//                        _____________
//MCLR/VPP----------------|1         40|-------RB7/PGD
//RA0/AN0-----------------|2         39|-------RB6/PGC
//RA1/AN1-----------------|3         38|-------RB5
//RA2/AN2/VREF-/CVREF-----|4         37|-------RB4
//RA3/AN3/VREF+-----------|5         36|-------RB3/PGM
//RA4/T0CKI/C1OUT---------|6         35|-------RB2
//RA5/AN4/SS/C2OUT--------|7         34|-------RB1
//RE0/RD/AN5--------------|8         33|-------RB0/INT
//RE1/WR/AN6--------------|9         32|-------VDD
//RE2/CS/AN7--------------|10        31|-------VSS
//VDD---------------------|11        30|-------RD7/PSP7
//VSS---------------------|12        29|-------RD6/PSP6
//OSC1/CLKI---------------|13        28|-------RD5/PSP5
//OSC2/CLKO---------------|14        27|-------RD4/PSP4
//RC0/T1OSO/T1CKI---------|15        26|-------RC7/RX/DT
//RC1/T1OSI/CCP2----------|16        25|-------RC6/TX/CK
//RC2/CCP1----------------|17        24|-------RC5/SDO
//RC3/SCK/SCL-------------|18        23|-------RC4/SDI/SDA
//RD0/PSP0----------------|19        22|-------RD3/PSP3
//RD1/PSP1----------------|20        21|-------RD2/PSP2
//                        |____________|


#include <main.h>
#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_C5
#define MODBUS_SERIAL_RX_ENABLE PIN_C4
#define MODBUS_SERIAL_BAUD 9600
#define MODBUS_OUR_ADDRESS 10
#include "modbus.c"

//#use fast_io(a)
//#use fast_io(b)
//#use fast_io(c)
//#use fast_io(d)
//#use fast_io(e)



#define LCD_ENABLE_PIN  PIN_D1
#define LCD_RS_PIN      PIN_D2
#define LCD_RW_PIN      PIN_D3
#define LCD_DATA4       PIN_D4
#define LCD_DATA5       PIN_D5
#define LCD_DATA6       PIN_D6
#define LCD_DATA7       PIN_D7

#include "lcd.c"

#define MODBUS_ADDRESS 0x05

#define OUT1   PIN_C0
#define OUT2   PIN_C1
#define OUT3   PIN_C2
#define OUT4   PIN_C3

int8 coils 0b00000000;
int8 inputs 0b00000000;
int16 hold_regs[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
int16 input_regs[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
int16 event_count 0;


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);
}

#zero_ram
void main()
{

   
//set_tris_a(0xFF);
   //set_tris_e(0b111);
   //set_tris_b(0x00);
   //set_tris_c(0b10000000);
   //set_tris_d(0x00);
   
   
modbus_init();
   
lcd_init();
   
delay_ms(1000);
   
   
lcd_gotoxy(1,1);
   
delay_ms(100);
   
lcd_putc("GOKHAN");
   
delay_ms(100);


   while(
TRUE)
   {
      if (
bit_test(coils,0) == 1)
         
OUTPUT_HIGH(OUT1);
      else
         
OUTPUT_LOW(OUT1);
         
      if (
bit_test(coils,1) == 1)
         
OUTPUT_HIGH(OUT2);
      else
         
OUTPUT_LOW(OUT2);
         
      if (
bit_test(coils,2) == 1)
         
OUTPUT_HIGH(OUT3);
      else
         
OUTPUT_LOW(OUT3);
         
      if (
bit_test(coils,3) == 1)
         
OUTPUT_HIGH(OUT4);
      else
         
OUTPUT_LOW(OUT4);
         
     
lcd_gotoxy(1,2);
     
printf(lcd_putc,"%4LX",hold_regs[0]); 
   
      while(!
modbus_kbhit());

      
delay_us(50);

      
//check address against our address, 0 is broadcast
      
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] >= || 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_coils_rsp(MODBUS_ADDRESS0x01, &data);
                  else
                     
modbus_read_discrete_input_rsp(MODBUS_ADDRESS0x01, &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] >= || 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] >= || 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=0modbus_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] >= || 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=5modbus_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);
         }
      }
  }
}


Bağlantılar ise şöyle;
Default olarak programdan  RX ve TX pini seçmediğinizde (Wizard ile Modbus RTU kodu oluştururken) hardware USART pinlerini kullanılıyor. 75176 kullandım konvertör olarak.

1. Pin-> işlemci RX pinine,
2. Pin-> Programdaki tanımlanan RX enable pini,
3. Pin-> Programdaki tanımlanan Serial enable pini,
4. Pin-> İşlemci TX pinine,
5. Pin-> GND,
6. Pin-> Modbus hattı,
7. Pin-> Modbus hattı,
8. Pin-> +5V,

LCD bağlantıları zaten programda belirlenebiliyor. İşlemci beslemesi ve reset osc pinleri standart işlemciye göre bağlantı yapılır. Cümleten iyi günler dilerim.


Bildiğini paylaşmak, Allah'ın verdiği öğrenme yeteneğinin zekatıdır.

PROTECH_

http://www.modbus.pl/Modbus%20Tester_MODBUS.PL.html

Bu programı  firmware'ini test edebilirsin.
Başlangıçta direk rs232 ile iletişim kurmanı tavsiye ederim. rx,tx,gnd pinleri ve herhangi bir usb seri çevirici yeterli olur.

RTX MODBUS  RTOS - istanbul--berlin

gokhangokcen

Teşekkür ederim hocam, Modbus Pool ile testlerimi yaptım gayet güzel çalışıyor ama demo olmasından dolayı 10 dk'da kapatmamı istiyor 30 gün gibide süresi var bitmek üzere verdiğiniz programı deneyeceğim.
Bildiğini paylaşmak, Allah'ın verdiği öğrenme yeteneğinin zekatıdır.

rattlesnake

Alıntı yapılan: gokhangokcen - 12 Eylül 2017, 14:12:16Teşekkür ederim hocam, Modbus Pool ile testlerimi yaptım gayet güzel çalışıyor ama demo olmasından dolayı 10 dk'da kapatmamı istiyor 30 gün gibide süresi var bitmek üzere verdiğiniz programı deneyeceğim.

Hocam selamün aleyküm, hemşeriymişiz.

Bana da tam senin projen ihtiyaçtı. Kodlarını kullanmak istedim. Söylediklerinin aynısını yapıyorum yalnız nedense transmitter enable pini bir türlü aktif olmuyor. Hem transmitteri hem de LCD yi arduino platformunda kullandım bir problem yoktu.

Yardımcı olursan çok sevinirim, benim için bu çok büyük dert oldu.

Kullandığım kod

Kod Seç
#include <16F877A.h> 
#device ADC=10 

#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD 
#use delay(crystal=20MHz) 
//--------------------------40 pin MCU PIN_diagram
//                        _____________
//MCLR/VPP----------------|1         40|-------RB7/PGD
//RA0/AN0-----------------|2         39|-------RB6/PGC
//RA1/AN1-----------------|3         38|-------RB5
//RA2/AN2/VREF-/CVREF-----|4         37|-------RB4
//RA3/AN3/VREF+-----------|5         36|-------RB3/PGM
//RA4/T0CKI/C1OUT---------|6         35|-------RB2
//RA5/AN4/SS/C2OUT--------|7         34|-------RB1
//RE0/RD/AN5--------------|8         33|-------RB0/INT
//RE1/WR/AN6--------------|9         32|-------VDD
//RE2/CS/AN7--------------|10        31|-------VSS
//VDD---------------------|11        30|-------RD7/PSP7
//VSS---------------------|12        29|-------RD6/PSP6
//OSC1/CLKI---------------|13        28|-------RD5/PSP5
//OSC2/CLKO---------------|14        27|-------RD4/PSP4
//RC0/T1OSO/T1CKI---------|15        26|-------RC7/RX/DT
//RC1/T1OSI/CCP2----------|16        25|-------RC6/TX/CK
//RC2/CCP1----------------|17        24|-------RC5/SDO
//RC3/SCK/SCL-------------|18        23|-------RC4/SDI/SDA
//RD0/PSP0----------------|19        22|-------RD3/PSP3
//RD1/PSP1----------------|20        21|-------RD2/PSP2
//                        |____________|

#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_C5
#define MODBUS_SERIAL_RX_ENABLE PIN_C5
#define MODBUS_SERIAL_BAUD 9600
#define MODBUS_OUR_ADDRESS 10
#include "modbus.c"

//#use fast_io(a)
//#use fast_io(b)
//#use fast_io(c)
//#use fast_io(d)
//#use fast_io(e)



#define LCD_ENABLE_PIN  PIN_D1
#define LCD_RS_PIN      PIN_D2
#define LCD_RW_PIN      PIN_D3
#define LCD_DATA4       PIN_D4
#define LCD_DATA5       PIN_D5
#define LCD_DATA6       PIN_D6
#define LCD_DATA7       PIN_D7

#include "lcd.c"

#define MODBUS_ADDRESS 0x05

#define OUT1   PIN_C0
#define OUT2   PIN_C1
#define OUT3   PIN_C2
#define OUT4   PIN_C3

int8 coils 0b00000000;
int8 inputs 0b00000000;
int16 hold_regs[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
int16 input_regs[] = {0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};
int16 event_count 0;


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);
}

#zero_ram
void main()
{

   
//set_tris_a(0xFF);
   //set_tris_e(0b111);
   //set_tris_b(0x00);
   //set_tris_c(0b10000000);
   //set_tris_d(0x00);
   
   
modbus_init();
   
lcd_init();
   
delay_ms(1000);
   
   
lcd_gotoxy(1,1);
   
delay_ms(100);
   
lcd_putc("GOKHAN");
   
delay_ms(100);


   while(
TRUE)
   {
      if (
bit_test(coils,0) == 1)
         
OUTPUT_HIGH(OUT1);
      else
         
OUTPUT_LOW(OUT1);
         
      if (
bit_test(coils,1) == 1)
         
OUTPUT_HIGH(OUT2);
      else
         
OUTPUT_LOW(OUT2);
         
      if (
bit_test(coils,2) == 1)
         
OUTPUT_HIGH(OUT3);
      else
         
OUTPUT_LOW(OUT3);
         
      if (
bit_test(coils,3) == 1)
         
OUTPUT_HIGH(OUT4);
      else
         
OUTPUT_LOW(OUT4);
         
     
lcd_gotoxy(1,2);
     
printf(lcd_putc,"%4LX",hold_regs[0]); 
   
      while(!
modbus_kbhit());

      
delay_us(50);

      
//check address against our address, 0 is broadcast
      
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] >= || 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_coils_rsp(MODBUS_ADDRESS0x01, &data);
                  else
                     
modbus_read_discrete_input_rsp(MODBUS_ADDRESS0x01, &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] >= || 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] >= || 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=0modbus_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] >= || 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=5modbus_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);
         }
      }
  }
}

Kodta bir yerlerde yanlış yapıyorum sanıyorum. Halbuki pic tanımlamaları dışında her şey seninkinin aynısı.

Yardımcı olursan çok sevinirim.

İyi akşamlar.

gokhangokcen

@rattlesnake mesajını yeni gördüm rx_enable ile tx_enable pinlerinin ikisinide PIN_C5 olarak tanımlamışsın bu pinler birbirinin değili olduğu için son fonksiyonda pini low yapıyordur o yüzden aktif olmaz. Olması gereken ya tek bir tane pin kullanacaksın 485 entegresinde rx_tx-enable pinlerini kısa devre yapacaksın ya da iki farklı pin tanımlayıp bağlayacaksın.
Bildiğini paylaşmak, Allah'ın verdiği öğrenme yeteneğinin zekatıdır.

omerglal1

gökhan kardeşim merhaba.
modbus poll da test yaptığımda timeout error hatası alıyorum. Bu konuda bir bilgin var mı? iyi çalışmalar.

gokhangokcen

@omerglal1 üstad devreni görmeden yorum yapmam zor. herşey olabilir. slave id hatalı olabilir, devren çalışmıyor olabilir, bozuk malzeme olabilir, a-b uçları ters olabilir.. vb. şeyleri çoğaltmak mümkün.
Bildiğini paylaşmak, Allah'ın verdiği öğrenme yeteneğinin zekatıdır.

omerglal1

tamamdır çözdüm problemi. enable pinlerini ters bağlamışım. cevabın için teşekkürler.


umutaymn

İyi günler , projenin şemasını paylaşabilme şansınız var mı acaba?

gokhangokcen

@umutaymn projenin şemasını paylaşacak bir durum yok zaten kodda bütün pinlerin nereye bağlı olduğu yazıyor.
Bildiğini paylaşmak, Allah'ın verdiği öğrenme yeteneğinin zekatıdır.