ModBus Slave RTU / ASCII tanpa SMS dan registrasi

gambar



Ada banyak perpustakaan yang tersedia untuk umum untuk mengimplementasikan perangkat ModBus Slave, tetapi mereka sering berisi fungsionalitas yang berlebihan, sulit dipelajari dan mengandung kesalahan besar. Artikel ini membahas perpustakaan, menurut pendapat penulis yang rendah hati, tanpa kekurangan ini.



Perangkat lunak perpustakaan disediakan sebagai kode C sumber terbuka.



modbus.h
////////////////////////////////////////////////////////////////////
//       ModBus v2   //
//     - I                                                      //
///////////////////////////////////////////////////////////////////
#ifndef __MODBUS_H
#define __MODBUS_H

#include "main.h"

///////////////////////////////////////////////////////////////////////////////
// 
//,   
#define ModBusUseGlobal (0) //  /, / 
//  
#define ModBusUseFunc1  (0) //  1  -   Coils (  )
#define ModBusUseFunc2  (0) //  2  -    
#define ModBusUseFunc3  (1) //  3  -    
#define ModBusUseFunc4  (0) //  4  -    
#define ModBusUseFunc5  (0) //  5  -   
#define ModBusUseFunc6  (1) //  6  -   
#define ModBusUseFunc15 (0) //  15 -    
#define ModBusUseFunc16 (1) //  16 -    
// 
#define ModBusID (1) //   
#define ModBusID_FF (255) //   ,    
//
#define ModBusMaxPause (5)//  ,     [mS], 
#define ModBusMaxPauseResp (2) //       [mS]
// 
#define ModBusMaxPaketRX (96)//    <127
// 
#define ModBusMaxInBit (0) //   
#define ModBusMaxInBitTX (8) //       
#define ModBusMaxInByte ((ModBusMaxInBit+7)/8) //    
// 
#define ModBusMaxOutBit (0) //  
#define ModBusMaxOutByte ((ModBusMaxOutBit+7)/8) //    
#define ModBusMaxOutBitTX (8) //       
#define ModBusMaxOutBitRX (8) //       
//   
#define ModBusMaxInReg (0) //   (   )
#define ModBusMaxInRegTX (24) //       
//   -
#define ModBusMaxOutReg (48) //  
#define ModBusMaxOutRegTX (32)//       
#define ModBusMaxOutRegRX (32)//        
////////////////////////////////////////////////////////////////////////////////
// ,   
// ,   
#define ModBusSysTimer TimingDelay
//      - void ModBusPUT(unsigned char A)
#define ModBusPUT(A) PutFifo0(A) 
//     , - unsigned short ModBusGET(void)
//    00000,   001
#define ModBusGET()  Inkey16Fifo0() 
////////////////////////////////////////////////////////////////////////////////

// 
void ModBusIni(void);

//    RTU
//     
//  ModbusPUT(A) ModbusGET()
void ModBusRTU(void);

//    ASCII
//     
//  ModbusPUT(A) ModbusGET()
void ModBusASCII(void);

//  
//       
void Prg2ModBusOutBit(void);
void Prg2ModBusInBit(void);
void Prg2ModBusOutReg(void);
void Prg2ModBusInReg(void);
//  
//       
void ModBus2PrgOutBit(void);
void ModBus2PrgOutReg(void);

#pragma pack(push,1)
//      /
typedef union
  {
  unsigned char byte;
  struct
    {
    unsigned char bit0:1;
    unsigned char bit1:1;
    unsigned char bit2:1;
    unsigned char bit3:1;
    unsigned char bit4:1;
    unsigned char bit5:1;
    unsigned char bit6:1;
    unsigned char bit7:1;
    };
  }
  ModBusBit_t;
#pragma pack(pop)
  
#ifdef __MODBUS2PRG_C
#if ModBusMaxInBit!=0
ModBusBit_t ModBusInBit[ModBusMaxInByte]; //  
#endif
#if ModBusMaxOutBit!=0
ModBusBit_t ModBusOutBit[ModBusMaxOutByte]; //  
#endif
#if ModBusMaxInReg!=0
unsigned short ModBusInReg[ModBusMaxInReg]; //  
#endif
#if ModBusMaxOutReg!=0
unsigned short ModBusOutReg[ModBusMaxOutReg]; //  
#endif
#else 
#if ModBusUseGlobal!=0 || defined(__MODBUS_C)
#if ModBusMaxInBit!=0
extern ModBusBit_t ModBusInBit[ModBusMaxInByte]; //  
#endif
#if ModBusMaxOutBit!=0
extern ModBusBit_t ModBusOutBit[ModBusMaxOutByte]; //  
#endif
#if ModBusMaxInReg!=0
extern unsigned short ModBusInReg[ModBusMaxInReg]; //  
#endif
#if ModBusMaxOutReg!=0
extern unsigned short ModBusOutReg[ModBusMaxOutReg]; //  
#endif
#endif//#if ModBusUseGlobal!=0
#endif//#ifdef __MODBUS2PRG_C
#endif//#ifndef __MODBUS_H




modbus.c
#define __MODBUS_C
#include "modbus.h"

static unsigned char PaketRX[ModBusMaxPaketRX];//   
static unsigned char UkPaket;//  ,    
static unsigned long TimModbus; //     
static unsigned short CRCmodbus;// CRC
static unsigned char Sost;// 0/1 /

// 
void ModBusIni(void)
  {
  TimModbus=ModBusSysTimer;// 
  UkPaket=0;//  
  CRCmodbus=0xFFFF; //   CRC
  //  
#if ModBusMaxOutBit!=0
  Prg2ModBusOutBit();
#endif  
#if ModBusMaxInBit!=0  
  Prg2ModBusInBit();
#endif  
#if ModBusMaxOutReg!=0  
  Prg2ModBusOutReg();
#endif  
#if ModBusMaxInReg!=0
  Prg2ModBusInReg();
#endif  
  return;
  }

//  CRC
static inline unsigned short CRCfunc(unsigned short inCRC, unsigned char in)
  {
  inCRC=inCRC^in;
  for(int j=0;j<8;j++){if(inCRC&1){inCRC=(inCRC>>1)^0xA001U;}else {inCRC=inCRC>>1;}}
  return inCRC;
  }

//   
void ModBusRTU(void)
  {
  if(Sost==0)
    {// 
    while(!0)
      {//  
      unsigned short Tmp=ModBusGET(); //    
      if(Tmp==0) return; //   -  
      // 
      Tmp=Tmp&0xFF;//   
      //    
      if((ModBusSysTimer-TimModbus)>ModBusMaxPause)
        {// ,    
        PaketRX[0]=Tmp;//     
        UkPaket=1;//  
        TimModbus=ModBusSysTimer;// 
        // CRC
        CRCmodbus=CRCfunc(0xFFFF,Tmp);
        continue;//  
        }
      else
        {//  ,    
        TimModbus=ModBusSysTimer;// 
        PaketRX[UkPaket]=Tmp;//  
        UkPaket++;//  
        if(UkPaket==ModBusMaxPaketRX)//   
          {//  
          UkPaket=0;//  
          CRCmodbus=0xFFFF; //   CRC
          return;//,    
          }
        // CRC
        CRCmodbus=CRCfunc(CRCmodbus,Tmp);
        }
      //   
      if(UkPaket<8) continue; //  
      //   
      if(CRCmodbus==0) 
        {//   
        if(PaketRX[1]==15 || PaketRX[1]==16)
          {//   (15,16) ,  " "
          if((PaketRX[6]+9)!=UkPaket) continue;
          }
        break; //!  !!!
        }
      }
    //////////////////////////////////////////////////////////////////////////////
    //                         !  !!!
    /////////////////////////////////////////////////////////////////////////////
    UkPaket=0;//  
    
    // 
    if((PaketRX[0]!=ModBusID)&&(PaketRX[0]!=ModBusID_FF))
      {//  
      CRCmodbus=0xFFFF; //   CRC
      return;//   
      }    
      
    //    
    Sost=!0;
#if ModBusMaxPauseResp!=0  
    return;//   
#endif 
    }
  
  ///////////////////////////////////////////////////////////////////////////// 
  if(Sost!=0 
#if ModBusMaxPauseResp!=0     
     && (ModBusSysTimer-TimModbus)>=ModBusMaxPauseResp
#endif     
     )
    {//  
    Sost=0;
    /////////////////////////////////////////////////////////////////////////////    
    //                                                          //
    /////////////////////////////////////////////////////////////////////////////
    //  01 -   Coils (  ). 
    /*-         . 
        0. 
     -      ,
           8  . 
         ,      . 
          .
    01    
           
            ON/OFF    . 
           
                   . 
              :  1-16   0-15.
                 20-56    17. 
           						
                                                                  (Hex) 
           					11	0
          						01	1
            Hi					00	2
            Lo					13	3
           Hi						00	4
           Lo						25	5
            (CRC  LRC)			--

           
                    .
                ,           0. 
                  . 
           						
                                                                  (Hex) 
           					11	0
          						01	1
           						05	2
          ( 27-20)					CD	3
          ( 35-28)					6B	4
          ( 43-36)					B2	5
          ( 51-44)					0E	6
          ( 56-52)					1B	7
            (CRC  LRC)			--
    */
#if ModBusUseFunc1!=0       
    if(PaketRX[1]==0x01)
      {
      //   
      unsigned short AdresBit=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //   
      unsigned short KolvoBit=((((unsigned short)PaketRX[4])<<8)|(PaketRX[5]));
      //    
      if((AdresBit+KolvoBit)>(ModBusMaxOutBit) || KolvoBit>ModBusMaxOutBitTX || KolvoBit==0)
        {//   
        CRCmodbus=0xFFFF; //   CRC
        return;//   
        }
      Prg2ModBusOutBit();//   (GlobalDate->ModBus)
      //  
      //
      ModBusPUT(PaketRX[0]);
      CRCmodbus=CRCfunc(0xFFFF,PaketRX[0]);
      //     
      ModBusPUT(1);
      CRCmodbus=CRCfunc(CRCmodbus,1);
      //  
      ModBusPUT((KolvoBit+7)>>3);
      CRCmodbus=CRCfunc(CRCmodbus,((KolvoBit+7)>>3));
      //    
      unsigned char TxByte=0;// 
      unsigned char Bit=AdresBit&7;//   ModBusOutBit[]
      AdresBit=AdresBit>>3;//  ModBusOutBit[]
      //   ModBusOutBit[]  
      int i=0;
      while(!0)
        {
        if((ModBusOutBit[AdresBit].byte)&(1<<Bit))
          {
          TxByte=TxByte|(1<<(i&7));
          }
        //  
        Bit++;
        if(Bit==8){Bit=0;AdresBit++;}
        i++;
        if((i&7)==0)
          {
          ModBusPUT(TxByte);
          CRCmodbus=CRCfunc(CRCmodbus,TxByte);
          TxByte=0;
          if(i==KolvoBit) break; else continue;
          }
        if(i==KolvoBit) 
          {
          ModBusPUT(TxByte);
          CRCmodbus=CRCfunc(CRCmodbus,TxByte);
          break;
          }
        }
      ModBusPUT(CRCmodbus);
      ModBusPUT(CRCmodbus>>8);
      //
      CRCmodbus=0xFFFF; //   CRC
      return;//    
      }
#endif    
    /////////////////////////////////////////////////////////////////////////////
    //  2 -    
    /*02 Read Input Status 
           
           ON/OFF    ( 1)  . 
           
                   .     0.
                 10197-10218    17. 
                   
           						
                                                                  (Hex) 
           					11	0
          						02	1
            .					00	2
            .					C4	3
          -  .					00	4
          -  .					16	5
           					--

           
                    .
                ,           0. 
                  . 
           						
                                                                  (Hex) 
           					11	0
          						01	1
           						03	2
          ( 10204-10197)				AC	3
          ( 10212-10205)				DB	4
          ( 10218-10213)				35	5
            (CRC  LRC)			--  
    */
#if ModBusUseFunc2!=0     
    if(PaketRX[1]==0x02)
      {
      //   
      unsigned short AdresBit=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //   
      unsigned short KolvoBit=((((unsigned short)PaketRX[4])<<8)|(PaketRX[5]));
      //    
      if((AdresBit+KolvoBit)>(ModBusMaxInBit) || KolvoBit>ModBusMaxInBitTX || KolvoBit==0)
        {//   
        CRCmodbus=0xFFFF; //   CRC
        return;//   
        }
      Prg2ModBusInBit();//   (GlobalDate->ModBus)
      //  
      //
      ModBusPUT(PaketRX[0]);
      CRCmodbus=CRCfunc(0xFFFF,PaketRX[0]);
      //     
      ModBusPUT(2);
      CRCmodbus=CRCfunc(CRCmodbus,2);
      //  
      ModBusPUT((KolvoBit+7)>>3);
      CRCmodbus=CRCfunc(CRCmodbus,((KolvoBit+7)>>3));
      //    
      unsigned char TxByte=0;// 
      unsigned char Bit=AdresBit&7;//  
      AdresBit=AdresBit>>3;//  
      //   ModBusInBit[]  
      int i=0;
      while(!0)
        {
        if((ModBusInBit[AdresBit].byte)&(1<<Bit))
          {//   
          TxByte=TxByte|(1<<(i&7));
          }
        //  
        Bit++;
        if(Bit==8){Bit=0;AdresBit++;}
        i++;
        if((i&7)==0)
          {
          ModBusPUT(TxByte);
          CRCmodbus=CRCfunc(CRCmodbus,TxByte);
          TxByte=0;
          if(i==KolvoBit) break; else continue;
          }
        if(i==KolvoBit)
          {
          ModBusPUT(TxByte);
          CRCmodbus=CRCfunc(CRCmodbus,TxByte);
          break;
          }
        }
      ModBusPUT(CRCmodbus);
      ModBusPUT(CRCmodbus>>8);
      //
      CRCmodbus=0xFFFF; //   CRC
      return;//   
      }
#endif    
    /////////////////////////////////////////////////////////////////////////////
    //  03 -   / . 
    /*-    /  ( ), 
        .     0.
    03 Read Holding Registers 
           
              ( 4)  . 
           
                   . 
              0:  1-16   0-15.
               40108-40110    17. 
           
           						
                                                                  (Hex) 
           					11	0
          						03	1
            .					00	2
            .					6B	3
          -  .					00	4
          -  .					03	5
           					--

           
                   . 
            ,          .
               125    984-8 (984-685  ..), 
           32    .      .
                : 
           
           						
                                                                  (Hex) 
           					11	0
          						03	1
           						06	2
           ( 40108) .				02	3
           ( 40108) .				2B	4
           ( 40109) .				00	5
           ( 40109) .				00	6
           ( 40110) .				00	7
           ( 40110) .				64	8
           					--
    */
#if ModBusUseFunc3!=0      
    if(PaketRX[1]==0x03)
      {
      //   
      unsigned short AdresWord=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //    
      unsigned short KolvoWord=((((unsigned short)PaketRX[4])<<8)|(PaketRX[5])); 
      //    
      if(((AdresWord+KolvoWord)>ModBusMaxOutReg) || (KolvoWord>ModBusMaxOutRegTX))
        {// 
        CRCmodbus=0xFFFF;//   CRC
        return;//,    
        }
      Prg2ModBusOutReg();//   (GlobalDate->ModBus)
      //  
      //
      ModBusPUT(PaketRX[0]);
      CRCmodbus=CRCfunc(0xFFFF,PaketRX[0]);
      //     
      ModBusPUT(3);
      CRCmodbus=CRCfunc(CRCmodbus,3);
      //  
      ModBusPUT(KolvoWord<<1);
      CRCmodbus=CRCfunc(CRCmodbus,(KolvoWord<<1));
      //   ModBusOutReg[]   
      for(int i=0;i<KolvoWord;i++)
        {
        ModBusPUT(ModBusOutReg[AdresWord+i]>>8);
        CRCmodbus=CRCfunc(CRCmodbus,(ModBusOutReg[AdresWord+i]>>8));
        ModBusPUT(ModBusOutReg[AdresWord+i]>>0);
        CRCmodbus=CRCfunc(CRCmodbus,(ModBusOutReg[AdresWord+i]>>0));
        }
      ModBusPUT(CRCmodbus);
      ModBusPUT(CRCmodbus>>8);
      //
      CRCmodbus=0xFFFF; //   CRC
      return;//   
      }
#endif     
    /////////////////////////////////////////////////////////////////////////////
    //  04 -    
    /*04 Read Input Registers 
           
               ( 3)  . 
           
                   .
                 30009    17. 
           
           						
                                                                  (Hex) 
           					11	0
          						03	1
            .					00	2
            .					6B	3
          -  .					00	4
          -  .					03	5
           					--
   
           
                   . 
            ,          .
               125    984-8 (984-685  ..), 
           32    .      .
                : 
           
           						
                                                                  (Hex) 
           					11	0
          						03	1
           						02	2
           ( 30009) .				00	3
           ( 30009) .				2A	4
           					--  
    */
#if ModBusUseFunc4!=0     
    if(PaketRX[1]==0x04)
      {
      //   
      unsigned short AdresWord=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //    
      unsigned short KolvoWord=((((unsigned short)PaketRX[4])<<8)|(PaketRX[5])); 
      //    
      if(((AdresWord+KolvoWord)>ModBusMaxInReg) || (KolvoWord>ModBusMaxInRegTX))
        {// 
        CRCmodbus=0xFFFF;//   CRC
        return;//,    
        }
      Prg2ModBusInReg();//   (GlobalDate->ModBus)
      //  
      //
      ModBusPUT(PaketRX[0]);
      CRCmodbus=CRCfunc(0xFFFF,(PaketRX[0]));
      //     
      ModBusPUT(4);
      CRCmodbus=CRCfunc(CRCmodbus,4);
      //  
      ModBusPUT(KolvoWord<<1);
      CRCmodbus=CRCfunc(CRCmodbus,(KolvoWord<<1));
      //   ModBusInReg[]   
      for(int i=0;i<KolvoWord;i++)
        {
        ModBusPUT(ModBusInReg[AdresWord+i]>>8);
        CRCmodbus=CRCfunc(CRCmodbus,(ModBusInReg[AdresWord+i]>>8));
        ModBusPUT(ModBusInReg[AdresWord+i]>>0);
        CRCmodbus=CRCfunc(CRCmodbus,(ModBusInReg[AdresWord+i]>>0));
        }
      ModBusPUT(CRCmodbus);
      ModBusPUT(CRCmodbus>>8);
      //
      CRCmodbus=0xFFFF; //   CRC
      return;//   
      }
#endif      
    /////////////////////////////////////////////////////////////////////////////
    //  05 -  / 
    /*05 Force Single Coil 
           
             ( 0)  ON  OFF. 
                       . 
                
                              . 
           
               .     0.  1   0.
          ,      (ON/OFF)    . 
           FF00 Hex - ON.  0000 - OFF.         .
                173   ON    17. 
           
           						
                                                                  (Hex) 
           					11	0
          						05	1
            .					00	2
            .					AC	3
           .						FF	4
           .						00	5
           					--
   
           
             . 
           
           						
                                                                  (Hex) 
           					11	0
          						05	1
            .					00	2
            .					AC	3
           .						FF	4
           .						00	5
           					--  
    */
#if ModBusUseFunc5!=0     
    if(PaketRX[1]==0x05)
      {
      //   
      unsigned short AdresBit=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //     
      if(AdresBit>=ModBusMaxOutBit)
        {//  
        CRCmodbus=0xFFFF; //   CRC
        return;//,    
        }
      //  
      switch (((((unsigned short)PaketRX[4])<<8)|(PaketRX[5])))
        {
        case 0xFF00:
        // 
        ModBusOutBit[(AdresBit>>3)].byte|=(1<<(AdresBit&7));
        break;
        case 0x0000:
        // 
        ModBusOutBit[(AdresBit>>3)].byte&=(~(1<<(AdresBit&7)));
        break;
        default:
          {//
          CRCmodbus=0xFFFF; //   CRC
          return;//,    
          } 
        }
      //
      for(int i=0;i<8;i++) ModBusPUT(PaketRX[i]);//   
      ModBus2PrgOutBit();//   (ModBus->GlobalDate)
      //
      CRCmodbus=0xFFFF; //   CRC
      return;//    
      }
#endif     
    /////////////////////////////////////////////////////////////////////////////
    //  06 -  / . 
    /*  05,     (). 
        /    . 
    06 Preset Single Register 
          .      ( 4).
                      . 
           
                . 
           
              ,   .    0.
          ,         . 
           M84  484  10-  ,     0. 
             16 .
                40002   0003 Hex    17. 
           
           						
                                                                  (Hex) 
           					11	0
          						06	1
            .					00	2
            .					01	3
           .						00	4
           .						03	5
           					--
   
           
             . 
           
           						
                                                                  (Hex) 
           					11	0
          						06	1
            .					00	2
            .					01	3
           .						00	4
           .						03	5
           					--  
    */
#if ModBusUseFunc6!=0    
    if(PaketRX[1]==0x06)
      {
      //   
      unsigned short AdresWord=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //     
      if(AdresWord>=(ModBusMaxOutReg))
        {//  
        CRCmodbus=0xFFFF; //   CRC
        return;//,    
        }
      // 
      ModBusOutReg[AdresWord]=(((((unsigned short)PaketRX[4])<<8)|(PaketRX[5])));
      //
      for(int i=0;i<8;i++) ModBusPUT(PaketRX[i]);//   
      ModBus2PrgOutReg();//   (ModBus->GlobalDate)
      //
      CRCmodbus=0xFFFF; //   CRC
      return;//   
      }
#endif     
    /////////////////////////////////////////////////////////////////////////////
    //  0x0F -   / . 
    /*     ,    ,     . 
    15 (0F Hex) Force Multiple Coils 
           
             ( 0)       ON  OFF. 
                   . 
                     . 
           
              .     0.
                    20 (  19) 
             17.
              2 : CD 01 Hex (1100 1101 0000 0001 ). 
               : 
          :    1  1  0  0  1  1  0  1		0  0  0  0  0  0   0  1 
          : 27 26 25 24 23 22 21 20		-  -  -  -  -  -  29 28 
           
           						
                                                                  (Hex) 
           					11	0
          						0F	1
            .					00	2
            .					13	3
          -  .					00	4
          -  .					0A	5
           						02	6
             ( 27-20)			CD	7
             ( 29-28) 			01	8
           					--	9
   
           
              ,  ,  ,    .
                . 
           
           						
                                                                  (Hex) 
           					11	0
          						0F	1
            .					00	2
            .					13	3
          -  .					00	4
          -  .					0A	5
           					--
    */
#if ModBusUseFunc15!=0    
    if(PaketRX[1]==0x0F)
      {
      //   
      unsigned short AdresBit=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //   
      unsigned short KolvoBit=(((((unsigned short)PaketRX[4])<<8)|(PaketRX[5])));
      //    
      if(((AdresBit+KolvoBit)>ModBusMaxOutBit) || (KolvoBit>ModBusMaxOutBitRX))
        {// 
        CRCmodbus=0xFFFF; //   CRC
        return;//,    
        }
      // 
      unsigned char Bit=(AdresBit&7);//   ModBusOutBit[]
      AdresBit=AdresBit>>3;//  ModBusOutBit[]
      //  
      for(int i=0;i<KolvoBit;i++)
        {
        if(PaketRX[7+(i>>3)]&(1<<(i&7)))//   PaketRX  1
          {//   ModBusOutBit[]
          ModBusOutBit[AdresBit].byte=(ModBusOutBit[AdresBit].byte)|((unsigned char)(1<<Bit));
          }
        else
          {//  ModBusOutBit[]
          ModBusOutBit[AdresBit].byte=(ModBusOutBit[AdresBit].byte)&((unsigned char)(~(1<<Bit)));
          }
        //  
        Bit++;if(Bit==8){Bit=0;AdresBit++;}
        }           
      // CRC    
      CRCmodbus=0xFFFF;
      for(int i=0;i<6;i++)
        {
        ModBusPUT(PaketRX[i]);
        CRCmodbus=CRCfunc(CRCmodbus,(PaketRX[i]));
        }
      ModBusPUT(CRCmodbus);
      ModBusPUT(CRCmodbus>>8);
          
      ModBus2PrgOutBit();//   (ModBus->GlobalDate)
      
      //
      CRCmodbus=0xFFFF; //   CRC
      return;//   
      }
#endif     
    //  0x10   / .
    /*16 (10 Hex) Preset Multiple Regs 
           
               ( 4). 
            ,        . 
           
                . 
           
              .     0.
                   . 
           M84  484  10- ,       0. 
              16 .
                    40002  00 0A  01 02 Hex, 
             17: 
           
           						
                                                                  (Hex) 
           					11	0
          						10	1
           					00	2
           					01	3
          -  .					00	4
          -  .					02	5
           						04	6
           .						00	7
           .						0A	8
           .						01	9
           .						02	10
           					--
   
           
              ,  ,  ,   . 
    */
#if ModBusUseFunc16!=0     
    if(PaketRX[1]==0x10)
      {
      //   
      unsigned short b=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //   
      unsigned short c=(((((unsigned short)PaketRX[4])<<8)|(PaketRX[5])));
      //    
      if(((b+c)>ModBusMaxOutReg) || c>ModBusMaxOutRegRX || c==0)
        {// 
        CRCmodbus=0xFFFF;//   CRC
        return;//,    
        }
      //     ModBusOutReg[]
      for(int i=0;i<c;i++)
        {
        ModBusOutReg[b+i]=(((unsigned short)PaketRX[7+(i<<1)])<<8)|(PaketRX[8+(i<<1)]);
        }
      // CRC    
      CRCmodbus=0xFFFF;
      for(int i=0;i<6;i++)
        {
        ModBusPUT(PaketRX[i]);
        CRCmodbus=CRCfunc(CRCmodbus,(PaketRX[i]));
        }
      ModBusPUT(CRCmodbus);
      ModBusPUT(CRCmodbus>>8);
      ModBus2PrgOutReg();//   (ModBus->GlobalDate)
      //
      CRCmodbus=0xFFFF; //   CRC
      return;//    
      }
#endif         
    /////////////////////////////////////////////////////////////////////////////
    // 
    CRCmodbus=0xFFFF; //   CRC
    return;////,  ,    
    }
  return;//    
  }

//     
static inline unsigned char Hex2Dig(unsigned char h)
  {
  if((h>='0')&&(h<='9')) return (h -'0');
  if((h>='A')&&(h<='F')) return (h -'A'+10);
  return 0;
  }
static unsigned char LRCmodbus;// LRC
static unsigned char Simvol0;//  
#define ASCII_CR (0x0D)//  
#define ASCII_LF (0x0A)// 
static const unsigned char BCD[]="0123456789ABCDEF";//     

//    ASCII
void ModBusASCII(void)
  {
  if(Sost==0)
    {// 
    while(!0)
      {//  
      unsigned short Tmp=ModBusGET(); //    
      if(Tmp==0) return; //       
      // 
      Tmp=Tmp&0xFF;//   
      //   
      if(Tmp==':')
        {// 
        LRCmodbus=0;// LRC
        UkPaket=0;//  ,   
        continue;//   
        }
       
      //   
      if(!(
           ((Tmp>='0')&&(Tmp<='9'))||
           ((Tmp>='A')&&(Tmp<='F'))||
           (Tmp==ASCII_CR)||
           (Tmp==ASCII_LF)
           )) 
        {
        return;//,    
        }
        
      //  
      if((UkPaket&1)==0)
        {//    0,2,4,6...
        Simvol0=Tmp; //   
        UkPaket++; //  
        continue;//   
        }
      else 
        {//    1,3,5,7...
        if(Tmp!=ASCII_LF)
          {//  
          PaketRX[UkPaket>>1]=(Hex2Dig(Simvol0)<<4)|(Hex2Dig(Tmp));//   
          LRCmodbus=LRCmodbus-PaketRX[UkPaket>>1];// LRC
          UkPaket++;//  
          if(UkPaket>(ModBusMaxPaketRX<<1))//  
            {//  
            UkPaket=0;//  
            return;//,    
            }
          }
        else break;
        }
      }      
    
    // LCR
    if(LRCmodbus!=0) return;//,    
    
    // 
    if((PaketRX[0]!=ModBusID)&&(PaketRX[0]!=ModBusID_FF))
      {//  
      return;//   
      }
      
    //   
    Sost=!0;
    TimModbus=ModBusSysTimer;// 
#if ModBusMaxPauseResp!=0  
    return;//   
#endif  
    }  
  
  ///////////////////////////////////////////////////////////////////////////// 
  if(Sost!=0 
#if ModBusMaxPauseResp!=0     
     && (ModBusSysTimer-TimModbus)>=ModBusMaxPauseResp
#endif     
     )
    {//  
    Sost=0;
    /////////////////////////////////////////////////////////////////////////////    
    //                                                          //
    /////////////////////////////////////////////////////////////////////////////
#if ModBusUseFunc1!=0     
    //01    
    if(PaketRX[1]==0x01)
      {
      //   
      unsigned short AdresBit=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //   
      unsigned short KolvoBit=((((unsigned short)PaketRX[4])<<8)|(PaketRX[5]));
      //    
      if((AdresBit+KolvoBit)>(ModBusMaxOutBit) || KolvoBit>ModBusMaxOutBitTX || KolvoBit==0)
        {//
        return;//,    
        }
      Prg2ModBusOutBit();//   (GlobalDate->ModBus)
      //  
      ModBusPUT(':');
      //
      ModBusPUT(BCD[PaketRX[0]>>4]);//  
      ModBusPUT(BCD[PaketRX[0]&0x0F]);// 
      LRCmodbus=0-PaketRX[0];// LRC
      //     
      ModBusPUT(BCD[1>>4]);//  
      ModBusPUT(BCD[1&0x0F]);// 
      LRCmodbus=LRCmodbus-1;// LRC
      //  
      ModBusPUT(BCD[((KolvoBit+7)>>3)>>4]);//  
      ModBusPUT(BCD[((KolvoBit+7)>>3)&0x0F]);// 
      LRCmodbus=LRCmodbus-((KolvoBit+7)>>3);// LRC
      //    
      unsigned char TxByte=0;// 
      unsigned char Bit=AdresBit&7;//   ModBusOutBit[]
      AdresBit=AdresBit>>3;//  ModBusOutBit[]
      //   ModBusOutBit[]  
      int i=0;
      while(!0)
        {
        if((ModBusOutBit[AdresBit].byte)&(1<<Bit))//   ModBusOutBit[]  1
          {//   
          TxByte=TxByte|(1<<(i&7));
          }
        //  
        Bit++;
        if(Bit==8){Bit=0;AdresBit++;}
        i++;
        if((i&7)==0)
          {
          ModBusPUT(BCD[TxByte>>4]);//  
          ModBusPUT(BCD[TxByte&0x0F]);// 
          LRCmodbus=LRCmodbus-TxByte;// LRC
          TxByte=0;
          if(i==KolvoBit) break; else continue;
          }
        if(i==KolvoBit) 
          {
          ModBusPUT(BCD[TxByte>>4]);//  
          ModBusPUT(BCD[TxByte&0x0F]);// 
          LRCmodbus=LRCmodbus-TxByte;// LRC
          break;
          }
        }
      ModBusPUT(BCD[LRCmodbus>>4]);
      ModBusPUT(BCD[LRCmodbus&0x0F]);
      ModBusPUT(ASCII_CR);
      ModBusPUT(ASCII_LF);
      //
      return;//   
      }
#endif
#if ModBusUseFunc2!=0     
    //02 Read Input Status 
    if(PaketRX[1]==0x02)
      {
      //   
      unsigned short AdresBit=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //   
      unsigned short KolvoBit=((((unsigned short)PaketRX[4])<<8)|(PaketRX[5]));
      //    
      if((AdresBit+KolvoBit)>(ModBusMaxInBit) || KolvoBit>ModBusMaxInBitTX || KolvoBit==0)
        {//
        return;//,    
        }
      Prg2ModBusInBit();//   (GlobalDate->ModBus)
      //  
      ModBusPUT(':');
      //
      ModBusPUT(BCD[PaketRX[0]>>4]);//  
      ModBusPUT(BCD[PaketRX[0]&0x0F]);// 
      LRCmodbus=0-PaketRX[0];// LRC
      //     
      ModBusPUT(BCD[2>>4]);//  
      ModBusPUT(BCD[2&0x0F]);// 
      LRCmodbus=LRCmodbus-2;// LRC
      //  
      ModBusPUT(BCD[((KolvoBit+7)>>3)>>4]);//  
      ModBusPUT(BCD[((KolvoBit+7)>>3)&0x0F]);// 
      LRCmodbus=LRCmodbus-((KolvoBit+7)>>3);// LRC
      //    
      unsigned char TxByte=0;// 
      unsigned char Bit=AdresBit&7;//   ModBusOutBit[]
      AdresBit=AdresBit>>3;//  ModBusOutBit[]
      //   ModBusOutBit[]  
      int i=0;
      while(!0)
        {
        if((ModBusInBit[AdresBit].byte)&(1<<Bit))//   ModBusOutBit[]  1
          {//   
          TxByte=TxByte|(1<<(i&7));
          }
        //  
        Bit++;
        if(Bit==8){Bit=0;AdresBit++;}
        i++;
        if((i&7)==0)
          {
          ModBusPUT(BCD[TxByte>>4]);//  
          ModBusPUT(BCD[TxByte&0x0F]);// 
          LRCmodbus=LRCmodbus-TxByte;// LRC
          TxByte=0;
          if(i==KolvoBit) break; else continue;
          }
        if(i==KolvoBit) 
          {
          ModBusPUT(BCD[TxByte>>4]);//  
          ModBusPUT(BCD[TxByte&0x0F]);// 
          LRCmodbus=LRCmodbus-TxByte;// LRC
          break;
          }
        }
      ModBusPUT(BCD[LRCmodbus>>4]);
      ModBusPUT(BCD[LRCmodbus&0x0F]);
      ModBusPUT(ASCII_CR);
      ModBusPUT(ASCII_LF);
      //
      return;//   
      }
#endif
#if ModBusUseFunc3!=0     
    //03 Read Holding Registers 
    if(PaketRX[1]==0x03)
      {
      //   
      unsigned short AdresWord=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //    
      unsigned short KolvoWord=((((unsigned short)PaketRX[4])<<8)|(PaketRX[5])); 
      //    
      if(((AdresWord+KolvoWord)>ModBusMaxOutReg) || KolvoWord>ModBusMaxOutRegTX)
        {// 
        return;//,    
        }
      Prg2ModBusOutReg();//   (GlobalDate->ModBus)
      //  
      ModBusPUT(':');
      //
      ModBusPUT(BCD[PaketRX[0]>>4]);//  
      ModBusPUT(BCD[PaketRX[0]&0x0F]);// 
      LRCmodbus=0-PaketRX[0];// LRC
      // 
      ModBusPUT(BCD[3>>4]);//  
      ModBusPUT(BCD[3&0x0F]);// 
      LRCmodbus=LRCmodbus-3;// LRC
      //  
      ModBusPUT(BCD[(KolvoWord<<1)>>4]);//  
      ModBusPUT(BCD[(KolvoWord<<1)&0x0F]);// 
      LRCmodbus=LRCmodbus-(KolvoWord<<1);// LRC
      //   ModBusOutReg[]   
      for(int i=0;i<KolvoWord;i++)
        {
        ModBusPUT(BCD[((ModBusOutReg[AdresWord+i])>>8)>>4]);//  
        ModBusPUT(BCD[((ModBusOutReg[AdresWord+i])>>8)&0x0F]);// 
        LRCmodbus=LRCmodbus-((ModBusOutReg[AdresWord+i])>>8);// LRC
        ModBusPUT(BCD[(((ModBusOutReg[AdresWord+i])>>0)>>4)&0x0F]);//  
        ModBusPUT(BCD[(((ModBusOutReg[AdresWord+i])>>0)>>0)&0x0F]);// 
        LRCmodbus=LRCmodbus-((ModBusOutReg[AdresWord+i])>>0);// LRC
        }
      ModBusPUT(BCD[LRCmodbus>>4]);
      ModBusPUT(BCD[LRCmodbus&0x0F]);
      ModBusPUT(ASCII_CR);
      ModBusPUT(ASCII_LF);
      //
      return;//   
      }
#endif
#if ModBusUseFunc4!=0     
    //04 Read Input Registers 
    if(PaketRX[1]==0x04)
      {
      //   
      unsigned short AdresWord=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //    
      unsigned short KolvoWord=((((unsigned short)PaketRX[4])<<8)|(PaketRX[5])); 
      //    
      if(((AdresWord+KolvoWord)>ModBusMaxOutReg) || KolvoWord>ModBusMaxOutRegTX)
        {// 
        return;//,    
        }
      Prg2ModBusInReg();//   (GlobalDate->ModBus)
      //  
      ModBusPUT(':');
      //
      ModBusPUT(BCD[PaketRX[0]>>4]);//  
      ModBusPUT(BCD[PaketRX[0]&0x0F]);// 
      LRCmodbus=0-PaketRX[0];// LRC
      // 
      ModBusPUT(BCD[4>>4]);//  
      ModBusPUT(BCD[4&0x0F]);// 
      LRCmodbus=LRCmodbus-4;// LRC
      //  
      ModBusPUT(BCD[(KolvoWord<<1)>>4]);//  
      ModBusPUT(BCD[(KolvoWord<<1)&0x0F]);// 
      LRCmodbus=LRCmodbus-(KolvoWord<<1);// LRC
      //   ModBusOutReg[]   
      for(int i=0;i<KolvoWord;i++)
        {
        ModBusPUT(BCD[((ModBusInReg[AdresWord+i])>>8)>>4]);//  
        ModBusPUT(BCD[((ModBusInReg[AdresWord+i])>>8)&0x0F]);// 
        LRCmodbus=LRCmodbus-((ModBusInReg[AdresWord+i])>>8);// LRC
        ModBusPUT(BCD[(((ModBusInReg[AdresWord+i])>>0)>>4)&0x0F]);//  
        ModBusPUT(BCD[(((ModBusInReg[AdresWord+i])>>0)>>0)&0x0F]);// 
        LRCmodbus=LRCmodbus-((ModBusInReg[AdresWord+i])>>0);// LRC
        }
      ModBusPUT(BCD[LRCmodbus>>4]);
      ModBusPUT(BCD[LRCmodbus&0x0F]);
      ModBusPUT(ASCII_CR);
      ModBusPUT(ASCII_LF);
      //
      return;//   
      }
#endif
#if ModBusUseFunc5!=0     
    //05 Force Single Coil 
    if(PaketRX[1]==0x05)
      {
      //   
      unsigned short AdresBit=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //     
      if(AdresBit>=ModBusMaxOutBit)//  
        {// 
        return;//,    
        }
      //  
      switch (((((unsigned short)PaketRX[4])<<8)|(PaketRX[5])))
        {
        case 0xFF00:
        // 
        ModBusOutBit[(AdresBit>>3)].byte|=(1<<(AdresBit&7));
        break;
        case 0x0000:
        // 
        ModBusOutBit[(AdresBit>>3)].byte&=(~(1<<(AdresBit&7)));
        break;
        default:
          { //
          return;//,    
          } 
        }
              
      //
      ModBusPUT(':');
      for(int i=0;i<7;i++)
        {
        ModBusPUT(BCD[PaketRX[i]>>4]);//  
        ModBusPUT(BCD[PaketRX[i]&0x0F]);// 
        }
      ModBusPUT(ASCII_CR);
      ModBusPUT(ASCII_LF);
         
      ModBus2PrgOutBit();//   (ModBus->GlobalDate)
      
      //
      return;//    
      }
#endif
#if ModBusUseFunc6!=0     
    //06 Preset Single Register 
    if(PaketRX[1]==0x06)
      {
      //   
      unsigned short AdresWord=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      
      //     
      if(AdresWord>=(ModBusMaxOutReg))//  
        {// 
        return;//,    
        }
      // 
      ModBusOutReg[AdresWord]=(((((unsigned short)PaketRX[4])<<8)|(PaketRX[5])));
      
      //
      ModBusPUT(':');
      for(int i=0;i<7;i++)
        {
        ModBusPUT(BCD[PaketRX[i]>>4]);//  
        ModBusPUT(BCD[PaketRX[i]&0x0F]);// 
        }
      ModBusPUT(ASCII_CR);
      ModBusPUT(ASCII_LF);
      
      ModBus2PrgOutReg();//   (ModBus->GlobalDate)
        
      //
      return;//   
      }
#endif
#if ModBusUseFunc15!=0      
    //15 (0F Hex) Force Multiple Coils 
    if(PaketRX[1]==0x0F)
      {
      //   
      unsigned short AdresBit=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //   
      unsigned short KolvoBit=(((((unsigned short)PaketRX[4])<<8)|(PaketRX[5])));
      //    
      if(((AdresBit+KolvoBit)>ModBusMaxOutBit) || (KolvoBit>ModBusMaxOutBitRX))
        {// 
        return;//,    
        }
      // 
      unsigned char Bit=(AdresBit&7);//   ModBusOutBit[]
      AdresBit=AdresBit>>3;//  ModBusOutBit[]
      //  
      for(int i=0;i<KolvoBit;i++)
        {
        if(PaketRX[7+(i>>3)]&(1<<(i&7)))//   PaketRX  1
          {//   ModBusOutBit[]
          ModBusOutBit[AdresBit].byte=(ModBusOutBit[AdresBit].byte)|((unsigned char)(1<<Bit));
          }
        else
          {//  ModBusOutBit[]
          ModBusOutBit[AdresBit].byte=(ModBusOutBit[AdresBit].byte)&((unsigned char)(~(1<<Bit)));
          }
        //  
        Bit++;if(Bit==8){Bit=0;AdresBit++;}
        }           
      
      // LRC    
      LRCmodbus=0;
      ModBusPUT(':');
      for(int i=0;i<6;i++)
        {
        ModBusPUT(BCD[PaketRX[i]>>4]);//  
        ModBusPUT(BCD[PaketRX[i]&0x0F]);// 
        LRCmodbus=LRCmodbus-PaketRX[i];// LRC
        }
      ModBusPUT(BCD[LRCmodbus>>4]);
      ModBusPUT(BCD[LRCmodbus&0x0F]);
      ModBusPUT(ASCII_CR);
      ModBusPUT(ASCII_LF);
      
      ModBus2PrgOutBit();//   (ModBus->GlobalDate)
      
      //
      return;//   
      }
#endif
#if ModBusUseFunc16!=0        
    //16 (10 Hex) Preset Multiple Regs 
    if(PaketRX[1]==0x10)
      {
      //   
      unsigned short b=(((((unsigned short)PaketRX[2])<<8)|(PaketRX[3])));
      //   
      unsigned short c=(((((unsigned short)PaketRX[4])<<8)|(PaketRX[5])));
      
      //    
      if(((b+c)>ModBusMaxOutReg) || c>ModBusMaxOutRegRX)
        {
        // 
        return;//,    
        }
      //     ModBusOutReg[]
      for(int i=0;i<c;i++)
        {
        ModBusOutReg[b+i]=(((unsigned short)PaketRX[7+(i<<1)])<<8)|(PaketRX[8+(i<<1)]);
        }
      
      // LRC    
      LRCmodbus=0;
      ModBusPUT(':');
      for(int i=0;i<6;i++)
        {
        ModBusPUT(BCD[PaketRX[i]>>4]);//  
        ModBusPUT(BCD[PaketRX[i]&0x0F]);// 
        LRCmodbus=LRCmodbus-PaketRX[i];// LRC
        }
      ModBusPUT(BCD[LRCmodbus>>4]);
      ModBusPUT(BCD[LRCmodbus&0x0F]);
      ModBusPUT(ASCII_CR);
      ModBusPUT(ASCII_LF);
      
      ModBus2PrgOutReg();//   (ModBus->GlobalDate)
      
      //
      return;//    
      }
#endif    
    } 
  //
  return;//,  ,    
  }




ModBus2Prg.c
#define __MODBUS2PRG_C
#include "modbus.h"

//  
//       
void Prg2ModBusOutBit(void)
  {//   
  
  return;
  }

void Prg2ModBusInBit(void)
  {//   
  //ModBusInBit[0].bit0=1;
  
  return;
  }

void Prg2ModBusOutReg(void)
  {//  4   /
  
  return;
  }

void Prg2ModBusInReg(void)
  {//  3   
  
  return;
  }

//  
//        
void ModBus2PrgOutBit(void)
  {//   
  
  return;
  }

void ModBus2PrgOutReg(void)
  {//  4   /
  
  return;
  }




File modbus.h berisi deklarasi yang diperlukan, opsi kompilasi, dan konstanta tuning. Mari kita jelaskan secara singkat opsi utama dan parameter penyetelan.



ModBusUseFunc1 - ModBusUseFunc15 - opsi kompilasi yang menentukan penggunaan fungsi protokol ModBus. Implementasi praktis perangkat ModBus bekerja dengan sekumpulan fungsi protokol yang terbatas, paling sering, fungsi 3,6 dan 16. Tidak perlu menyertakan kode tambahan dalam proyek.



ModBusID, ModBusID_FF - Alamat di bus ModBus. Implementasi protokol ini mendukung dua alamat. Ini dapat berguna untuk menugaskan perangkat, alamat ModBusID adalah alamat perangkat yang dapat dikonfigurasi, dan alamat ModBusID_FF adalah alamat untuk menyesuaikan perangkat.



ModBusMaxPause- Jeda antar karakter, untuk menentukan awal paket, diatur dalam quanta ModBusSysTimer. Biasanya, kuantum ModBusSysTimer adalah 1ms. Untuk sebagian besar aplikasi, kepatuhan dengan batas waktu yang dijelaskan dalam standar protokol tidak mungkin dilakukan.



Misalnya, ModBus Master yang dijalankan pada mesin Win tidak akan pernah dapat menyediakan waktu tunggu yang diperlukan oleh protokol. Oleh karena itu, pengaturan potongan waktu kurang dari 1 mS dapat dianggap tidak praktis. Pengamatan praktis menunjukkan bahwa nilai ModBusMaxPause harus sekitar 5-10 mS.



ModBusMaxPauseResp - Jeda antara permintaan Master dan tanggapan Slave. Banyak perangkat ModBus Master mengalami penundaan dalam peralihan dari transmisi ke penerimaan, penundaan ini dapat dikompensasikan dengan konstanta ini.



ModBusMaxInBit, ModBusMaxOutBit, ModBusMaxInReg, ModBusMaxOutReg- Jumlah input, output, register untuk membaca, register untuk membaca / menulis. Program ini menyimpan memori untuk register ModBus. Jika tipe register tertentu tidak digunakan, nilainya harus ditentukan sebagai nol.



ModBusMaxInBitTX, ModBusMaxOutBitTX, ModBusMaxInRegTX, ModBusMaxOutRegTX - Jumlah maksimum input, output, register diskrit untuk membaca, register untuk membaca / menulis register output dalam paket yang ditransmisikan. Pengaturan ini harus cocok dengan pengaturan yang sesuai pada ModBus Master.



Untuk mem-port pustaka ke platform apa pun, Anda harus menentukan tiga fungsi melalui makro.



ModBusSysTimer- Timer sistem, variabel yang bertambah setiap milidetik dalam rangkaian eksekusi terpisah. Variabel ini bisa uwTick, dari perpustakaan STM32 HAL, atau jam fungsi C standar () .



void ModBusPUT (unsigned char A) - Menulis byte ke aliran serial.



unsigned short ModBusGET (void) - Membaca byte dari serial stream. Jika tidak ada data di aliran serial, fungsi mengembalikan 0, jika ada data, maka nilai yang dikembalikan adalah byte tinggi 0x01, byte rendah adalah data yang dibaca.



Untuk menggunakan perpustakaan, Anda perlu mengisi isi fungsi Prg2ModBusOutBit (), Prg2ModBusInBit (), Prg2ModBusOutReg (), Prg2ModBusInReg ()bertanggung jawab untuk menyalin variabel pengguna ke register ModBus. Selain itu, perlu untuk mengisi badan fungsi



ModBus2PrgOutBit (), ModBus2PrgOutReg () , yang bertanggung jawab untuk menyalin register ModBus ke dalam variabel pengguna. Di badan fungsi ini, Anda dapat melakukan beberapa tindakan yang terkait dengan mengubah register, misalnya, memeriksa nilai yang valid.



Contohnya:



void Prg2ModBusOutReg(void)
  {// , 4   /
  ModBusOutReg[0]=A;
  ModBusOutReg[1]=B;
  ModBusOutReg[2]=C;
  return;
  }
void ModBus2PrgOutReg(void)
  { //  4,   /
  if(ModBusOutReg[0] < MaxA) A= ModBusOutReg[0];
  B=ModBusOutReg[1];
  C=ModBusOutReg[2];
  return;
  }


Diperbolehkan untuk tidak mengisi badan fungsi yang ditentukan, tetapi untuk bekerja dengan register secara langsung, saat menggunakan opsi ModBusUseGlobal .



Untuk menginisialisasi perangkat ModBus, panggil fungsi ModBusIni () . Fungsi ModBusRTU () atau ModBusASCII () masing-masing menyediakan operasi perangkat melalui protokol RTU dan ASCII. Mereka harus dipanggil di loop utama program:



ModBusIni();
while(!0)
  {
  if(ModBusTip==RTU) ModBusRTU(); else ModBusASCII();
  }


Jangan lupa bahwa sebelum menginisialisasi dan memanggil fungsi yang memastikan pengoperasian perangkat ModBus, Anda harus berhati-hati saat menginisialisasi serial stream (UART). Keputusan perangkat lunak yang terkait dengan organisasi streaming I / O bergantung pada platform perangkat keras, dan pertimbangan mereka berada di luar cakupan artikel ini.



Pustaka ini diuji dengan server Kepware OPC, panel SIMATIC dan Wientek, serta ModBus Master lainnya, di berbagai perangkat berdasarkan mikrokontroler PIC dan STM32, dan menunjukkan kinerja 142%. Kemudahan porting library ini akan membuatnya mudah untuk diadaptasikan ke jenis mikrokontroler 8-16-32-bit lainnya.



All Articles