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

📄 modbus_00_00.st~

📁 moudbus通讯协议, moudbus通讯协议, moudbus通讯协议,
💻 ST~
📖 第 1 页 / 共 2 页
字号:
	form		: sint;
	dest		: ^DINT;
	P_size		: int;
END_VAR


  SYS(130, AL:=1, AH:=b_rate, CL:=form, CH:=0, BX:=SEG(dest),
   DX:=OFF(dest), SI:=p_size);


END_FUNCTION // Modbus::InitCom1
//[#ENGLISH]
//Empfang uberwachen
FUNCTION  Modbus::Rec
//
// Empfang 乥erwachen.
//
//

//---- COM1 Zeiger holen ----
 _rx_zeiger_old := _rx_zeiger_akt;         // Alten merken
 SYS(130, AL:=6);                        // Neuen holen
  _rx_zeiger_akt := BX;

//---- _timeout reset ----
 IF _rx_zeiger_akt <> _rx_zeiger_old THEN  // falls ein Zeichen kommt...
  IF _timeout = 1 THEN
   _timeout := 0;
   _rd_zeiger := _rx_zeiger_old;
   _delta_rd_zeiger := 0;
  END_IF;
  _timeout_ctr := 0;                      // Time-Out reset.
 END_IF;

//---- 歜erlauf ----
 IF _timeout_ctr > TIMEOUT_PRESET THEN    // Time-Out 歜erlauf ???
  _timeout := 1;
 ELSE
  _timeout := 0;
 END_IF;

//---- _timeout mitz刪len ----
 IF _Impuls10ms = 1 THEN
  _timeout_ctr += 1;
 END_IF;



END_FUNCTION // Modbus::Rec
//[#ENGLISH]
//
//Funktion auswerten und Senden.
//
//Die Funktion SEND wertet den Funktionscode aus,
//f乭rt die entsprechende Aktion aus und sendet eine
//Antwort. Ist die Funktion, der Adressbereich oder
//der Wertbereich falsch, so wird der EXCEPTION CODE
//gesendet.
//
//Ausgef乭rte Funktionen:   1:  Ein-Ausg刵ge lesen
//                          2:  -''-
//                          3:  Datenregister lesen
//                          4:  -''-
//                         15:  Ausg刵ge schreiben
//                         16:  Datenspeicher schreiben
//
//
//
//
//
FUNCTION  Modbus::Send
//
//-----------------------------------------------------------------------
// Funktion 1         ( Read Coil Status.      M0F00 ... M0FFF )
// Funktion 2         ( Read Input Status.     M0F00 ... M0FFF )
// Funktion 3         ( Read Holding Register. M1000 ... M5E1D )
// Funktion 4         ( Read Input Register.   M1000 ... M5E1D )
// Funktion 15        ( Force Multiple Coils.  M0F00 ... M0FFF )
// Funktion 16        ( Preset Multiple Regs.  M1000 ... M5E1D )
// Fehler R乧kmeldung ( Exception Response )
//-----------------------------------------------------------------------


//---- Sende - Puffer l攕chen ----
 _poi_tx_buff := #_tx_buffer[0];
 CLRBUFFer(256, _poi_tx_buff);


//-----------------------------------------------------------------------
// Funktion No.: 1 und 2;   Lesen der Ein- und Ausg刵ge.
//
IF _m_function = 1 | _m_function = 2 THEN
 IF _start_address < 16#F00 | _start_address > 16#FFF 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
   _tx_buffer[0] := SLAVE_ADDRESS;                    // Header aufbauen
   _tx_buffer[1] := _m_function;
   _tx_buffer[2] := 1+((_rd_latch[5]-1) SHR 3);    // von Bits nach Bytes
   _a := 0;
   WHILE _a < _tx_buffer[2] DO
    _tx_buffer[2*_a + 3] := _GET_BYTE(4*_a + _start_address+0);  // Dat
    _tx_buffer[2*_a + 4] := _GET_BYTE(4*_a + _start_address+1);  // Dat
    _a += 1;
   END_WHILE
   _n_bytes := 3 + _tx_buffer[2];                    // Header plus Daten
   _crc_result := _CALK_CRC(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
   SYS(130, AL:=2, CX:=_n_bytes, BX:=SEG(_poi_tx_buff),         // senden
         DX:=OFF(_poi_tx_buff));
   IF CF 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 = 1 und 2


//-----------------------------------------------------------------------
// Funktion No.: 3 und 4;   Lesen der Datenspeicher
//
IF _m_function = 3 | _m_function = 4 THEN
 IF _start_address < 16#1000 | _start_address > 16#5E1D 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
   _tx_buffer[0] := SLAVE_ADDRESS;                    // Header aufbauen
   _tx_buffer[1] := _m_function;
   _tx_buffer[2] := _rd_latch[5] * 2;                       // Byte Count
   _a := 0;
   WHILE _a < _rd_latch[5] DO                       // [5] = No of Points
    _tx_buffer[2*_a + 3] := _GET_BYTE(2*_a + _start_address+1); // Data H
    _tx_buffer[2*_a + 4] := _GET_BYTE(2*_a + _start_address+0); // Data L
    _a += 1;
   END_WHILE
   _n_bytes := 3 + _tx_buffer[2];                    // Header plus Daten
   _crc_result := _CALK_CRC(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
   SYS(130, AL:=2, CX:=_n_bytes, BX:=SEG(_poi_tx_buff),         // senden
         DX:=OFF(_poi_tx_buff));
   IF CF 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 = 3 und 4


//-----------------------------------------------------------------------
// Funktion No.: 15;   Beschreiben der Ausg刵ge
//
IF _m_function = 15 THEN
 IF _start_address < 16#0F00 | _start_address > 16#0FFF 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 := _GET_BYTE(_set_address);       // altes Bitmuster holen
     _bin_1    := 16#ff XOR _set_mask;          // Maske invertieren
     _old_byte := _old_byte AND _bin_1;          // neuen Teil l攕chen
     _bin_1    := _rd_latch[7+_a] AND _set_mask;// neuen Teil vorbereiten
     _bin_1    := _bin_1 OR _old_byte;           // Alten dazu
     _SET_BYTE(_set_address, _bin_1);            // raus
    ELSE
     _SET_BYTE(_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;             // 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 := _CALK_CRC(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
   SYS(130, AL:=2, CX:=_n_bytes, BX:=SEG(_poi_tx_buff),        // senden
         DX:=OFF(_poi_tx_buff));
   IF CF 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 THEN
 IF _start_address < 16#1000 | _start_address > 16#5E1D 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
    _SET_BYTE(_set_address+1, _rd_latch[2*_a + 7]);    // [7] = 1.Hi-Byte
    _SET_BYTE(_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;                  // 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 := _CALK_CRC(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
   SYS(130, AL:=2, CX:=_n_bytes, BX:=SEG(_poi_tx_buff),       // senden
         DX:=OFF(_poi_tx_buff));
   IF CF 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;                  // Header aufbauen
   _tx_buffer[1] := _m_function OR 16#80;
   _tx_buffer[2] := _exception_code;
   _n_bytes := 3;
   _crc_result := _CALK_CRC(TO_UINT(_n_bytes), _poi_tx_buff);    // CRC..
   (_poi_tx_buff$^HINT + _n_bytes)^ := _crc_result;       // hinten dran
   _n_bytes += 2;
   SYS(130, AL:=2, CX:=_n_bytes, BX:=SEG(_poi_tx_buff),       // senden
         DX:=OFF(_poi_tx_buff));
   IF CF THEN
    _tx_back := 1;                                           // Fehler
   ELSE
    _tx_back := 0;                                       // in Ordnung
   END_IF // CF
END_IF // Exception Code


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

         PUSH      AX
         PUSH      ES
         PUSH      DI
         L.AX      00000
         L.ES      AX
         L.AL      wert
         L.DI      adresse
         S.AL    E (DI)
         POP       DI
         POP       ES
         POP       AX




END_FUNCTION // Modbus::SetByte

FUNCTION  Modbus::SubbRoll
VAR_INPUT
	subtr		: uint;
	subtrh		: uint;
END_VAR
VAR_OUTPUT
	diff		: uint;
END_VAR

 IF subtr >= subtrh THEN
  diff := subtr - subtrh;
 ELSE
  diff := 512 - subtrh + subtr;
 END_IF;


END_FUNCTION // Modbus::SubbRoll

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

⌨️ 快捷键说明

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