⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modbus_00_00.st

📁 moudbus通讯协议, moudbus通讯协议, moudbus通讯协议,
💻 ST
📖 第 1 页 / 共 2 页
字号:
  END_IF // _no_of_points
 END_IF // Start_Adresse
END_IF // Funktion = 3 und 4


//-----------------------------------------------------------------------
// Funktion No.: 5;   Beschreiben der Ausg刵g
//
IF _m_function = 5 THEN
 IF _start_address < 16#000 | _start_address > IOSize THEN
  _exception_code := 2;                          // illegal data address
 ELSE
//---- Ausg刵ge beschreiben ----
//   _a := 0;
   _set_address := _start_address;

   if _rd_latch[4] =  16#ff then 

	     SETBit(_set_address, 1);            


		else

	     SETBit(_set_address, 0);            

	end_if;

//---- Response --------------------------
   _tx_buffer[0] := SLAVE_ADDRESS$USINT;             // Header aufbauen
   _tx_buffer[1] := _m_function;
   _tx_buffer[2] := _rd_latch[2];               // Coil Address Hi
   _tx_buffer[3] := _rd_latch[3];               // Coil Address Lo
   _tx_buffer[4] := _rd_latch[4];               // Quantity of Coils Hi
   _tx_buffer[5] := _rd_latch[5];               // Quantity of Coils Lo
   _n_bytes := 6;                              // Header = 6 Bytes
   _crc_result := CALKCRC(TO_UINT(_n_bytes), _poi_tx_buff);  // CRC..
   (_poi_tx_buff$^HINT + _n_bytes)^ := _crc_result;        // hinten dran
   _n_bytes += 2;                                   // sind 2 Byte mehr

	ret1 := SERUSER_Send(pHandle, _poi_tx_buff, _n_bytes, #WrLen1);

   IF ret1 THEN
    _tx_back := 1;                                            // Fehler
   ELSE
    _tx_back := 0;                                        // in Ordnung
   END_IF // CF
   _exception_code  := 0;
   _mb_error        := 0;
//  END_IF // _no_of_points
 END_IF // Start_Adresse
END_IF // Funktion = 5


//-----------------------------------------------------------------------
// Funktion No.: 6;   Beschreiben der Datenspeicher
//
IF _m_function = 6 THEN
 IF _start_address < 0 | _start_address > (DataSize-2) THEN
  _exception_code := 2;                        // illegal data address
 ELSE
//---- Datenspeicher beschreiben ----
   _set_address := _start_address;

    SETBYTE(_set_address+1, _rd_latch[7]);    // [7] = 1.Hi-Byte
    SETBYTE(_set_address+0, _rd_latch[8]);    // [8] = 1.Lo-Byte

//---- Response --------------------------
   _tx_buffer[0] := SLAVE_ADDRESS$USINT;                  // Header aufbauen
   _tx_buffer[1] := _m_function;
   _tx_buffer[2] := _rd_latch[2];                // Starting Address Hi
   _tx_buffer[3] := _rd_latch[3];                // Starting Address Lo
   _tx_buffer[4] := _rd_latch[4];                      // No of Regs Hi
   _tx_buffer[5] := _rd_latch[5];                      // No of Regs Lo
   _n_bytes := 6;                                  // Header = 6 Bytes
   _crc_result := CALKCRC(TO_UINT(_n_bytes), _poi_tx_buff);    // CRC..
   (_poi_tx_buff$^HINT + _n_bytes)^ := _crc_result;       // hinten dran
   _n_bytes += 2;                                  // sind 2 Byte mehr

	ret1 := SERUSER_Send(pHandle, _poi_tx_buff, _n_bytes, #WrLen1);

   IF ret1 THEN
    _tx_back := 1;                                           // Fehler
   ELSE
    _tx_back := 0;                                       // in Ordnung
   END_IF // CF
   _exception_code  := 0;
   _mb_error        := 0;
 END_IF // Start_Adresse
END_IF // Funktion = 6


//-----------------------------------------------------------------------
// Funktion No.: 15;   Beschreiben der Ausg刵ge
//
IF _m_function = 15 THEN
 IF _start_address < 00 | _start_address > IOSize THEN
  _exception_code := 2;                          // illegal data address
 ELSE
  IF _no_of_points < 1 | _no_of_points > 127 THEN
   _exception_code := 3;                           // illegal data value
  ELSE
//---- Ausg刵ge beschreiben ----
   _a := 0;
   _set_address := _start_address;
   _set_mask    := 16#ff;
   _bit_ctr     := _no_of_points;
   WHILE _a < _rd_latch[6] DO                         // [6] = Byte Count
    IF _bit_ctr < 8 THEN                    // falls kein ganzes Byte...
     _shift_ctr := TO_USINT(8 - _bit_ctr);
     _set_mask  := _set_mask SHR _shift_ctr;         // dann maskieren.
    END_IF
    IF (_set_address AND 2#00000011) = 2#00000010 THEN
     _set_address += 1;               // falls Adress-Loch, dann weiter.
    END_IF
    IF (_set_address AND 2#00000011) = 2#00000011 THEN
     _set_address += 1;
    END_IF

    IF _bit_ctr < 8 THEN                       // falls kein ganzes Byte
     _old_byte := GETBYTE(_set_address);       // altes Bitmuster holen
     _bin_1    := 16#ff XOR _set_mask;          // Maske invertieren
     _old_byte := _old_byte AND _bin_1;          // neuen Teil loschen
     _bin_1    := _rd_latch[7+_a] AND _set_mask;// neuen Teil vorbereiten
     _bin_1    := _bin_1 OR _old_byte;           // Alten dazu
     SETBYTE(_set_address, _bin_1);            // raus
    ELSE
     SETBYTE(_set_address, _rd_latch[7+_a]);    // [7] = 1.Datenbyte
    END_IF

    _a += 1;
    _set_address += 1;
    _bit_ctr -= 8;
   END_WHILE
//---- Response --------------------------
   _tx_buffer[0] := SLAVE_ADDRESS$USINT;             // Header aufbauen
   _tx_buffer[1] := _m_function;
   _tx_buffer[2] := _rd_latch[2];               // Coil Address Hi
   _tx_buffer[3] := _rd_latch[3];               // Coil Address Lo
   _tx_buffer[4] := _rd_latch[4];               // Quantity of Coils Hi
   _tx_buffer[5] := _rd_latch[5];               // Quantity of Coils Lo
   _n_bytes := 6;                              // Header = 6 Bytes
   _crc_result := CALKCRC(TO_UINT(_n_bytes), _poi_tx_buff);  // CRC..
   (_poi_tx_buff$^HINT + _n_bytes)^ := _crc_result;        // hinten dran
   _n_bytes += 2;                                   // sind 2 Byte mehr

	ret1 := SERUSER_Send(pHandle, _poi_tx_buff, _n_bytes, #WrLen1);

   IF ret1 THEN
    _tx_back := 1;                                            // Fehler
   ELSE
    _tx_back := 0;                                        // in Ordnung
   END_IF // CF
   _exception_code  := 0;
   _mb_error        := 0;
  END_IF // _no_of_points
 END_IF // Start_Adresse
END_IF // Funktion = 15


//-----------------------------------------------------------------------
// Funktion No.: 16;   Beschreiben der Datenspeicher
//
IF (_m_function = 16) | (_m_function = 17) THEN
 IF _start_address < 000 | _start_address > DataSize THEN
  _exception_code := 2;                        // illegal data address
 ELSE
  IF _no_of_points < 1 | _no_of_points > 127 THEN
   _exception_code := 3;                         // illegal data value
  ELSE
//---- Datenspeicher beschreiben ----
   _a := 0;
   _set_address := _start_address;
   WHILE _a < _rd_latch[5] DO                 // [5] = No. of Registers
    SETBYTE(_set_address+1, _rd_latch[2*_a + 7]);    // [7] = 1.Hi-Byte
    SETBYTE(_set_address+0, _rd_latch[2*_a + 8]);    // [8] = 1.Lo-Byte
    _a += 1;
    _set_address += 2;
   END_WHILE;
//---- Response --------------------------
   _tx_buffer[0] := SLAVE_ADDRESS$USINT;                  // Header aufbauen
   _tx_buffer[1] := _m_function;
   _tx_buffer[2] := _rd_latch[2];                // Starting Address Hi
   _tx_buffer[3] := _rd_latch[3];                // Starting Address Lo
   _tx_buffer[4] := _rd_latch[4];                      // No of Regs Hi
   _tx_buffer[5] := _rd_latch[5];                      // No of Regs Lo
   _n_bytes := 6;                                  // Header = 6 Bytes
   _crc_result := CALKCRC(TO_UINT(_n_bytes), _poi_tx_buff);    // CRC..
   (_poi_tx_buff$^HINT + _n_bytes)^ := _crc_result;       // hinten dran
   _n_bytes += 2;                                  // sind 2 Byte mehr

	ret1 := SERUSER_Send(pHandle, _poi_tx_buff, _n_bytes, #WrLen1);

   IF ret1 THEN
    _tx_back := 1;                                           // Fehler
   ELSE
    _tx_back := 0;                                       // in Ordnung
   END_IF // CF
   _exception_code  := 0;
   _mb_error        := 0;
  END_IF // _no_of_points
 END_IF // Start_Adresse
END_IF // Funktion = 16


//-----------------------------------------------------------------------
// Fehler (Exception Response); sendet Fehlermeldung
//
IF _exception_code > 0 THEN
   _tx_buffer[0] := SLAVE_ADDRESS$USINT;                  // Header aufbauen
   _tx_buffer[1] := _m_function OR 16#80;
   _tx_buffer[2] := _exception_code;
   _n_bytes := 3;
   _crc_result := CALKCRC(TO_UINT(_n_bytes), _poi_tx_buff);    // CRC..
   (_poi_tx_buff$^HINT + _n_bytes)^ := _crc_result;       // hinten dran
   _n_bytes += 2;

	ret1 := SERUSER_Send(pHandle, _poi_tx_buff, _n_bytes, #WrLen1);

   IF ret1 THEN
    _tx_back := 1;                                           // Fehler
   ELSE
    _tx_back := 0;                                       // in Ordnung
   END_IF // CF
END_IF // Exception Code


END_FUNCTION // Modbus::Send

FUNCTION TAB  Modbus::CRCTab
//
//
// Tabelle, aus der sich die jeweilige Checksumme geholt wird
//

16#0000,16#C0C1,16#C181,16#0140,16#C301,16#03C0,16#0280,16#C241
16#C601,16#06C0,16#0780,16#C741,16#0500,16#C5C1,16#C481,16#0440
16#CC01,16#0CC0,16#0D80,16#CD41,16#0F00,16#CFC1,16#CE81,16#0E40
16#0A00,16#CAC1,16#CB81,16#0B40,16#C901,16#09C0,16#0880,16#C841
16#D801,16#18C0,16#1980,16#D941,16#1B00,16#DBC1,16#DA81,16#1A40
16#1E00,16#DEC1,16#DF81,16#1F40,16#DD01,16#1DC0,16#1C80,16#DC41
16#1400,16#D4C1,16#D581,16#1540,16#D701,16#17C0,16#1680,16#D641
16#D201,16#12C0,16#1380,16#D341,16#1100,16#D1C1,16#D081,16#1040
16#F001,16#30C0,16#3180,16#F141,16#3300,16#F3C1,16#F281,16#3240
16#3600,16#F6C1,16#F781,16#3740,16#F501,16#35C0,16#3480,16#F441
16#3C00,16#FCC1,16#FD81,16#3D40,16#FF01,16#3FC0,16#3E80,16#FE41
16#FA01,16#3AC0,16#3B80,16#FB41,16#3900,16#F9C1,16#F881,16#3840
16#2800,16#E8C1,16#E981,16#2940,16#EB01,16#2BC0,16#2A80,16#EA41
16#EE01,16#2EC0,16#2F80,16#EF41,16#2D00,16#EDC1,16#EC81,16#2C40
16#E401,16#24C0,16#2580,16#E541,16#2700,16#E7C1,16#E681,16#2640
16#2200,16#E2C1,16#E381,16#2340,16#E101,16#21C0,16#2080,16#E041
16#A001,16#60C0,16#6180,16#A141,16#6300,16#A3C1,16#A281,16#6240
16#6600,16#A6C1,16#A781,16#6740,16#A501,16#65C0,16#6480,16#A441
16#6C00,16#ACC1,16#AD81,16#6D40,16#AF01,16#6FC0,16#6E80,16#AE41
16#AA01,16#6AC0,16#6B80,16#AB41,16#6900,16#A9C1,16#A881,16#6840
16#7800,16#B8C1,16#B981,16#7940,16#BB01,16#7BC0,16#7A80,16#BA41
16#BE01,16#7EC0,16#7F80,16#BF41,16#7D00,16#BDC1,16#BC81,16#7C40
16#B401,16#74C0,16#7580,16#B541,16#7700,16#B7C1,16#B681,16#7640
16#7200,16#B2C1,16#B381,16#7340,16#B101,16#71C0,16#7080,16#B041
16#5000,16#90C1,16#9181,16#5140,16#9301,16#53C0,16#5280,16#9241
16#9601,16#56C0,16#5780,16#9741,16#5500,16#95C1,16#9481,16#5440
16#9C01,16#5CC0,16#5D80,16#9D41,16#5F00,16#9FC1,16#9E81,16#5E40
16#5A00,16#9AC1,16#9B81,16#5B40,16#9901,16#59C0,16#5880,16#9841
16#8801,16#48C0,16#4980,16#8941,16#4B00,16#8BC1,16#8A81,16#4A40
16#4E00,16#8EC1,16#8F81,16#4F40,16#8D01,16#4DC0,16#4C80,16#8C41
16#4400,16#84C1,16#8581,16#4540,16#8701,16#47C0,16#4680,16#8641
16#8201,16#42C0,16#4380,16#8341,16#4100,16#81C1,16#8081,16#4040

//
//

END_FUNCTION //TAB  Modbus::CRCTab

FUNCTION AWL Modbus::GetBit
VAR_INPUT
	Adresse		: UINT;
END_VAR
VAR_OUTPUT
	Inhalt		: hsINT;
END_VAR

		 l.edi     IOPtr
         ADD.DI   adresse
         L.AL      (EDI)
         S.AL      inhalt


END_FUNCTION // Modbus::GetBit

FUNCTION AWL Modbus::SetBit
VAR_INPUT
	Adresse		: uINT;
	Wert		: hsiNT;
END_VAR

		 l.edi     IOPtr
         ADD.DI   adresse
         L.AL      Wert
         S.AL      (EDI)



END_FUNCTION // Modbus::SetBit
//[#ENGLISH]
//
//Ein Byte lesen.
//
//In INHALT steht der Wert der von ADRESSE gelesen wird.
//
FUNCTION AWL Modbus::GetByte
VAR_INPUT
	Adresse		: uint;
END_VAR
VAR_OUTPUT
	inhalt		: hsint;
END_VAR

		 l.edi     DataPtr
         ADD.DI   adresse
         L.AL      (EDI)
         S.AL      inhalt


END_FUNCTION // Modbus::GetByte
//[#ENGLISH]
//
//Schreibt den Inhalt von WERT an die ADRESSE.
FUNCTION AWL Modbus::SetByte
VAR_INPUT
	Adresse		: uint;
	Wert		: hsint;
END_VAR



		 l.edi     DataPtr
         ADD.DI   adresse
         L.AL      Wert
         S.AL      (EDI)




END_FUNCTION // Modbus::SetByte
//[#ENGLISH]
//
//Daten kopieren.
//
//ANZAHL von Bytes werden von SOURCE nach DESTI kopiert.
//
//
FUNCTION AWL Modbus::CopyBuff
VAR_INPUT
	Anzahl		: uint;
	Desti		: ^DINT;
	Source		: ^DINT;
END_VAR

		 push     esi
         PUSHF
         CLD
		 clr      ecx
         L.CX      anzahl
         L.EDI    desti
         L.ESI    source
         REP
         MOVSB
         POPF
		 pop	  esi



END_FUNCTION // Modbus::CopyBuff


//[#ENGLISH]
//
//Diese Funktion berechnet den CRC16.
//
//ANZAHL : Anzahl der Bytes
//SOURCE : Pointer auf den Datenbereich
//ERGEBN : CRC-Ergebnis
//
FUNCTION AWL Modbus::CalkCRC
VAR_INPUT
	Anzahl		: UINT;
	Source		: ^Hsint;
END_VAR
VAR_OUTPUT
	Ergebn		: hint;
END_VAR

         L.DX      16#FFFF
		 clr      ecx 
         L.CX      anzahl
         L.EDI    source
CRC_LP
         L         (EDI)
         CALL      CRC16
         INC       EDI
         LOOP      CRC_LP
         S.DX      ergebn


END_FUNCTION // Modbus::CalkCRC
//[#ENGLISH]
//
//Unterfunktion zur CRC-Berechnung
//
FUNCTION AWL Modbus::CRC16

		 push      Ecx
		 clr       ebx


         CLR       AH
         L.BX      DX
         XOR.BX    AX
         CLR       BH
         SHL.BX    00001
         L.ESI     #CRCTAB()
         L.AX     (EBX+ESI+003)
         XCH.DH    DL
         CLR       DH
         XOR.DX    AX

		 pop       Ecx




END_FUNCTION // Modbus::CRC16


//[#ENGLISH]
//
//Buffer l攕chen.
//
//ANZAHL von Bytes ab Datenspeicher DESTI auf $00 setzen.
//
FUNCTION AWL Modbus::ClrBuffer
VAR_INPUT
	Anzahl		: uint;
	Desti		: ^Hsint;
END_VAR

		 Clr      ECX
         L.CX     anzahl
         L.AL     16#00
         L.EDI    desti
		 CLD
         REP
         STOSB


END_FUNCTION // Modbus::ClrBuffer

FUNCTION awl Modbus::ENABLE_ME

	L.DX  16#F8FC
	inb
	and.al  16#FE
	outb
	
END_FUNCTION // Modbus::ENABLE_ME

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -