summaryrefslogtreecommitdiff
path: root/prozess/ls-Prozess 1 für MUFI im Terminalkanal
diff options
context:
space:
mode:
Diffstat (limited to 'prozess/ls-Prozess 1 für MUFI im Terminalkanal')
-rw-r--r--prozess/ls-Prozess 1 für MUFI im Terminalkanal511
1 files changed, 481 insertions, 30 deletions
diff --git a/prozess/ls-Prozess 1 für MUFI im Terminalkanal b/prozess/ls-Prozess 1 für MUFI im Terminalkanal
index d1edbc1..712b8a2 100644
--- a/prozess/ls-Prozess 1 für MUFI im Terminalkanal
+++ b/prozess/ls-Prozess 1 für MUFI im Terminalkanal
@@ -22,34 +22,485 @@
*)
PACKET altes incharety DEFINES old incharety:
-TEXT PROC old incharety:{} incharety{}END PROC old incharety;{}TEXT PROC old incharety (INT CONST timelimit):{} incharety (timelimit){}END PROC old incharety;{}END PACKET altes incharety;{}PACKET ls prozess 1 DEFINES{} run pdv,{} run pdv again,{} initialisiere interface,{} ausgeben,{} eingabe,{} warte,{} abbruch gewuenscht,{} tue nichts,{} trage kanaldaten ein,{} beende kanaldaten eintragen,{} hole spannungsbereich,{} letzte ausgabe,{}
- pruefe kanal,{} pruefe abbruch,{} teste interface,{} schalte alles aus,{} oeffne interface,{} schliesse interface,{} nicht belegt,{} digital aus,{} analog aus,{} digital ein,{} analog ein,{} kanalbreite,{} ganzzahl obergrenze,{} adapterart,{} incharety,{} inchar,{} pause:{}(******************** A N P A S S U N G A N M U F I ********************){}LET mufikennung = ""31""31"",{} erwartete zeichen = 4 ;{}
-TEXT CONST adapterart :: "MUFI im Terminalkanal",{} interface test code :: ""27""27"10",{} interface okay code :: ""27""27"00",{} interface open code :: ""27""27"1C" + hex (mufikennung),{} interface close code :: mufikennung + "1C" + hex (""27""27""),{} adresse 0 code :: mufikennung + "3D",{} leertakt code :: mufikennung + "3E",{} interface write code :: mufikennung + "5" ,{} interface read code :: mufikennung + "4" ;{}
-TEXT VAR puffer :: "";{}ROW 256 TEXT CONST hexcode :: ROW 256 TEXT : ({}"00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",{}"10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",{}"20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",{}"30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F",{}"40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",{}"50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",{}
-"60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",{}"70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",{}"80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",{}"90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",{}"A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",{}"B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",{}"C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",{}
-"D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",{}"E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",{}"F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF");{}TEXT PROC interface anpassung (INT CONST kanalnummer, steuerungscode):{} LET hexzeichen = "0123456789ABCDEF";{} IF es ist ein ausgabekanal{} THEN interface write code{} + (hexzeichen SUB (device + 4 * steuerungscode)){} ELIF es ist ein eingabekanal{}
- THEN lesecode in abhaengigkeit von der taktzahl{} ELSE ""{} FI.{} es ist ein ausgabekanal:{} kanal [kanalnummer].betriebsart < 0.{} es ist ein eingabekanal:{} kanal [kanalnummer].betriebsart > 0.{} device:{} IF kanalnummer < 10{} THEN 1{} ELSE kanalnummer DIV 10{} FI.{} lesecode in abhaengigkeit von der taktzahl:{} SELECT kanal [kanalnummer].taktzahl OF{} CASE 1: lesecode{} CASE 2: adresse 0 code + lesecode + lesecode{} CASE 3: adresse 0 code + lesecode + zwei weitere takte{}
- OTHERWISE "" END SELECT.{} lesecode:{} interface read code + (hexzeichen SUB (device + 4 * steuerungscode)).{} zwei weitere takte:{} IF leertakt code = ""{} THEN lesecode + lesecode{} ELSE kanal [kanalnummer].taktzahl DECR 1;{} leertakt code + lesecode{} FI.{}END PROC interface anpassung;{}PROC ausgeben (INT CONST kanalnummer, wert):{} merke wert;{} gib wert aus.{} merke wert:{} vorherige ausgabe [kanalnummer] := wert.{} gib wert aus:{} out (kanal [kanalnummer].steuercode);{}
- out (hexcode [wert + 1]).{}END PROC ausgeben;{}INT PROC eingabe (INT CONST kanalnummer):{} gib lesecode aus;{} erhaltene antwort.{} gib lesecode aus:{} out (kanal [kanalnummer].steuercode).{} erhaltene antwort:{} TEXT VAR dummy;{} SELECT kanal [kanalnummer].taktzahl OF{} CASE 1 : erste sendung{} CASE 2 : zweite sendung{} CASE 3 : dritte sendung{} OTHERWISE -1{} END SELECT.{} erste sendung:{} fange mufikennung;{} dezimalwert (old incharety (1), old incharety (1)).{}
- zweite sendung:{} fange mufikennung;{} dummy := old incharety (1);{} dummy := old incharety (1);{} erste sendung.{} dritte sendung:{} fange mufikennung;{} dummy := old incharety (1);{} dummy := old incharety (1);{} zweite sendung.{} fange mufikennung:{} puffer CAT old incharety;{} REP puffer CAT old incharety{} UNTIL pos (puffer, mufikennung) > 0 PER;{} puffer := subtext (puffer, 1, length (puffer) - 2).{}END PROC eingabe;{}(************ H A R D W A R E U N A B H Ä N G I G E R T E I L ************){}
-LET max kanalanzahl = 49,{} endezeichen = "q",{} abbruchzeichen = "h",{} esc = ""27"";{}INT CONST analog aus :: -2, (* Betriebsarten *){} digital aus :: -1,{} nicht belegt :: 0,{} digital ein :: 1,{} analog ein :: 2,{} kanalbreite :: 8,{} ganzzahl obergrenze :: 2 ** kanalbreite,{}
- configuration error code :: -1,{} interface error code :: -4;{}TEXT VAR meldung :: "";{}BOOL VAR kanaldaten sind eingetragen :: FALSE,{} endezeichen gegeben :: FALSE,{} programm mit pdv gestartet :: FALSE,{} fehler zu melden :: FALSE;{}TYPE KANAL = STRUCT (INT betriebsart, taktzahl, TEXT steuercode),{} SPANNUNG = STRUCT (REAL minimalwert, maximalwert);{}ROW max kanalanzahl INT VAR vorherige ausgabe;{}
-ROW max kanalanzahl KANAL VAR kanal;{}ROW max kanalanzahl SPANNUNG VAR spannung;{}PROC run pdv:{} run pdv (last param){}END PROC run pdv;{}PROC run pdv (TEXT CONST programmname):{} enable stop;{} last param (programmname);{} programm mit pdv gestartet := TRUE;{} teste interface;{} disable stop;{} run (programmname);{} IF is error{} THEN fehlerbehandlung{} ELSE melde programmende{} FI;{} schliesse interface;{} programm mit pdv gestartet := FALSE;{} enable stop;{} IF fehler zu melden{}
- THEN errorstop (meldung){} FI{}END PROC run pdv;{}PROC run pdv again:{} enable stop;{} programm mit pdv gestartet := TRUE;{} teste interface;{} disable stop;{} run again;{} IF is error{} THEN fehlerbehandlung{} ELSE melde programmende{} FI;{} schliesse interface;{} programm mit pdv gestartet := FALSE;{} enable stop;{} IF fehler zu melden{} THEN errorstop (meldung){} FI{}END PROC run pdv again;{}PROC melde programmende:{} page;{} menufootnote ("Programmende! Zum Weitermachen bitte irgendeine Taste tippen.");{}
- pause;{} schalte alles aus{}END PROC melde programmende;{}PROC initialisiere interface:{} enable stop;{} pruefe abbruch;{} IF programm mit pdv gestartet{} THEN schalte alles aus{} ELSE errorstop ("PDV-Programme müssen mit 'run pdv' gestartet werden!"){} FI{}END PROC initialisiere interface;{}PROC schalte alles aus:{} INT VAR kanalnummer, kanalbetriebsart;{} FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{} kanalbetriebsart := kanal [kanalnummer].betriebsart;{} IF kanalbetriebsart = digital aus{}
- THEN ausgeben (kanalnummer, 0){} ELIF kanalbetriebsart = analog aus{} THEN ausgeben (kanalnummer, gewandelte nullspannung){} FI{} PER.{} gewandelte nullspannung:{} int(- real (ganzzahl obergrenze) * u min / (u max - u min) + 0.5).{} u max : spannung [kanalnummer].maximalwert.{} u min : spannung [kanalnummer].minimalwert.{}END PROC schalte alles aus;{}PROC warte (REAL CONST sekunden):{} TEXT VAR eingabe;{} pruefe abbruch;{} eingabe := incharety (int (sekunden * 10.0 + 0.5));{}
- IF eingabe = esc{} THEN untersuche naechstes zeichen{} FI.{} untersuche naechstes zeichen:{} eingabe := incharety (30);{} IF eingabe = endezeichen{} THEN endezeichen gegeben := TRUE{} ELIF eingabe = abbruchzeichen{} THEN errorstop ("Programm-Abbruch durch <ESC><"{} + abbruchzeichen + ">!"){} FI.{}END PROC warte;{}PROC warte (INT CONST sekunden):{} TEXT VAR eingabe;{} pruefe abbruch;{} eingabe := incharety (sekunden * 10);{} IF eingabe = esc{}
- THEN untersuche naechstes zeichen{} FI.{} untersuche naechstes zeichen:{} eingabe := incharety (30);{} IF eingabe = endezeichen{} THEN endezeichen gegeben := TRUE{} ELIF eingabe = abbruchzeichen{} THEN errorstop ("Programm-Abbruch durch <ESC><"{} + abbruchzeichen + ">!"){} FI.{}END PROC warte;{}TEXT PROC incharety:{} IF puffer = ""{} THEN old incharety{} ELSE erstes zeichen von puffer{} FI.{} erstes zeichen von puffer:{} TEXT CONST zeichen :: puffer SUB 1;{}
- puffer := subtext (puffer, 2);{} zeichen.{}END PROC incharety;{}TEXT PROC incharety (INT CONST timelimit):{} IF puffer = ""{} THEN old incharety (timelimit){} ELSE erstes zeichen von puffer{} FI.{} erstes zeichen von puffer:{} TEXT CONST zeichen :: puffer SUB 1;{} puffer := subtext (puffer, 2);{} zeichen.{}END PROC incharety;{}PROC inchar (TEXT VAR character):{} REP character := incharety{} UNTIL character <> "" PER{}END PROC inchar;{}PROC pause:{} TEXT VAR dummy;{} inchar (dummy){}
-END PROC pause;{}PROC pause (INT CONST timelimit):{} TEXT VAR dummy := incharety (timelimit){}END PROC pause;{}BOOL PROC abbruch gewuenscht:{} pruefe abbruch;{} BOOL VAR entscheidung :: endezeichen gegeben;{} endezeichen gegeben := FALSE;{} entscheidung{}END PROC abbruch gewuenscht;{}PROC tue nichts:{} pruefe abbruch{}END PROC tue nichts;{}PROC trage kanaldaten ein (INT CONST kanalnummer,{} ROW 2 REAL CONST spannungsbereich,{} ROW 3 INT CONST kanalparameter):{}
- spannung [kanalnummer].minimalwert := spannungsbereich [1];{} spannung [kanalnummer].maximalwert := spannungsbereich [2];{} kanal [kanalnummer].betriebsart := kanalparameter [1];{} kanal [kanalnummer].taktzahl := kanalparameter [2];{} kanal [kanalnummer].steuercode := interface anpassung{} (kanalnummer, kanalparameter [3]){}END PROC trage kanaldaten ein;{}PROC beende kanaldaten eintragen:{} kanaldaten sind eingetragen := TRUE{}END PROC beende kanaldaten eintragen;{}
-PROC hole spannungsbereich (INT CONST kanalnummer, REAL VAR u min, u max):{} u min := spannung [kanalnummer].minimalwert;{} u max := spannung [kanalnummer].maximalwert{}END PROC hole spannungsbereich;{}INT PROC letzte ausgabe (INT CONST kanalnummer):{} vorherige ausgabe [kanalnummer]{}END PROC letzte ausgabe;{}PROC pruefe kanal (INT CONST kanalnummer, gewuenschte betriebsart):{} pruefe abbruch;{} pruefe kanalnummer;{} pruefe betriebsart.{} pruefe kanalnummer:{} IF kanalnummer < 1 OR kanalnummer > max kanalanzahl{}
- THEN errorstop ("Kanalnummer " + text (kanalnummer) +{} " ist unzulaessig !"){} FI.{} pruefe betriebsart:{} IF gewuenschte betriebsart <> kanal [kanalnummer].betriebsart{} THEN errorstop ("An Kanal " + text (kanalnummer) +{} " keine " + wunsch + " moeglich!"){} FI.{} wunsch:{} IF gewuenschte betriebsart = analog aus{} THEN "Analog-Ausgabe"{} ELIF gewuenschte betriebsart = digital aus{} THEN "Digital-Ausgabe"{}
- ELIF gewuenschte betriebsart = digital ein{} THEN "Digital-Eingabe"{} ELIF gewuenschte betriebsart = analog ein{} THEN "Analog-Eingabe"{} ELSE "Ein- oder Ausgabe"{} FI.{}END PROC pruefe kanal;{}PROC pruefe abbruch:{} TEXT VAR zeichen :: incharety;{} IF zeichen = esc{} THEN pruefe weiter{} FI.{} pruefe weiter:{} zeichen := incharety (30);{} IF zeichen = endezeichen{} THEN endezeichen gegeben := TRUE{} ELIF zeichen = abbruchzeichen{} THEN errorstop ("Programm-Abbruch durch <ESC><"{}
- + abbruchzeichen + ">!"){} FI.{}END PROC pruefe abbruch;{}PROC oeffne interface (INT VAR status):{} enable stop;{} IF kanaldaten sind eingetragen{} THEN teste interface funktion{} ELSE status := configuration error code{} FI.{} teste interface funktion:{} leere puffer;{} out (interface test code);{} fange antwort;{} IF antwort = interface okay code{} THEN status := 0;{} out (interface open code){} ELSE status := interface error code{}
- FI.{} leere puffer:{} puffer := "";{} REP UNTIL old incharety = "" PER.{} fange antwort:{} INT VAR zaehler;{} TEXT VAR antwort :: "";{} FOR zaehler FROM 1 UPTO erwartete zeichen REP{} antwort CAT old incharety (1){} PER.{}END PROC oeffne interface;{}PROC schliesse interface:{} enable stop;{} out (interface close code){}END PROC schliesse interface;{}(********************* H I L F S P R O Z E D U R E N *********************){}PROC teste interface:{} INT VAR test;{}
- warte etwas;{} oeffne interface (test);{} IF test < 0{} THEN errorstop (fehlermeldung){} ELSE endezeichen gegeben := FALSE;{} fehler zu melden := FALSE{} FI.{} warte etwas:{} pause (1); pause (1); pause (1); pause (1); pause (1).{} fehlermeldung:{} IF test = configuration error code{} THEN "Interface ist noch nicht konfiguriert!"{} ELIF test = interface error code{} THEN "Interface meldet sich nicht!"{} ELSE "Interface kann nicht geöffnet werden!"{}
- FI.{}END PROC teste interface;{}PROC fehlerbehandlung:{} meldung := errormessage;{} IF meldung <> ""{} THEN meldung CAT fehlerzeile;{} fehler zu melden := TRUE{} FI;{} clear error;{} initialisiere interface.{} fehlerzeile:{} IF errorline = 0{} THEN ""{} ELSE " (bei Zeile " + text (errorline) + ")"{} FI.{}END PROC fehlerbehandlung;{}INT PROC dezimalwert (TEXT CONST zeichen 1, zeichen 2):{} 16 * pos (hexzeichen, zeichen 1) + pos (hexzeichen, zeichen 2).{} hexzeichen: "123456789ABCDEF".{}
-END PROC dezimalwert;{}TEXT PROC hex (TEXT CONST zwei zeichen):{} hex (code (zwei zeichen SUB 1)) + hex (code (zwei zeichen SUB 2)){}END PROC hex;{}TEXT PROC hex (INT CONST wert):{} (hexzeichen SUB (wert DIV 16 + 1)) + (hexzeichen SUB (wert MOD 16 + 1)).{} hexzeichen: "0123456789ABCDEF".{}END PROC hex;{}PROC initialisiere die kanaele:{} INT VAR kanalnummer;{} FOR kanalnummer FROM 1 UPTO max kanalanzahl REP{} trage kanaldaten ein (kanalnummer, keine spannung, leere karte);{} vorherige ausgabe [kanalnummer] := 0{}
- PER.{} keine spannung:{} ROW 2 REAL : (0.0, 0.0).{} leere karte:{} ROW 3 INT : (nicht belegt, 0, 0).{}END PROC initialisiere die kanaele;{}initialisiere die kanaele{}END PACKET ls prozess 1{}
+TEXT PROC old incharety:
+ incharety
+END PROC old incharety;
+TEXT PROC old incharety (INT CONST timelimit):
+ incharety (timelimit)
+END PROC old incharety;
+END PACKET altes incharety;
+PACKET ls prozess 1 DEFINES
+ run pdv,
+ run pdv again,
+ initialisiere interface,
+ ausgeben,
+ eingabe,
+ warte,
+ abbruch gewuenscht,
+ tue nichts,
+ trage kanaldaten ein,
+ beende kanaldaten eintragen,
+ hole spannungsbereich,
+ letzte ausgabe,
+
+ pruefe kanal,
+ pruefe abbruch,
+ teste interface,
+ schalte alles aus,
+ oeffne interface,
+ schliesse interface,
+ nicht belegt,
+ digital aus,
+ analog aus,
+ digital ein,
+ analog ein,
+ kanalbreite,
+ ganzzahl obergrenze,
+ adapterart,
+ incharety,
+ inchar,
+ pause:
+(******************** A N P A S S U N G A N M U F I ********************)
+LET mufikennung = ""31""31"",
+ erwartete zeichen = 4 ;
+
+TEXT CONST adapterart :: "MUFI im Terminalkanal",
+ interface test code :: ""27""27"10",
+ interface okay code :: ""27""27"00",
+ interface open code :: ""27""27"1C" + hex (mufikennung),
+ interface close code :: mufikennung + "1C" + hex (""27""27""),
+ adresse 0 code :: mufikennung + "3D",
+ leertakt code :: mufikennung + "3E",
+ interface write code :: mufikennung + "5" ,
+ interface read code :: mufikennung + "4" ;
+
+TEXT VAR puffer :: "";
+ROW 256 TEXT CONST hexcode :: ROW 256 TEXT : (
+"00","01","02","03","04","05","06","07","08","09","0A","0B","0C","0D","0E","0F",
+"10","11","12","13","14","15","16","17","18","19","1A","1B","1C","1D","1E","1F",
+"20","21","22","23","24","25","26","27","28","29","2A","2B","2C","2D","2E","2F",
+"30","31","32","33","34","35","36","37","38","39","3A","3B","3C","3D","3E","3F",
+"40","41","42","43","44","45","46","47","48","49","4A","4B","4C","4D","4E","4F",
+"50","51","52","53","54","55","56","57","58","59","5A","5B","5C","5D","5E","5F",
+
+"60","61","62","63","64","65","66","67","68","69","6A","6B","6C","6D","6E","6F",
+"70","71","72","73","74","75","76","77","78","79","7A","7B","7C","7D","7E","7F",
+"80","81","82","83","84","85","86","87","88","89","8A","8B","8C","8D","8E","8F",
+"90","91","92","93","94","95","96","97","98","99","9A","9B","9C","9D","9E","9F",
+"A0","A1","A2","A3","A4","A5","A6","A7","A8","A9","AA","AB","AC","AD","AE","AF",
+"B0","B1","B2","B3","B4","B5","B6","B7","B8","B9","BA","BB","BC","BD","BE","BF",
+"C0","C1","C2","C3","C4","C5","C6","C7","C8","C9","CA","CB","CC","CD","CE","CF",
+
+"D0","D1","D2","D3","D4","D5","D6","D7","D8","D9","DA","DB","DC","DD","DE","DF",
+"E0","E1","E2","E3","E4","E5","E6","E7","E8","E9","EA","EB","EC","ED","EE","EF",
+"F0","F1","F2","F3","F4","F5","F6","F7","F8","F9","FA","FB","FC","FD","FE","FF");
+TEXT PROC interface anpassung (INT CONST kanalnummer, steuerungscode):
+ LET hexzeichen = "0123456789ABCDEF";
+ IF es ist ein ausgabekanal
+ THEN interface write code
+ + (hexzeichen SUB (device + 4 * steuerungscode))
+ ELIF es ist ein eingabekanal
+
+ THEN lesecode in abhaengigkeit von der taktzahl
+ ELSE ""
+ FI.
+ es ist ein ausgabekanal:
+ kanal [kanalnummer].betriebsart < 0.
+ es ist ein eingabekanal:
+ kanal [kanalnummer].betriebsart > 0.
+ device:
+ IF kanalnummer < 10
+ THEN 1
+ ELSE kanalnummer DIV 10
+ FI.
+ lesecode in abhaengigkeit von der taktzahl:
+ SELECT kanal [kanalnummer].taktzahl OF
+ CASE 1: lesecode
+ CASE 2: adresse 0 code + lesecode + lesecode
+ CASE 3: adresse 0 code + lesecode + zwei weitere takte
+
+ OTHERWISE "" END SELECT.
+ lesecode:
+ interface read code + (hexzeichen SUB (device + 4 * steuerungscode)).
+ zwei weitere takte:
+ IF leertakt code = ""
+ THEN lesecode + lesecode
+ ELSE kanal [kanalnummer].taktzahl DECR 1;
+ leertakt code + lesecode
+ FI.
+END PROC interface anpassung;
+PROC ausgeben (INT CONST kanalnummer, wert):
+ merke wert;
+ gib wert aus.
+ merke wert:
+ vorherige ausgabe [kanalnummer] := wert.
+ gib wert aus:
+ out (kanal [kanalnummer].steuercode);
+
+ out (hexcode [wert + 1]).
+END PROC ausgeben;
+INT PROC eingabe (INT CONST kanalnummer):
+ gib lesecode aus;
+ erhaltene antwort.
+ gib lesecode aus:
+ out (kanal [kanalnummer].steuercode).
+ erhaltene antwort:
+ TEXT VAR dummy;
+ SELECT kanal [kanalnummer].taktzahl OF
+ CASE 1 : erste sendung
+ CASE 2 : zweite sendung
+ CASE 3 : dritte sendung
+ OTHERWISE -1
+ END SELECT.
+ erste sendung:
+ fange mufikennung;
+ dezimalwert (old incharety (1), old incharety (1)).
+
+ zweite sendung:
+ fange mufikennung;
+ dummy := old incharety (1);
+ dummy := old incharety (1);
+ erste sendung.
+ dritte sendung:
+ fange mufikennung;
+ dummy := old incharety (1);
+ dummy := old incharety (1);
+ zweite sendung.
+ fange mufikennung:
+ puffer CAT old incharety;
+ REP puffer CAT old incharety
+ UNTIL pos (puffer, mufikennung) > 0 PER;
+ puffer := subtext (puffer, 1, length (puffer) - 2).
+END PROC eingabe;
+(************ H A R D W A R E U N A B H Ä N G I G E R T E I L ************)
+
+LET max kanalanzahl = 49,
+ endezeichen = "q",
+ abbruchzeichen = "h",
+ esc = ""27"";
+INT CONST analog aus :: -2, (* Betriebsarten *)
+ digital aus :: -1,
+ nicht belegt :: 0,
+ digital ein :: 1,
+ analog ein :: 2,
+ kanalbreite :: 8,
+ ganzzahl obergrenze :: 2 ** kanalbreite,
+
+ configuration error code :: -1,
+ interface error code :: -4;
+TEXT VAR meldung :: "";
+BOOL VAR kanaldaten sind eingetragen :: FALSE,
+ endezeichen gegeben :: FALSE,
+ programm mit pdv gestartet :: FALSE,
+ fehler zu melden :: FALSE;
+TYPE KANAL = STRUCT (INT betriebsart, taktzahl, TEXT steuercode),
+ SPANNUNG = STRUCT (REAL minimalwert, maximalwert);
+ROW max kanalanzahl INT VAR vorherige ausgabe;
+
+ROW max kanalanzahl KANAL VAR kanal;
+ROW max kanalanzahl SPANNUNG VAR spannung;
+PROC run pdv:
+ run pdv (last param)
+END PROC run pdv;
+PROC run pdv (TEXT CONST programmname):
+ enable stop;
+ last param (programmname);
+ programm mit pdv gestartet := TRUE;
+ teste interface;
+ disable stop;
+ run (programmname);
+ IF is error
+ THEN fehlerbehandlung
+ ELSE melde programmende
+ FI;
+ schliesse interface;
+ programm mit pdv gestartet := FALSE;
+ enable stop;
+ IF fehler zu melden
+
+ THEN errorstop (meldung)
+ FI
+END PROC run pdv;
+PROC run pdv again:
+ enable stop;
+ programm mit pdv gestartet := TRUE;
+ teste interface;
+ disable stop;
+ run again;
+ IF is error
+ THEN fehlerbehandlung
+ ELSE melde programmende
+ FI;
+ schliesse interface;
+ programm mit pdv gestartet := FALSE;
+ enable stop;
+ IF fehler zu melden
+ THEN errorstop (meldung)
+ FI
+END PROC run pdv again;
+PROC melde programmende:
+ page;
+ menufootnote ("Programmende! Zum Weitermachen bitte irgendeine Taste tippen.");
+
+ pause;
+ schalte alles aus
+END PROC melde programmende;
+PROC initialisiere interface:
+ enable stop;
+ pruefe abbruch;
+ IF programm mit pdv gestartet
+ THEN schalte alles aus
+ ELSE errorstop ("PDV-Programme müssen mit 'run pdv' gestartet werden!")
+ FI
+END PROC initialisiere interface;
+PROC schalte alles aus:
+ INT VAR kanalnummer, kanalbetriebsart;
+ FOR kanalnummer FROM 1 UPTO max kanalanzahl REP
+ kanalbetriebsart := kanal [kanalnummer].betriebsart;
+ IF kanalbetriebsart = digital aus
+
+ THEN ausgeben (kanalnummer, 0)
+ ELIF kanalbetriebsart = analog aus
+ THEN ausgeben (kanalnummer, gewandelte nullspannung)
+ FI
+ PER.
+ gewandelte nullspannung:
+ int(- real (ganzzahl obergrenze) * u min / (u max - u min) + 0.5).
+ u max : spannung [kanalnummer].maximalwert.
+ u min : spannung [kanalnummer].minimalwert.
+END PROC schalte alles aus;
+PROC warte (REAL CONST sekunden):
+ TEXT VAR eingabe;
+ pruefe abbruch;
+ eingabe := incharety (int (sekunden * 10.0 + 0.5));
+
+ IF eingabe = esc
+ THEN untersuche naechstes zeichen
+ FI.
+ untersuche naechstes zeichen:
+ eingabe := incharety (30);
+ IF eingabe = endezeichen
+ THEN endezeichen gegeben := TRUE
+ ELIF eingabe = abbruchzeichen
+ THEN errorstop ("Programm-Abbruch durch <ESC><"
+ + abbruchzeichen + ">!")
+ FI.
+END PROC warte;
+PROC warte (INT CONST sekunden):
+ TEXT VAR eingabe;
+ pruefe abbruch;
+ eingabe := incharety (sekunden * 10);
+ IF eingabe = esc
+
+ THEN untersuche naechstes zeichen
+ FI.
+ untersuche naechstes zeichen:
+ eingabe := incharety (30);
+ IF eingabe = endezeichen
+ THEN endezeichen gegeben := TRUE
+ ELIF eingabe = abbruchzeichen
+ THEN errorstop ("Programm-Abbruch durch <ESC><"
+ + abbruchzeichen + ">!")
+ FI.
+END PROC warte;
+TEXT PROC incharety:
+ IF puffer = ""
+ THEN old incharety
+ ELSE erstes zeichen von puffer
+ FI.
+ erstes zeichen von puffer:
+ TEXT CONST zeichen :: puffer SUB 1;
+
+ puffer := subtext (puffer, 2);
+ zeichen.
+END PROC incharety;
+TEXT PROC incharety (INT CONST timelimit):
+ IF puffer = ""
+ THEN old incharety (timelimit)
+ ELSE erstes zeichen von puffer
+ FI.
+ erstes zeichen von puffer:
+ TEXT CONST zeichen :: puffer SUB 1;
+ puffer := subtext (puffer, 2);
+ zeichen.
+END PROC incharety;
+PROC inchar (TEXT VAR character):
+ REP character := incharety
+ UNTIL character <> "" PER
+END PROC inchar;
+PROC pause:
+ TEXT VAR dummy;
+ inchar (dummy)
+
+END PROC pause;
+PROC pause (INT CONST timelimit):
+ TEXT VAR dummy := incharety (timelimit)
+END PROC pause;
+BOOL PROC abbruch gewuenscht:
+ pruefe abbruch;
+ BOOL VAR entscheidung :: endezeichen gegeben;
+ endezeichen gegeben := FALSE;
+ entscheidung
+END PROC abbruch gewuenscht;
+PROC tue nichts:
+ pruefe abbruch
+END PROC tue nichts;
+PROC trage kanaldaten ein (INT CONST kanalnummer,
+ ROW 2 REAL CONST spannungsbereich,
+ ROW 3 INT CONST kanalparameter):
+
+ spannung [kanalnummer].minimalwert := spannungsbereich [1];
+ spannung [kanalnummer].maximalwert := spannungsbereich [2];
+ kanal [kanalnummer].betriebsart := kanalparameter [1];
+ kanal [kanalnummer].taktzahl := kanalparameter [2];
+ kanal [kanalnummer].steuercode := interface anpassung
+ (kanalnummer, kanalparameter [3])
+END PROC trage kanaldaten ein;
+PROC beende kanaldaten eintragen:
+ kanaldaten sind eingetragen := TRUE
+END PROC beende kanaldaten eintragen;
+
+PROC hole spannungsbereich (INT CONST kanalnummer, REAL VAR u min, u max):
+ u min := spannung [kanalnummer].minimalwert;
+ u max := spannung [kanalnummer].maximalwert
+END PROC hole spannungsbereich;
+INT PROC letzte ausgabe (INT CONST kanalnummer):
+ vorherige ausgabe [kanalnummer]
+END PROC letzte ausgabe;
+PROC pruefe kanal (INT CONST kanalnummer, gewuenschte betriebsart):
+ pruefe abbruch;
+ pruefe kanalnummer;
+ pruefe betriebsart.
+ pruefe kanalnummer:
+ IF kanalnummer < 1 OR kanalnummer > max kanalanzahl
+
+ THEN errorstop ("Kanalnummer " + text (kanalnummer) +
+ " ist unzulaessig !")
+ FI.
+ pruefe betriebsart:
+ IF gewuenschte betriebsart <> kanal [kanalnummer].betriebsart
+ THEN errorstop ("An Kanal " + text (kanalnummer) +
+ " keine " + wunsch + " moeglich!")
+ FI.
+ wunsch:
+ IF gewuenschte betriebsart = analog aus
+ THEN "Analog-Ausgabe"
+ ELIF gewuenschte betriebsart = digital aus
+ THEN "Digital-Ausgabe"
+
+ ELIF gewuenschte betriebsart = digital ein
+ THEN "Digital-Eingabe"
+ ELIF gewuenschte betriebsart = analog ein
+ THEN "Analog-Eingabe"
+ ELSE "Ein- oder Ausgabe"
+ FI.
+END PROC pruefe kanal;
+PROC pruefe abbruch:
+ TEXT VAR zeichen :: incharety;
+ IF zeichen = esc
+ THEN pruefe weiter
+ FI.
+ pruefe weiter:
+ zeichen := incharety (30);
+ IF zeichen = endezeichen
+ THEN endezeichen gegeben := TRUE
+ ELIF zeichen = abbruchzeichen
+ THEN errorstop ("Programm-Abbruch durch <ESC><"
+
+ + abbruchzeichen + ">!")
+ FI.
+END PROC pruefe abbruch;
+PROC oeffne interface (INT VAR status):
+ enable stop;
+ IF kanaldaten sind eingetragen
+ THEN teste interface funktion
+ ELSE status := configuration error code
+ FI.
+ teste interface funktion:
+ leere puffer;
+ out (interface test code);
+ fange antwort;
+ IF antwort = interface okay code
+ THEN status := 0;
+ out (interface open code)
+ ELSE status := interface error code
+
+ FI.
+ leere puffer:
+ puffer := "";
+ REP UNTIL old incharety = "" PER.
+ fange antwort:
+ INT VAR zaehler;
+ TEXT VAR antwort :: "";
+ FOR zaehler FROM 1 UPTO erwartete zeichen REP
+ antwort CAT old incharety (1)
+ PER.
+END PROC oeffne interface;
+PROC schliesse interface:
+ enable stop;
+ out (interface close code)
+END PROC schliesse interface;
+(********************* H I L F S P R O Z E D U R E N *********************)
+PROC teste interface:
+ INT VAR test;
+
+ warte etwas;
+ oeffne interface (test);
+ IF test < 0
+ THEN errorstop (fehlermeldung)
+ ELSE endezeichen gegeben := FALSE;
+ fehler zu melden := FALSE
+ FI.
+ warte etwas:
+ pause (1); pause (1); pause (1); pause (1); pause (1).
+ fehlermeldung:
+ IF test = configuration error code
+ THEN "Interface ist noch nicht konfiguriert!"
+ ELIF test = interface error code
+ THEN "Interface meldet sich nicht!"
+ ELSE "Interface kann nicht geöffnet werden!"
+
+ FI.
+END PROC teste interface;
+PROC fehlerbehandlung:
+ meldung := errormessage;
+ IF meldung <> ""
+ THEN meldung CAT fehlerzeile;
+ fehler zu melden := TRUE
+ FI;
+ clear error;
+ initialisiere interface.
+ fehlerzeile:
+ IF errorline = 0
+ THEN ""
+ ELSE " (bei Zeile " + text (errorline) + ")"
+ FI.
+END PROC fehlerbehandlung;
+INT PROC dezimalwert (TEXT CONST zeichen 1, zeichen 2):
+ 16 * pos (hexzeichen, zeichen 1) + pos (hexzeichen, zeichen 2).
+ hexzeichen: "123456789ABCDEF".
+
+END PROC dezimalwert;
+TEXT PROC hex (TEXT CONST zwei zeichen):
+ hex (code (zwei zeichen SUB 1)) + hex (code (zwei zeichen SUB 2))
+END PROC hex;
+TEXT PROC hex (INT CONST wert):
+ (hexzeichen SUB (wert DIV 16 + 1)) + (hexzeichen SUB (wert MOD 16 + 1)).
+ hexzeichen: "0123456789ABCDEF".
+END PROC hex;
+PROC initialisiere die kanaele:
+ INT VAR kanalnummer;
+ FOR kanalnummer FROM 1 UPTO max kanalanzahl REP
+ trage kanaldaten ein (kanalnummer, keine spannung, leere karte);
+ vorherige ausgabe [kanalnummer] := 0
+
+ PER.
+ keine spannung:
+ ROW 2 REAL : (0.0, 0.0).
+ leere karte:
+ ROW 3 INT : (nicht belegt, 0, 0).
+END PROC initialisiere die kanaele;
+initialisiere die kanaele
+END PACKET ls prozess 1
+