ModBus Slave RTU / ASCII sin SMS ni registro

imagen



Hay muchas bibliotecas disponibles públicamente para implementar dispositivos ModBus Slave, pero a menudo contienen funcionalidad redundante, son difíciles de aprender y contienen errores graves. Este artículo analiza una biblioteca, en la humilde opinión del autor, desprovista de estos defectos.



El software de la biblioteca se suministra como código C de fuente abierta.



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




El archivo modbus.h contiene las declaraciones necesarias, las opciones de compilación y las constantes de ajuste. Describamos brevemente las principales opciones y parámetros de ajuste.



ModBusUseFunc1 - ModBusUseFunc15 - opción de compilación que determina el uso de funciones del protocolo ModBus. Las implementaciones prácticas de los dispositivos ModBus funcionan con un conjunto limitado de funciones de protocolo, la mayoría de las veces las funciones 3,6 y 16. No es necesario incluir código adicional en el proyecto.



ModBusID, ModBusID_FF : direcciones en el bus ModBus. Esta implementación del protocolo admite dos direcciones. Esto puede ser útil para la puesta en servicio de dispositivos, la dirección ModBusID es la dirección del dispositivo configurable y la dirección ModBusID_FF es la dirección para personalizar el dispositivo.



ModBusMaxPause- La pausa entre caracteres, para determinar el comienzo del paquete, se establece en los cuantos ModBusSysTimer. Normalmente, el cuanto ModBusSysTimer es de 1 ms. Para la mayoría de las aplicaciones, el cumplimiento de los tiempos de espera descritos en el protocolo estándar es simplemente imposible.



Por ejemplo, un ModBus Master que se ejecuta en una máquina Win nunca podrá proporcionar los tiempos de espera requeridos por el protocolo. Por lo tanto, establecer un intervalo de tiempo inferior a 1 mS puede considerarse poco práctico. Las observaciones prácticas muestran que el valor de ModBusMaxPause debe ser de aproximadamente 5-10 mS.



ModBusMaxPauseResp : pausa entre la solicitud del maestro y la respuesta del esclavo. Muchos dispositivos ModBus Master tienen una demora en el cambio de la transmisión a la recepción, esta demora puede compensarse con esta constante.



ModBusMaxInBit, ModBusMaxOutBit, ModBusMaxInReg, ModBusMaxOutReg- El número de entradas discretas, salidas, registros para lectura, registros para lectura / escritura. El programa reserva memoria para registros ModBus. Si no se utiliza cierto tipo de registros, el valor debe especificarse como cero.



ModBusMaxInBitTX, ModBusMaxOutBitTX, ModBusMaxInRegTX, ModBusMaxOutRegTX : el número máximo de entradas discretas, salidas, registros para lectura, registros para lectura / escritura de registros de salida en el paquete transmitido. Esta configuración debe coincidir con la configuración correspondiente en ModBus Master.



Para portar la biblioteca a cualquier plataforma, debe especificar tres funciones a través de macros.



ModBusSysTimer- Temporizador del sistema, una variable que se incrementa cada milisegundo en un hilo de ejecución separado. Esta variable puede ser uwTick, de la biblioteca STM32 HAL, o el reloj de función C estándar () .



void ModBusPUT (unsigned char A) : escribir un byte en una secuencia en serie.



ModBusGET corto sin firmar (void) : lee un byte de una secuencia en serie. Si no hay datos en el flujo en serie, la función devuelve 0, si hay datos, entonces el valor de retorno es el byte alto 0x01, el byte bajo son los datos leídos.



Para usar la biblioteca, debe completar el cuerpo de las funciones Prg2ModBusOutBit (), Prg2ModBusInBit (), Prg2ModBusOutReg (), Prg2ModBusInReg ()responsable de copiar las variables de usuario a los registros ModBus. Además, es necesario completar el cuerpo de las



funciones ModBus2PrgOutBit (), ModBus2PrgOutReg () , que se encargan de copiar los registros ModBus en variables de usuario. En el cuerpo de estas funciones, puede realizar algunas acciones relacionadas con el cambio de registros, por ejemplo, verificar valores válidos.



Por ejemplo:



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


Se permite no completar el cuerpo de las funciones especificadas, sino trabajar con registros directamente, mientras se usa la opción ModBusUseGlobal .



Para inicializar un dispositivo ModBus, llame a la función ModBusIni () . Las funciones ModBusRTU () o ModBusASCII () proporcionan la operación del dispositivo utilizando los protocolos RTU y ASCII, respectivamente. Deben llamarse en el bucle principal del programa:



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


No olvide que antes de inicializar y llamar a la función que asegura el funcionamiento del dispositivo ModBus, debe encargarse de inicializar el flujo serie (UART). Las decisiones de software relacionadas con la organización de la transmisión de E / S dependen de la plataforma de hardware y su consideración está más allá del alcance de este artículo.



Esta librería fue probada con el servidor Kepware OPC, paneles SIMATIC y Wientek, así como otros ModBus Masters, en una variedad de dispositivos basados ​​en microcontroladores PIC y STM32, y mostró su rendimiento del 142%. La facilidad de portar esta biblioteca facilitará su adaptación a otros tipos de microcontroladores de 8-16-32 bits.



All Articles