(* ********************************************************** ********************************************************** ** ** ** ls-Prozess 1 ** ** ** ** Anpassung für MUFI im Terminalkanal ** ** ** ** Version 1.02 ** ** ** ** (Stand : 26.01.90) ** ** ** ** ** ** Autoren: Bruno Pollok, Bielefeld ** ** Wolfgang Weber, Bielefeld ** ** ** ** Copyright (C) 1988 Eva Latta-Weber, Bielefeld ** ** Copyright (C) 1990 ERGOS GmbH, Siegburg ** ********************************************************** ********************************************************** *) 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 <" + 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 <" + 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 <" + 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