ModBus Slave RTU / ASCII sans SMS ni enregistrement

image



Il existe de nombreuses bibliothèques accessibles au public pour la mise en œuvre de périphériques ModBus Slave, mais elles contiennent souvent des fonctionnalités redondantes, sont difficiles à apprendre et contiennent des erreurs grossières. Cet article traite d'une bibliothèque, selon l'humble avis de l'auteur, dépourvue de ces lacunes.



Le logiciel de la bibliothèque est fourni sous forme de code C open source.



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




Le fichier modbus.h contient les déclarations requises, les options de compilation et les constantes de réglage. Décrivons brièvement les principales options et paramètres de réglage.



ModBusUseFunc1 - ModBusUseFunc15 - option de compilation qui détermine l'utilisation des fonctions du protocole ModBus. Les implémentations pratiques des appareils ModBus fonctionnent avec un ensemble limité de fonctions de protocole, le plus souvent les fonctions 3, 6 et 16. Il n'est pas nécessaire d'inclure du code supplémentaire dans le projet.



ModBusID, ModBusID_FF - Adresses sur le bus ModBus. Cette implémentation du protocole prend en charge deux adresses. Cela peut être utile pour la mise en service des appareils, l'adresse ModBusID est l'adresse de l'appareil configurable et l'adresse ModBusID_FF est l'adresse de personnalisation de l'appareil.



ModBusMaxPause- La pause entre les caractères, pour déterminer le début du paquet, est définie dans les quanta ModBusSysTimer. En règle générale, le quantum ModBusSysTimer est de 1 ms. Pour la plupart des applications, le respect des délais d'expiration décrits dans la norme de protocole est tout simplement impossible.



Par exemple, ModBus Master exécuté sur une machine Win ne pourra jamais fournir les délais requis par le protocole. Par conséquent, définir une tranche de temps inférieure à 1 ms peut être considéré comme peu pratique. Des observations pratiques montrent que la valeur ModBusMaxPause doit être d'environ 5 à 10 mS.



ModBusMaxPauseResp - Pause entre la demande du maître et la réponse de l'esclave. De nombreux appareils ModBus Master ont un retard dans le passage de l'émission à la réception, ce retard peut être compensé par cette constante.



ModBusMaxInBit, ModBusMaxOutBit, ModBusMaxInReg, ModBusMaxOutReg- Le nombre d'entrées TOR, de sorties, de registres de lecture, de registres de lecture / écriture. Le programme réserve de la mémoire pour les registres ModBus. Si un certain type de registres n'est pas utilisé, la valeur doit être spécifiée comme zéro.



ModBusMaxInBitTX, ModBusMaxOutBitTX, ModBusMaxInRegTX, ModBusMaxOutRegTX - Le nombre maximum d'entrées TOR, de sorties, de registres de lecture, de registres de lecture / écriture des registres de sortie dans le paquet transmis. Ce paramètre doit correspondre au paramètre correspondant sur le maître ModBus.



Pour porter la bibliothèque sur n'importe quelle plate-forme, vous devez spécifier trois fonctions via des macros.



ModBusSysTimer- Minuterie système, une variable qui est incrémentée toutes les millisecondes dans un thread d'exécution distinct. Cette variable peut être uwTick, de la bibliothèque STM32 HAL, ou l' horloge de la fonction C standard () .



void ModBusPUT (unsigned char A) - Ecriture d'un octet dans un flux série.



unsigned short ModBusGET (void) - Lit un octet à partir d'un flux série. S'il n'y a pas de données dans le flux série, la fonction renvoie 0, s'il y a des données, alors la valeur de retour est l'octet haut 0x01, l'octet bas - lire les données.



Pour utiliser la bibliothèque, vous devez remplir le corps des fonctions Prg2ModBusOutBit (), Prg2ModBusInBit (), Prg2ModBusOutReg (), Prg2ModBusInReg ()responsable de la copie des variables utilisateur dans les registres ModBus. En outre, il est nécessaire de remplir le corps des fonctions



ModBus2PrgOutBit (), ModBus2PrgOutReg () , qui sont responsables de la copie des registres ModBus dans les variables utilisateur. Dans le corps de ces fonctions, vous pouvez effectuer certaines actions liées à la modification des registres, par exemple, vérifier les valeurs valides.



Par exemple:



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


Il est permis de ne pas remplir le corps des fonctions spécifiées, mais de travailler directement avec les registres, en utilisant l'option ModBusUseGlobal .



Pour initialiser un appareil ModBus, appelez la fonction ModBusIni () . Les fonctions ModBusRTU () ou ModBusASCII () assurent le fonctionnement de l'appareil en utilisant respectivement les protocoles RTU et ASCII. Ils doivent être appelés dans la boucle principale du programme:



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


N'oubliez pas qu'avant d'initialiser et d'appeler la fonction qui assure le fonctionnement de l'appareil ModBus, vous devez vous occuper de l'initialisation du flux série (UART). Les décisions logicielles liées à l'organisation des E / S en continu dépendent de la plate-forme matérielle et leur prise en compte dépasse le cadre de cet article.



Cette bibliothèque a été testée avec le serveur Kepware OPC, les panneaux SIMATIC et Wientek, ainsi que d'autres maîtres ModBus, dans une variété d'appareils basés sur les microcontrôleurs PIC et STM32, et a montré ses 142% de performances. La facilité de portage de cette bibliothèque facilitera son adaptation à d'autres types de microcontrôleurs 8-16-32 bits.



All Articles