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

📄 modbus_00_00.st~

📁 moudbus通讯协议, moudbus通讯协议, moudbus通讯协议,
💻 ST~
📖 第 1 页 / 共 2 页
字号:

FUNCTION VIRTUAL GLOBAL Modbus::CyWork
VAR_INPUT
	EAX		: UDINT;
END_VAR
VAR_OUTPUT
	state		: UDINT;
END_VAR
(*


MODBUS RTU Protokoll          18.06.97 Ch. Kalleitner

1. Die COM1 wird als Modbus-Schnittstelle initialisiert.
   Die privaten Konstanten sind eventuell anzupassen:
          BAUDRATE        = V.24 Baudrate
          FORMAT          = V.24 Format
          SLAVE_ADDRESS   = Modbus Slave-Address

2. Der Empfang wird 歜erwacht.

3. Wird eine verwertbare Funktion erkannt, so wird
   Ausgewertet und eine Antwort gesendet. Folgende
   Funktionen sind m攇lich:
          1,2 : Ein-Ausg刵ge lesen
                Adressbereich: M0F00 bis M0FFF
          3,4 : Datenspeicher lesen
                Adressbereich: M1000 bis M5E1D
          15  : Ausg刵ge schreiben
          16  : Datenspeicher schreiben

   Falls eine falsche Funktionsnummer oder ein Adressbereich
   kommt, wird eine Fehlermeldung (Exception Code) gesendet.

4. Das Modul liefert einen Fehlercode.
   Die Bits im FEHLER haben folgende Bedeutung:
       $00   = kein Fehler

   Bit 7 MSB = -
   Bit 6     = -
   Bit 5     = V.24 Sendefehler
   Bit 4     = Daten falsch
   Bit 3     = Adressbereich falsch
   Bit 2     = Funktion ist falsch
   Bit 1     = CRC Fehler
   Bit 0 LSB = Slave - Adresse falsch


*)




// _MOBU_INIT();     // initialisieren
 REC();           // Empfang 乥erwachen
 COMP();          // pr乫en und senden.
  fehler := _mb_error;



	state := READY$UDINT;
END_FUNCTION //VIRTUAL GLOBAL Modbus::CyWork

FUNCTION VIRTUAL GLOBAL Modbus::Init

 IF _FirstScan = 1 THEN
  _rd_zeiger       := 0;
  _delta_rd_zeiger := 0;
  _poi_rxbuff      := #_rx_buffer[0];
  CLRBUFFer(256, _poi_rxbuff);
  _INIT_COM1(BAUDRATE, FORMAT, _poi_rxbuff, RX_BSIZE);       // COM1 init
  SYS(130, AL:=5);                                 // RX-Puffer l攕chen
  _mb_error        := 0;
  _exception_code  := 0;
  _no_of_rxobjkts  := 0;
 END_IF;

END_FUNCTION //VIRTUAL GLOBAL Modbus::Init

FUNCTION  Modbus::AddRoll
VAR_INPUT
	Suma_512		: UINT;
	Suma_d		: uint;
END_VAR
VAR_OUTPUT
	Summe		: uint;
END_VAR

 IF suma_512 < 512 - suma_d THEN
  summe := suma_512 + suma_d;
 ELSE
  summe := suma_d - (512 - suma_512);
 END_IF;





END_FUNCTION // Modbus::AddRoll
//[#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		: ^DINT;
END_VAR
VAR_OUTPUT
	Ergebn		: hint;
END_VAR

         L.DX      16#FFFF
         L.CX      anzahl
         LES.DI    source
CRC_LP
         L       E (DI)
         CALL      CRC16
         INC       DI
         LOOP      CRC_LP
         S.DX      ergebn


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


         PUSH      ES
         PUSH      SI
         L.CX      anzahl
         L.AL      16#00
         LES.DI    desti
         REP
         STOSB
         POP       SI
         POP       ES


END_FUNCTION // Modbus::ClrBuffer
//[#ENGLISH]
//
//Die empfangenen Daten werden gepr乫t.
//
//1. Die Anzahl der empfangenen Zeichen richtig ?
//2. Slave-Address ?
//3. Funktionscode ?
//4. CRC berechnen und vergleichen
//5. Alles ok ?, dann SEND aufrufen
//6. Fehlercode berechnen
//
FUNCTION  Modbus::Comp
//-----------------------------------------------------------------------
//
// Empfangenes Objekt pr乫en
//
//-----------------------------------------------------------------------

//---- wieviel Zeichen sind schon da ??? ----
 _delta_rd_zeiger := SUBBROLL(_rx_zeiger_akt, _rd_zeiger);

//---- Header schon empfangen ----
 IF _delta_rd_zeiger < 8 THEN
  RETURN;
 END_IF;

//---- Header holen ----
 _rd_scan := _rd_zeiger;
 FOR _a := 0 TO 7 DO
  _rd_latch[_a] := _rx_buffer[_rd_scan];
  _rd_scan   := ADDROLL(_rd_scan, 1);
 END_FOR;

//---- Adresse pr乫en ----
 IF _rd_latch[0] <> SLAVE_ADDRESS THEN
  _mb_error        := _mb_error OR 1;
  RETURN;
 ELSE // Slave Address ok

//---- wieviel werden es ??? ----
 _m_function := _rd_latch[1]
   CASE _m_function OF
    1,2,3,4       : _rx_size := 6;
    15,16         : _rx_size := 6 + 1 + _rd_latch[6];
    ELSE            _rx_size := 6
                    _exception_code := 1;
   END_CASE;

//---- alle empfangen, auch CRC (2 Bytes) ??? ----
 IF _delta_rd_zeiger < _rx_size + 2 THEN
  RETURN;
 END_IF;

//---- jetzt alle kopieren ----
  _rd_scan := _rd_zeiger;
  FOR _a := 0 TO _rx_size + 1 DO
   _rd_latch[_a] := _rx_buffer[_rd_scan];
   _rd_scan   := _ADD_ROLL(_rd_scan, 1);
  END_FOR;

//---- CRC berechnen ----
   IF (_rx_size > 0) & (_rx_size < 254) THEN
    _poi_latch     := #_rd_latch[0];
    _crc_calk      := _CALK_CRC(_rx_size, _poi_latch);  // Der Berechnete
    _crc_rx        := ((_poi_latch + _rx_size)$^HINT)^; // Der Empfangene
   ELSE
    _crc_rx        := 0;
    _crc_calk      := 1;
   END_IF; // CRC berechnen

//---- CRC vergleichen ----
   IF _crc_rx = _crc_calk THEN
    _start_address := _rd_latch[2];
    _start_address := _start_address SHL 8 OR _rd_latch[3];
    _no_of_points  := _rd_latch[4];
    _no_of_points  := _no_of_points SHL 8 OR _rd_latch[5];
    _no_of_rxobjkts  += 1;
    _mb_error      := 0;

//---- senden ----
    _SEND();
    _crc_rx        := 0;
    _crc_calk      := 1;
   ELSE                                               // CRC ist falsch
    _start_address := 0;
    _no_of_points  := 0;
    _mb_error      := _mb_error OR 2;
   END_IF;

//---- ok, Zeiger nachziehen ---
  _rd_zeiger       := _rx_zeiger_akt;
  _delta_rd_zeiger := 0;
 END_IF; // Slave Adresse ok


//---- Fehler-Code berechnen ----
  CASE _exception_code OF
    1: _mb_error := _mb_error OR 2#00000100;
    2: _mb_error := _mb_error OR 2#00001000;
    3: _mb_error := _mb_error OR 2#00010000;
  END_CASE;

  IF _tx_back = 1 THEN
   _mb_error := _mb_error  OR 2#00100000;
  ELSE
   _mb_error := _mb_error AND 2#11011111;
  END_IF;




END_FUNCTION // Modbus::Comp
//[#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      DS
         PUSHF
         CLD

         L.CX      anzahl
         LES.DI    desti
         LDS.SI    source
         REP
         MOVSB

         POPF
         POP       DS




END_FUNCTION // Modbus::CopyBuff
//[#ENGLISH]
//
//Unterfunktion zur CRC-Berechnung
//
FUNCTION AWL Modbus::CRC16
VAR_INPUT
	Zeich		: sint;
END_VAR
VAR_OUTPUT
	ergebn		: int;
END_VAR

         CLR       AH
         L.BX      DX
         XOR.BX    AX
         CLR       BH
         SHL.BX    00001
         L.SI      #CRCTAB()
         L.AX    C (BX+SI+002)
         XCH.DH    DL
         CLR       DH
         XOR.DX    AX


END_FUNCTION // Modbus::CRC16
//[#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

         PUSH      ES
         PUSH      SI
         PUSH      AX
         L.AX      00000
         L.ES      AX
         L.SI      adresse
         L.AL    E (SI)
         S.AL      inhalt
         POP       AX
         POP       SI
         POP       ES


END_FUNCTION // Modbus::GetByte
//[#ENGLISH]
//
//V.24 ( COM1 ) Initialisierung.
//
//b_rate: Baudrate    0: 9600 Baud
//                    1: 4800
//                    2: 2400
//                    3: 1200
//                    4: 600
//                    5: 300
//                    6: 115200
//                    7: 57600
//                    8: 38400
//                    9: 19200
//
//form: Datenformat   0: 8 Bit, 1 Stop, no Parity
//                    1: 8 Bit, 2 Stop, no Parity
//                    2: 8 Bit, 1 Stop, Parity even
//                    3: 8 Bit, 2 Stop, Parity even
//                    4: 8 Bit, 1 Stop, Parity odd
//                    5: 8 Bit, 2 Stop, Parity odd
//
//dest: Far-Pointer auf Empfangspuffer
//
//p_size: Gr斸e des Puffers in Byte ( 256 )
//
//
//
//
FUNCTION  Modbus::InitCom1
VAR_INPUT
	b_rate		: sint;

⌨️ 快捷键说明

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