home *** CD-ROM | disk | FTP | other *** search
/ Chip 1994 February / CHIP0294.ISO / digital / praxis / hwtip / laden.pas < prev    next >
Pascal/Delphi Source File  |  1994-04-21  |  90KB  |  2,165 lines

  1. PROGRAM NiCd_Lader;
  2.  
  3. { ┌────────────────────────────────────────────────────────────────────────┐
  4.   │    LADESTEUERUNG VON NI-CD-AKKUS VERSION 2.0 + Graphik                 │
  5.   │    PROGRAMMIERER   : CARSTEN STELLING                                  │
  6.   │    PASCAL VERSION  : 6.01                                              │
  7.   │    MS-DOS VERSION  : 6.02                                              │
  8.   │    LETZTE ÄNDERUNG : 15.04.1994  15:37                                 │
  9.   └────────────────────────────────────────────────────────────────────────┘ }
  10.  
  11. USES  DOS, GRAPH, CRT, PRINTER;                    { Standard-Units einbinden }
  12.  
  13. LABEL START, LADEN, ENTLADEN, EINTRAG,
  14.       LEER, VOLL, DEFEKT;                          { Sprungmarken }
  15.  
  16. CONST
  17.       Akku_Datei : STRING [25] = 'C:\AKKULAD\EINST.NCL';    { Einstellungen }
  18.       Akku_Pdatei: STRING [25] = 'C:\AKKULAD\PORTS.NCL';    { Schnittstellen }
  19.       Mess_Datei : STRING [25] = 'C:\AKKULAD\MESS_1.NCL';   { Meßdatenerfassung }
  20.       Widst_Datei: STRING [25] = 'C:\AKKULAD\SETUP.NCL';    { Widerstandswerte }
  21.       Grfk_Pfad  : STRING [30] = 'C:\AKKULAD';              { BGI-Grafiktreiber-Suchpfad }
  22.  
  23.       Ref : REAL = 5.0;                                     { Wert der Referenzspannung }
  24.  
  25. TYPE  Akku_rec = RECORD                            { Akku - Daten }
  26.                    Kap      : REAL;                { Nennkapazität }
  27.                    Spg      : REAL;                { Nennspannung }
  28.                    Algor    : BYTE;                { Ladealgorithmus }
  29.                    Laden    : BOOLEAN;             { Status Laden }
  30.                    Entladen : BOOLEAN;             { Status Entladen }
  31.                    Defekt   : BOOLEAN;             { Status Defekt }
  32.                    Online   : BOOLEAN;             { Akku im Ladeprozeß }
  33.                    V_Summe  : REAL;                { Spannungssumme }
  34.                    V_Mittel : REAL;                { Mittelwert der Spannung }
  35.                    V_Vorher : REAL;                { Vorheriger Wert der Spannung }
  36.                    Proben   : LONGINT;             { Anzahl der Meßproben/Minute }
  37.                    Zyklus   : BYTE;                { Anzahl der Lade-/Entladezyklen }
  38.                  END;
  39.  
  40.       Akku_str = STRING [8];                       { String für Dateizuweisungen }
  41.  
  42.       Akku_arr = ARRAY [1..4] OF Akku_rec;         { Array der Akku-Daten }
  43.  
  44.       Messen   = ARRAY [1..4] OF REAL;             { Array der Messwerte }
  45.  
  46.       Wid      = ARRAY [1..4] OF REAL;             { Array der Widerstandswerte aus SETUP }
  47.  
  48. VAR   Regs       : REGISTERS;                      { DOS Registertypen }
  49.  
  50.       Akku       : Akku_arr;                       { Akku - Speichervariablen }
  51.       Akku_Dat   : FILE OF Akku_str;               { Speichert Akku-Informationen }
  52.       Akku_Port  : FILE OF Akku_str;               { Speichert eingest. Ports }
  53.       Akku_Wid   : FILE OF Wid;                    { Liest Widerstandswerte }
  54.       Mess_Daten : FILE OF Messen;                 { Speichert Meßdaten }
  55.       Messwert   : Messen;                         { String für Meßwertumwandlung }
  56.       R          : Wid;                            { Widerstandswerte 1..4 }
  57.  
  58.       Pruef   : REAL;                              { Ablagevar. für 1. Wandlung }
  59.       Mess1   : ARRAY [1..4] OF REAL;              { Zwischenspeicher für Messwert Hi-Pot. }
  60.       Mess2   : ARRAY [1..4] OF REAL;              { Zwischenspeicher für Messwert Lo-Pot. }
  61.       Portadr : WORD;                              { COM1, COM2 Portadresse }
  62.       Akku_Nr : BYTE;                              { Akkunummer 1..4 }
  63.       Zaehler : BYTE;                              { Umlaufzaehler während des Ladens }
  64.       Z       : BYTE;                              { Zaehler Hilfsvariable }
  65.       Taste   : CHAR;                              { für Tastendruck }
  66.       Maust   : WORD;                              { Maustasten-Status }
  67.       Mausx   : WORD;                              { Maus X-Position }
  68.       Mausy   : WORD;                              { Maus Y-Position }
  69.       Exit_Adr: POINTER;                           { Programmabbruchadresse }
  70.       Bed_Abr : BOOLEAN;                           { Bediener-Abbruch }
  71.       Drucken : BOOLEAN;                           { Protokoll Drucken }
  72.       Dr_OK   : BOOLEAN;                           { Druck Fehlerhaft }
  73.       Zoom    : BYTE;                              { Zeitauflösung fein=2, grob=1 }
  74.       CurAnf  : BYTE;                              { Cursorposition }
  75.       CurEnd :  BYTE;
  76.       AD_Init_Err : BOOLEAN;                       { Initialisierungsfehler A/D-Wandler }
  77.  
  78.       std, min, sek, s100             : WORD;      { akt. Uhrzeit }
  79.       stdalt, minalt, sekalt, s100alt : WORD;      { alte Uhrzeit }
  80.       jahr, mon, tag, wtag            : WORD;      { Datum }
  81.  
  82.       AdrLPT  : WORD;                              { nimmt aktive LPT-Adresse auf }
  83.                                                    { zeigen auf BIOS-Kommunikationsbereich }
  84.       AdrLPT1 : WORD ABSOLUTE $40:$08;             { Adr. der 1. parallelen Schnittstelle }
  85.       AdrLPT2 : WORD ABSOLUTE $40:$0A;             { Adr. der 2. parallelen Schn. }
  86.       AdrLPT3 : WORD ABSOLUTE $40:$0F;             { Adr. der 3. parallelen Schn. }
  87.       AdrCOM1 : WORD ABSOLUTE $40:$00;             { Adr. der 1. seriellen Schn. }
  88.       AdrCOM2 : WORD ABSOLUTE $40:$02;             { Adr. der 2. seriellen Schn. }
  89.       AdrCOM3 : WORD ABSOLUTE $40:$04;             { Adr. der 3. seriellen Schn. }
  90.       AdrCOM4 : WORD ABSOLUTE $40:$06;             { Adr. der 4. seriellen Schn. }
  91.  
  92.       Ser     : Akku_str;                          { serielle Schnittstelle }
  93.       Par     : Akku_str;                          { parallele Schnittstelle }
  94.  
  95. { ┌────────────────────────────────────────────────────────────────────────┐
  96.   │    CURSORPOSITION UND ERSCHEINUNGSBILD ERMITTELN                       │
  97.   │    EINGABEN : KEINE                                                    │
  98.   │    AUSGABE  : CURSORPOSITION                                           │
  99.   └────────────────────────────────────────────────────────────────────────┘ }
  100. PROCEDURE CursorErmitteln;
  101.  
  102. BEGIN
  103.   Regs.AH := $0F;                                  { Auslesen des Video-Modus }
  104.   INTR ($10, Regs);                                { AL = Video-Modus-Kennung }
  105.                                                    { AH = Anzahl der Zeichen / Zeile }
  106.                                                    { BH = Nr. der Bildschirmseite }
  107.   Regs.AH := $03;                                  { Auslesen der Cursor Position }
  108.   INTR ($10, Regs);                                { Eing. BH = Nr. der Bildschirmseite }
  109.   CurAnf := Regs.CH;
  110.   CurEnd := Regs.CL;
  111. END;
  112.  
  113. { ┌────────────────────────────────────────────────────────────────────────┐
  114.   │    CURSOR AUSSCHALTEN                                                  │
  115.   │    EINGABEN : KEINE                                                    │
  116.   │    AUSGABE  : CURSOR UNSICHTBAR                                        │
  117.   └────────────────────────────────────────────────────────────────────────┘ }
  118. PROCEDURE CursorAus;
  119.  
  120. BEGIN
  121.   Regs.AH := $01;                                  { Erscheinungsbild des Cursors }
  122.   Regs.CH := $20;                                  { Außerhalb der Startzeile pos. }
  123.   Regs.CL := $00;                                  { Endzeile 0 }
  124.   INTR ($10, Regs);
  125. END;
  126.  
  127. { ┌────────────────────────────────────────────────────────────────────────┐
  128.   │    CURSOR EINSCHALTEN                                                  │
  129.   │    EINGABEN : KEINE                                                    │
  130.   │    AUSGABE  : CURSOR SICHTBAR                                          │
  131.   └────────────────────────────────────────────────────────────────────────┘ }
  132. PROCEDURE CursorEin;
  133.  
  134. BEGIN
  135.   Regs.AH := $01;                                  { Erscheinungsbild }
  136.   Regs.CH := CurAnf;                               { Startzeile = alter Wert }
  137.   Regs.CL := CurEnd;                               { Endzeile = alter Wert }
  138.   INTR ($10, Regs);
  139. END;
  140.  
  141. { ┌────────────────────────────────────────────────────────────────────────┐
  142.   │    UMWANDELN EINER 16-BIT-DEZIMALZAHL IN EINE HEXADEZIMALE ZAHL        │
  143.   │    EINGABEN : DEZIMALZAHL, ANZAHL DER AUSGABESTELLEN                   │
  144.   │    AUSGABE  : HEXADEZIMALZAHL                                          │
  145.   └────────────────────────────────────────────────────────────────────────┘ }
  146. FUNCTION HexZahl (DezZahl : WORD; Stellen: BYTE):STRING;
  147. VAR Wandeln      : BYTE;                           { Variablendeklaration }
  148.     Zeichen      : STRING [1];
  149.     Zeichenkette : STRING [5];
  150.     Puffer       : STRING [5];
  151.  
  152.   PROCEDURE Eintragen (Ganzzahl : WORD);           { Zeichen in den String eintragen }
  153.   VAR Asciinr : BYTE;                              { ASCII-Nr. des Zeichens }
  154.     BEGIN
  155.      IF Ganzzahl > 9 THEN Asciinr := Ganzzahl + 55 { ASCII-Nr. für Zahlen }
  156.       ELSE Asciinr := Ganzzahl + 48;               { ASCII-Nr. für Buchstaben }
  157.       Zeichenkette := Zeichenkette + CHR (Asciinr);
  158.     END;
  159.  
  160. BEGIN
  161.   Zeichenkette := '';                              { Zeichenkette löschen }
  162.  
  163.   FOR Wandeln := 1 TO Stellen DO                   { x Stellen umwandeln }
  164.     BEGIN
  165.      Eintragen (DezZahl MOD 16);                   { Rest der Division eintragen }
  166.      DezZahl := DezZahl DIV 16;                    { ganzzahliger Anteil wird gespeichert }
  167.     END;
  168.  
  169.   Puffer := '$';                                   { $-Zeichen vorweg }
  170.   FOR Wandeln := 1 TO Stellen DO                   { x Stellen umwandeln }
  171.     BEGIN
  172.      Zeichen := COPY (Zeichenkette, Stellen + 1 - Wandeln, 1);
  173.      Puffer := Puffer + Zeichen;                   { Zeichenkette herstellen }
  174.     END;
  175.  
  176.    HexZahl := Puffer;                              { Zuweisung }
  177. END;
  178.  
  179. { ┌────────────────────────────────────────────────────────────────────────┐
  180.   │    FORMATIERTE ZEITAUSGABE                                             │
  181.   │    EINGABEN : STUNDEN, MINUTEN ODER SEKUNDEN                           │
  182.   │    AUSGABEN : ZWEISTELLIGE AUSGABE OHNE UNTERDRÜCKUNG VON F. NULLEN    │
  183.   └────────────────────────────────────────────────────────────────────────┘ }
  184. FUNCTION TFormat (Zeit : WORD) :STRING;
  185.  
  186. VAR Zehner : CHAR;                                 { Variablendeklaration }
  187.     Einer  : CHAR;
  188.  
  189. BEGIN;
  190.   Zehner := CHR (Zeit DIV 10 + 48);                { ASCII-Zeichen der Zehner-Stelle }
  191.   Einer  := CHR (Zeit MOD 10 + 48);                { ASCII-Zeichen der Einer-Stelle }
  192.   TFormat := Zehner + Einer;                       { FORMAT = Zehner + Einer }
  193. END;
  194.  
  195.  {┌────────────────────────────────────────────────────────────────────────┐
  196.   │    FENSTER FÜR FEHLERAUSGABE, WARNUNG                                  │
  197.   │    EINGABEN : KEINE                                                    │
  198.   │    AUSGABEN : OFFNET EIN NEUES FENSTER                                 │
  199.   └────────────────────────────────────────────────────────────────────────┘ }
  200. PROCEDURE Fehler_Fenster;
  201. BEGIN
  202.     WINDOW (17, 10, 66, 16);
  203.     TEXTBACKGROUND (12);
  204.     TEXTCOLOR (15);
  205.     CLRSCR;
  206.     WRITELN ('╔═════ WARNUNG ═════════════════════════════════╗');
  207.     WRITELN ('║                                               ║');
  208.     WRITELN ('║                                               ║');
  209.     WRITELN ('║                                               ║');
  210.     WRITELN ('║                                               ║');
  211.     WRITELN ('║                                               ║');
  212.     WRITE ('╚═══════════════════════════════════════════════╝');
  213.    SOUND (1200);
  214.    DELAY (100);
  215.    NOSOUND;
  216. END;
  217.  
  218. { ┌────────────────────────────────────────────────────────────────────────┐
  219.   │    WIDERSTANDSWERTE AUS DATEI SETUP ERMITTELN                          │
  220.   │    EINGABEN : KEINE                                                    │
  221.   │    AUSGABEN : KEINE                                                    │
  222.   └────────────────────────────────────────────────────────────────────────┘ }
  223.  
  224. PROCEDURE Wid_Werte;
  225.  
  226. VAR OK : BOOLEAN;
  227.  
  228. BEGIN
  229.   ASSIGN (Akku_Wid, Widst_Datei);
  230.   {$I-}
  231.    RESET (Akku_Wid);
  232.   {$I-}
  233.   OK := IORESULT=0;
  234.   IF NOT OK THEN
  235.    BEGIN
  236.     Fehler_Fenster;
  237.      GOTOXY (3, 3);
  238.      WRITE ('Datei ',Widst_Datei, ' nicht gefunden.');
  239.      GOTOXY (3, 4);
  240.      WRITE ('Starten Sie das Programm SETUP.EXE !');
  241.      GOTOXY (3, 6);
  242.      WRITE ('Taste zum Ausführen drücken. >');
  243.       REPEAT UNTIL KEYPRESSED;
  244.       Taste := READKEY;
  245.       WINDOW (1, 1, 80, 25);
  246.       TEXTBACKGROUND (0);
  247.       CLRSCR;
  248.       TEXTCOLOR (7);
  249.       WRITELN ('Programm beendet.');
  250.       WRITELN ('Starten Sie SETUP.EXE !');
  251.      HALT;
  252.     END;
  253.  
  254.   READ (Akku_Wid, R);
  255. END;
  256.  
  257. { ┌────────────────────────────────────────────────────────────────────────┐
  258.   │    MAUSTREIBER INITIALISIEREN                                          │
  259.   │    EINGABEN : AX-REGISTER                                              │
  260.   │    AUSGABEN : DOS INTERRUPT $33 FUNKT. 0 ERGEBNIS IN AX                │
  261.   └────────────────────────────────────────────────────────────────────────┘ }
  262. PROCEDURE Mausinit;
  263.  
  264. BEGIN
  265.   Regs.ax := 0;                                    { Funktionsnummer in AX }
  266.   INTR ($33, Regs);                                { DOS-Interrupt nr. 33h }
  267.    IF Regs.ax = 0 THEN                             { Rückmeldung in AX }
  268.     BEGIN                                          { wenn 0 - Fehlermeldung }
  269.      Fehler_Fenster;
  270.      GOTOXY (3, 3);
  271.      WRITE ('Maustreiber konnte nicht initialisiert werden.');
  272.      GOTOXY (3, 4);
  273.      WRITE ('Falscher oder fehlender Maustreiber.');
  274.      GOTOXY (3, 6);
  275.      WRITE ('Taste zum Quittieren betätigen. >');
  276.       REPEAT UNTIL KEYPRESSED;
  277.       Taste := READKEY;
  278.     END;
  279. END;
  280.  
  281. { ┌────────────────────────────────────────────────────────────────────────┐
  282.   │    MAUSCURSOR IM TEXTMODUS AN/AUS-SCHALTEN                             │
  283.   │    EINGABEN : AX-REGISTER (1=AN, 2=AUS)                                │
  284.   │    AUSGABEN : MAUSCURSOR SICHTBAR/UNSICHTBAR                           │
  285.   └────────────────────────────────────────────────────────────────────────┘ }
  286. PROCEDURE Mausein (Schalter : BYTE);
  287.  
  288. BEGIN
  289.   Schalter := 2 - Schalter;                        { Normierung auf 0 / 1 }
  290.    IF Schalter > 2 THEN Schalter := 2;             { Sicherheit }
  291.    IF Schalter < 1 THEN Schalter := 1;
  292.   Regs.ax := Schalter;                             { AX=2 - Cursor aus }
  293.                                                    { AX=1 - Cursor an }
  294.   INTR ($33, Regs);                                { DOS-Interrupt Nr. 33h }
  295. END;
  296.  
  297. { ┌────────────────────────────────────────────────────────────────────────┐
  298.   │    MAUSSTATUS VIA DOS INERRUPT $33 FUNKTION 3                          │
  299.   │    EINGABEN : KEINE                                                    │
  300.   │    AUSGABEN : X-, Y-KOORDINATEN, TASTENSTATUS                          │
  301.   └────────────────────────────────────────────────────────────────────────┘ }
  302. PROCEDURE Mausstatus;
  303.  
  304. BEGIN
  305.   Regs.ax := 3;                                    { Funktion 3 }
  306.   INTR ($33, Regs);                                { DOS-Interrupt Nr. 33h }
  307.    Maust := Regs.bx;                               { Status der Maustasten }
  308.    Mausx := Regs.cx;                               { Maus X-Position }
  309.    Mausy := Regs.dx;                               { Maus Y-Position }
  310.  
  311. END;
  312.  
  313. { ┌────────────────────────────────────────────────────────────────────────┐
  314.   │    MAUSBEWEGUNGSBEREICH FESTLEGEN VIA DOS INERRUPT $33 FUNKTION 7, 8   │
  315.   │    EINGABEN : X1, Y1, X2, Y2                                           │
  316.   │    AUSGABEN : BEWEGUNGSBEREICH DES MAUSCURSORS                         │
  317.   └────────────────────────────────────────────────────────────────────────┘ }
  318. PROCEDURE Mausbereich (X1, Y1, X2, Y2 : WORD);
  319.  
  320. BEGIN
  321.   Regs.AX := 7;
  322.   Regs.CX := X1;
  323.   Regs.DX := X2;
  324.   INTR ($33, Regs);
  325.  
  326.   Regs.AX := 8;
  327.   Regs.CX := Y1;
  328.   Regs.DX := Y2;
  329.   INTR ($33, Regs);
  330. END;
  331.  
  332.  {┌────────────────────────────────────────────────────────────────────────┐
  333.   │    AUF TASTENDRUCK ODER MAUSTASTE WARTEN                               │
  334.   │    EINGABEN : TASTATUR, MAUS                                           │
  335.   │    AUSGABE  : KEINE                                                    │
  336.   └────────────────────────────────────────────────────────────────────────┘ }
  337. PROCEDURE Warten;
  338.  
  339. VAR Taste : CHAR;
  340.  
  341. BEGIN
  342.   Mausein (1);
  343.    REPEAT;
  344.     Mausstatus;
  345.    UNTIL (KEYPRESSED) OR (Maust <> 0);
  346.   IF KEYPRESSED THEN
  347.    BEGIN
  348.     Taste := READKEY;
  349.     Taste := ' ';
  350.    END;
  351. END;
  352.  
  353. { ┌────────────────────────────────────────────────────────────────────────┐
  354.   │    TAKTUNABHÄNGIGE WARTESCHLEIFE FÜR MIKROSEKUNDEN                     │
  355.   │    EINGABEN : VERZÖGERUNGSZEIT IN µs                                   │
  356.   │    AUSGABEN : PROGRAMMUNTERBRECHUNG                                    │
  357.   └────────────────────────────────────────────────────────────────────────┘ }
  358. PROCEDURE Microdelay (del : LONGINT);              { Taktunabhängige Verzögerung }
  359.  
  360. VAR  T8, T8s            : LONGINT;                 { Hilfsvariablen }
  361.      lb1, hb1, lb2, hb2 : BYTE;                    { Lobyte, Hibyte des PIT }
  362.  
  363. BEGIN
  364.     IF del > 50000000 THEN DELAY ((del + 500) div 1000)
  365.      ELSE
  366.       BEGIN
  367.        T8 := 0;
  368.        T8s := (del * 16) div 27;                   { 16 /27 /4 * 6.704 = 0.993 }
  369.         PORT [$43]:= 0;                            { Lese Timer }
  370.         lb1 := port [$40];                         { Lese Lowbyte }
  371.         hb1 := port [$40];                         { Lese Highbyte }
  372.           REPEAT;                                  { Je Durchgang 6.704 us }
  373.             INC (T8 ,4);
  374.                REPEAT;
  375.                  PORT [$43] := 0;
  376.                  lb2 := PORT [$40];
  377.                  hb2 := PORT [$40];
  378.                UNTIL (( WORD (lb1) + WORD (hb1) SHL 8) AND $FFFC) <>
  379.                      (( WORD (lb2) + WORD (hb2) SHL 8) AND $FFFC);
  380.                                                   { Änderung der letzten 2 Bits = 3.352 us }
  381.                 REPEAT
  382.                   PORT [$43] := 0;
  383.                   lb1 := PORT [$40];
  384.                   hb1 := PORT [$40];
  385.                 UNTIL (( WORD (lb1) + WORD (hb1) SHL 8) AND $FFFC) <>
  386.                       (( WORD (lb2) + WORD (hb2) SHL 8) AND $FFFC);
  387.                                                   { Änderung der letzten 2 Bits = 3.352 us }
  388.           UNTIL T8 >= T8s;
  389.    END;
  390. END;
  391.   
  392. { ┌────────────────────────────────────────────────────────────────────────┐
  393.   │    ANALOGMESSWERTKARTE PROGRAMMIEREN UND SIGNALE AUSWERTEN             │
  394.   │    EINGABEN : SCHNITTSTELLENNUMMER                                     │
  395.   │    AUSGABEN : SPANNUNG DER 8 MESSKANÄLE IM BEREICH 0V BIS 5V           │
  396.   └────────────────────────────────────────────────────────────────────────┘ }
  397. FUNCTION AD_Messwert (Kanal : BYTE) : REAL;        { Aufruf mit Kanalnummer 1 bis 8 }
  398.  
  399. { Kontrollsequenzen für LT1090 }
  400. CONST Auswahl : ARRAY [1..8] OF WORD = ($F71+0, $F71+2, $F71+8, $F71+$A, $F71+4, $F71+6, $F71+$C, $F71+$E);
  401.  
  402. VAR   Control : WORD;                              { Kontroll-Register }
  403.       pout    : WORD;                              { COM Modemkontrollregister-Adresse }
  404.       pin     : WORD;                              { COM Modemstatusregister-Adresse }
  405.       Z       : BYTE;                              { Schleifenzähler }
  406.       skal    : INTEGER;                           { Skalierung }
  407.  
  408.  
  409. BEGIN                                             { Ansteuerung des A/D Wandlers Conrad Best.-Nr. 97 97 67 }
  410.     pout := Portadr + 4;                          { MCR = COM Basisadresse + 4 }
  411.     pin := Portadr + 6;                           { MSR = COM Basisadresse + 6 }
  412.     Control := Auswahl [Kanal];                   { Kontrollregister laden }
  413.  
  414.     PORT [pout] := PORT [pout] AND $FD OR $01;
  415.      Microdelay (5);
  416.     PORT [pout] := PORT [pout] OR $02;
  417.  
  418.     FOR Z := 1 TO 12 DO                           { 12 Bit an A/D-Wandler }
  419.       BEGIN
  420.         Microdelay (5);
  421.           PORT [pout] := $FE AND PORT [pout];
  422.         Microdelay (5);
  423.           PORT [pout] := PORT [pout] OR $02;
  424.            IF NOT ODD (Control) THEN
  425.              BEGIN
  426.                Microdelay (5);
  427.                  PORT [pout] := port [pout] AND $FD;
  428.              END;
  429.           Microdelay (5);
  430.             PORT [pout] := PORT [pout] OR $01;
  431.           Control:= Control SHR 1;
  432.        END;
  433.  
  434.     Microdelay (5);
  435.       PORT [pout] := PORT [pout] AND $FD OR $01;
  436.     Microdelay (5);
  437.       PORT [pout] := PORT [pout] OR $02;
  438.     Microdelay (250);
  439.  
  440.     skal:=0;
  441.     Control := Auswahl [Kanal];
  442.  
  443.     FOR z:= 1 TO 12 DO                             { 12 Bits lesen und skalieren }
  444.       BEGIN
  445.         Microdelay (5);
  446.           PORT [pout] := $FE AND PORT [pout];
  447.         Microdelay (5);
  448.           PORT [pout] := PORT [pout] OR $02;
  449.         Microdelay (5);
  450.           PORT [pout] := PORT [pout] OR $01;
  451.             IF z < 11 THEN
  452.               BEGIN
  453.                 skal := skal SHL 1;
  454.                 Microdelay (5);
  455.                   IF NOT (( PORT [pin] AND $10) = $10) THEN INC (skal);
  456.               END;
  457.           Control := Control SHR 1;
  458.      END;
  459.  
  460.   AD_Messwert := skal / 1023.0 * ref;              { Umrechnen auf Volt }
  461.  
  462. END;                                               { Ende der Funktion }
  463.  
  464. { ┌────────────────────────────────────────────────────────────────────────┐
  465.   │    ANALOGMESSWERTKARTE INITIALISIEREN UND PRÜFEN                       │
  466.   │    EINGABEN : ADRESSE COM X                                            │
  467.   │    AUSGABEN : FEHLERMELDUNG WENN MESSWERT 5V                           │
  468.   └────────────────────────────────────────────────────────────────────────┘ }
  469. PROCEDURE AD_Wandler_Init;
  470.  
  471. VAR Antw : CHAR;
  472.  
  473. BEGIN
  474.   Pruef := AD_Messwert (2);                        { 1. Messung ist falsch }
  475.   DELAY (50);                                      { 50 ms warten }
  476.   Pruef := AD_Messwert (1);                        { 2. Messung ist auswertbar }
  477.     IF Pruef = 5.0 THEN                            { wahrscheinlich falscher Port }
  478.       BEGIN
  479.         Fehler_Fenster;
  480.         GOTOXY (3, 2);
  481.         WRITE ('AD-Wandlerkarte an Port: ',ser,' nicht entdeckt!');
  482.         GOTOXY (3, 3);
  483.         WRITE ('Prüfen Sie die "GRUNDEINSTELLUNGEN"');
  484.         GOTOXY (3, 4);
  485.         WRITE ('oder die A/D-Wandlerkarte am seriellen Port.');
  486.         GOTOXY (3, 6);
  487.         WRITE ('Zurück zum Hauptmenü mit Tastendruck. >');
  488.           REPEAT UNTIL KEYPRESSED;
  489.           Antw := READKEY;
  490.           Antw := ' ';
  491.         AD_Init_err := TRUE;
  492.        END;
  493. END;
  494.  
  495. { ┌────────────────────────────────────────────────────────────────────────┐
  496.   │    LADETRANSISTOR DUCHSTEUERN                                          │
  497.   │    EINGABEN : LADEPLATZ-NUMMER                                         │
  498.   │    AUSGABE  : SETZT BIT 1 (3, 5, 7) AM PARALLELPORT AUF "1"            │
  499.   └────────────────────────────────────────────────────────────────────────┘ }
  500. PROCEDURE Laden_ein (Platz : BYTE);
  501.  
  502. BEGIN
  503.   PORT [AdrLPT] := PORT [AdrLPT] OR 1 SHL ((Platz - 1 ) * 2);
  504. END;
  505.  
  506. { ┌────────────────────────────────────────────────────────────────────────┐
  507.   │    LADETRANSISTOR SPERREN                                              │
  508.   │    EINGABEN : LADEPLATZ-NUMMER                                         │
  509.   │    AUSGABE  : SETZT BIT 1 (3, 5, 7) AM PARALLELPORT AUF "0"            │
  510.   └────────────────────────────────────────────────────────────────────────┘ }
  511. PROCEDURE Laden_aus (Platz : BYTE);
  512.  
  513. BEGIN
  514.  PORT [AdrLPT] := PORT [AdrLPT] AND NOT  1 SHL ((Platz - 1)  * 2);
  515. END;
  516.  
  517. { ┌────────────────────────────────────────────────────────────────────────┐
  518.   │    ENTLADE-MOSFET DURCHSTEUERN                                         │
  519.   │    EINGABEN : LADEPLATZ-NUMMER                                         │
  520.   │    AUSGABE  : SETZT BIT 0 (2, 4, 6) AM PARALLELPORT AUF "1"            │
  521.   └────────────────────────────────────────────────────────────────────────┘ }
  522. PROCEDURE Entladen_ein (Platz : BYTE);
  523.  
  524. BEGIN
  525.  PORT [AdrLPT] := PORT [AdrLPT] OR  2 SHL ((Platz - 1) * 2);
  526. END;
  527.  
  528.  
  529. { ┌────────────────────────────────────────────────────────────────────────┐
  530.   │    ENTLADE-MOSFET SPERREN                                              │
  531.   │    EINGABEN : LADEPLATZ-NUMMER                                         │
  532.   │    AUSGABE  : SETZT BIT 0 (2, 4, 6) AM PARALLELPORT AUF "0"            │
  533.   └────────────────────────────────────────────────────────────────────────┘ }
  534. PROCEDURE Entladen_aus (Platz : BYTE);
  535.  
  536. BEGIN
  537.  PORT [AdrLPT] := PORT [AdrLPT]  AND NOT 2 SHL ((Platz - 1) * 2);
  538. END;
  539.  
  540. { ┌────────────────────────────────────────────────────────────────────────┐
  541.   │    GITTERNETZLINIEN ZEICHNEN                                           │
  542.   │    EINGABEN : LADEPLATZ-NUMMER                                         │
  543.   │    AUSGABE  : LADEKURVE IN EIN KOORDINATENSYSTEM SCHREIBEN             │
  544.   └────────────────────────────────────────────────────────────────────────┘ }
  545. PROCEDURE Gitternetz;
  546.  
  547. VAR  X, Y : WORD;                                  { Zeichenkoordinaten }
  548.  
  549. BEGIN
  550.    SETCOLOR (8);                                   { Farbe grau }
  551.     SETLINESTYLE (DOTTEDLN, 0, 1);                 { Punktierte Linie }
  552.      X := 70;                                      { Startwert }
  553.       REPEAT
  554.        LINE (X, 400, X, 60);                       { Linie zeichnen }
  555.        INC (X, 20);                                { X-Position erhöhen }
  556.       UNTIL X > 600;                               { bis 600 überschritten }
  557.  
  558.      Y := 80;                                      { Prozedur mit Y wiederholen }
  559.       REPEAT
  560.        LINE (50, Y, 600, Y);
  561.        INC (Y, 20);
  562.       UNTIL Y > 380;
  563.  
  564.    SETLINESTYLE (SOLIDLN, 0, 1);                   { Durchgezogene Linie, dünn }
  565.    SETCOLOR (4);                                   { Farbe rot }
  566.    LINE (50 ,240 ,595 ,240);                       { 1.2V-Bezugslinie zeichnen }
  567.  
  568.    SETLINESTYLE (SOLIDLN, 0, 2);                   { normale Linienstärke }
  569. END;
  570.  
  571. { ┌────────────────────────────────────────────────────────────────────────┐
  572.   │    PLOTTEN DER LADEKURVEN                                              │
  573.   │    EINGABEN : X1, Y1, OFFSET, LÖSCHEN                                  │
  574.   │    AUSGABE  : 4 LADEKURVEN IN DAS KOORDINATENSYSTEM SCHREIBEN          │
  575.   └────────────────────────────────────────────────────────────────────────┘ }
  576. PROCEDURE Plotten (Offs : LONGINT; Clr : BOOLEAN; Anf_std : WORD; Anf_min : WORD);
  577.  
  578. LABEL PLOT_ENDE;
  579.  
  580. VAR  X1 : WORD;                                    { X-Koordinaten }
  581.      X2 : WORD;                                    { X1=Anfang, X2=Ende }
  582.      Y1 : ARRAY [1..4] OF WORD;                    { Y-Koordinaten }
  583.      Y2 : ARRAY [1..4] OF WORD;                    { Y1=Anfang, Y2=Ende }
  584.      Ze : ARRAY [1..4] OF BOOLEAN;                 { Zeichnen erlaubt }
  585.  
  586.      End_std     : WORD;                           { Zeit Ende }
  587.      Dummy       : WORD;                           { Hilfsvar. für 24 Std. }
  588.      Puffer      : STRING;
  589.  
  590.      D_Zeiger : WORD;                              { Datei-Zeigervariable }
  591.      Z        : BYTE;                              { Zählvariable }
  592.      Err      : INTEGER;                           { Fehler }
  593.      OK       : BOOLEAN;                           { IO-RESULT Var. }
  594.  
  595. BEGIN
  596.        X1 := 52;                                   { Start bei X-Pos. 52 }
  597.        X2 := X1 + Zoom;
  598.        D_Zeiger := 6;                              { Element 0 = Datum }
  599.                                                    { Element 1 = Zeit }
  600.                                                    { Element 2 = Kapazität }
  601.                                                    { Element 3 = Spannung }
  602.                                                    { Element 4 = Algorithmus }
  603.                                                    { Element 5 = 1. Messwert }
  604.  
  605.     Anf_std := Anf_Std + (Offs DIV 60);
  606.     Dummy := Anf_Std DIV 24;
  607.     DEC (Anf_std, Dummy * 24);
  608.     Puffer := TFormat (Anf_std) + ':' + TFormat (Anf_min);
  609.     IF Clr = TRUE THEN SETCOLOR (0) ELSE SETCOLOR (9);
  610.     OUTTEXTXY (30, 410, Puffer);
  611.  
  612.     FOR Z := 1 TO 4 DO
  613.      BEGIN
  614.       End_std := Anf_std + (Z * Zoom);
  615.       Dummy := End_Std DIV 24;
  616.       DEC (End_Std, Dummy * 24);
  617.       Puffer := TFormat (End_std) + ':' + Tformat (Anf_min);
  618.       IF CLR = TRUE THEN SETCOLOR (0) ELSE SETCOLOR (9);
  619.       OUTTEXTXY (30 + 120 * Z, 410, Puffer);
  620.      END;
  621.  
  622.      FOR Z := 1 TO 4 DO                            { Initialisieren }
  623.        BEGIN
  624.         Ze [Z] := TRUE;
  625.        END;
  626.  
  627.        RESET (Mess_Daten);                         { Zeiger auf Anfang }
  628.        SEEK (Mess_Daten, D_Zeiger + Offs);         { neues Element suchen }
  629.  
  630.      REPEAT;
  631.        D_Zeiger := FILEPOS (Mess_Daten);           { Elementnummer ermitteln }
  632.        DEC (D_Zeiger, 1);                          { eine Elementnummer zurück }
  633.        SEEK (Mess_Daten, D_Zeiger);                { neues Element suchen }
  634.        {$I-}
  635.        READ (Mess_Daten, Messwert);                { Messwerte einlesen }
  636.        {$I+}
  637.         OK := IORESULT=0;
  638.          IF (NOT OK) OR (EOF (Mess_Daten)) THEN GOTO PLOT_ENDE;
  639.            FOR Z := 1 TO 4 DO
  640.              BEGIN
  641.                IF Messwert [Z] >= 777 THEN Ze [Z] := FALSE;
  642.              END;
  643.  
  644.         FOR Z := 1 TO 4 DO                         { Ursprung der Linie berechnen }
  645.          BEGIN
  646.           IF (Messwert [Z] < 0) THEN Messwert [Z] := 0;
  647.            Y1 [Z] := TRUNC ((1.2 - Messwert [Z]) * 400 + 240);
  648.           IF Y1 [Z] > 400 THEN Y1 [Z] := 398;
  649.           IF Y1 [Z] < 60 THEN Y1 [Z] := 60;
  650.          END;
  651.  
  652.  
  653.        {$I-}
  654.        READ (Mess_Daten, Messwert);                { neue Messwerte lesen }
  655.        {$I+}
  656.         OK := IORESULT=0;
  657.          IF (NOT OK) OR (EOF (Mess_Daten)) THEN GOTO PLOT_ENDE;
  658.  
  659.            FOR Z := 1 TO 4 DO                      { Prüfen ob Linie sichtbar sein soll }
  660.              BEGIN
  661.                IF Messwert [Z] >= 777 THEN Ze [Z] := FALSE;
  662.              END;
  663.  
  664.         FOR Z := 1 TO 4 DO                         { Ziel der Linie berechnen }
  665.          BEGIN
  666.           IF Z = 1 THEN SETCOLOR (10);             { 1. Durchlauf in hellgrün }
  667.           IF Z = 2 THEN SETCOLOR (13);             { 2. Durcklauf in magenta }
  668.           IF Z = 3 THEN SETCOLOR (7);              { 3. Durchlauf in grau }
  669.           IF Z = 4 THEN SETCOLOR (1);              { 4. Durchlauf in blau }
  670.           IF Clr = TRUE THEN SETCOLOR (0);         { Löschmodus in schwarz }
  671.  
  672.           IF (Messwert [Z] < 0) THEN Messwert [Z] := 0;   { Zielpunkt berechnen }
  673.           Y2 [Z] := TRUNC ((1.2 - Messwert [Z]) * 400 + 240);
  674.           IF Y2 [Z] > 400 THEN Y2 [Z] := 398;
  675.           IF Y2 [Z] < 60 THEN Y2 [Z] := 60;
  676.          IF Ze [Z] = TRUE THEN LINE (X1, Y1 [Z], X2, Y2 [Z]);  { Linie ziehen }
  677.        END;
  678.  
  679.          INC (X1 , 3 - Zoom);                             { nächste Schreibposition }
  680.          INC (X2 , 3 - Zoom);
  681.  
  682.       UNTIL (EOF (Mess_Daten)) OR (X1 > 590);
  683.  
  684. PLOT_ENDE:
  685.  
  686.     OK := TRUE;
  687.  
  688. END;
  689.  
  690. { ┌────────────────────────────────────────────────────────────────────────┐
  691.   │    GRAPHISCHE AUSWERTUNG DES LADEVORGANGES                             │
  692.   │    EINGABEN : LADEPLATZ-NUMMER                                         │
  693.   │    AUSGABE  : LADEKURVE IN EIN KOORDINATENSYSTEM SCHREIBEN             │
  694.   └────────────────────────────────────────────────────────────────────────┘ }
  695. PROCEDURE Auswertung;
  696.  
  697. LABEL ENDE;
  698.  
  699. VAR
  700.       Puffer      : STRING;                        { Zeichenpuffer }
  701.       jahrstr     : STRING [4];
  702.       GraphDriver : INTEGER;                       { Grafik-Treiber }
  703.       GraphMode   : INTEGER;                       { Grafik-Modus }
  704.       Err         : INTEGER;                       { Grafik-Fehlerspeicher }
  705.       X1, Y1      : WORD;                          { Zeichenkoordinaten }
  706.       W           : REAL;                          { REAL-Messwert }
  707.       Zeiger      : LONGINT;                       { Dateizeiger }
  708.       Offs        : LONGINT;                       { Dateizeiger Offset }
  709.       Antw        : CHAR;                          { Tastaturabfrage }
  710.       OK          : BOOLEAN;                       { IO-Result Variable }
  711.       Clr         : BOOLEAN;                       { Löschmodus }
  712.       Anf_std     : WORD;                          { Zeitbeschriftung der X-Achse, Stunden }
  713.       Anf_min     : WORD;                          { Minuten }
  714.       X_POS       : WORD;                          { Mauscursorposition X-Achse }
  715.       Spng        : REAL;                          { Spannung am Punkt des Mauscursors }
  716.       Spng_Str    : STRING [8];                    { Spannung Ausgabestring }
  717.       Y_POS       : WORD;                          { Mauscursorposition Y-Achse }
  718.       Y_POS_Real  : REAL;                          { Position Y als Real-Typ }
  719.       Zeit        : WORD;                          { Zeit in Min. am Pukt des Mausc. }
  720.       Zeit_Str    : STRING [9];                    { Zeit Ausgabestring }
  721.  
  722. BEGIN
  723.   Mausein (0);
  724.   GraphDriver := DETECT;                           { Grafiktreiber suchen }
  725.    INITGRAPH (GraphDriver, GraphMode, Grfk_Pfad);  { Treiber initialisieren }
  726.     Err := GRAPHRESULT;                            { Status holen }
  727.     IF Err <> 0 THEN                               { Wenn initialisierung fehlerhaft }
  728.       BEGIN                                        { dann Fehlermeldung }
  729.        Fehler_fenster;
  730.         GOTOXY (3, 3);
  731.         WRITE ('SYSTEMFEHLER:');
  732.         GOTOXY (3, 4);
  733.         WRITE (GraphErrorMsg (Err));
  734.         GOTOXY (3, 6);
  735.         WRITE ('Zurück zum Hauptmenü mit Tastendruck. >');
  736.          REPEAT UNTIL KEYPRESSED;
  737.           Antw := READKEY;
  738.           Antw := ' ';
  739.          EXIT;
  740.        END;
  741.  
  742.    SETACTIVEPAGE (0);                              { aktive Schreibseite }
  743.    SETVISUALPAGE (0);                              { aktive Leseseite }
  744.    SETBKCOLOR (0);                                 { Hintergrundfarbe }
  745.    CLEARVIEWPORT;                                  { Bildschirm löschen }
  746.    SETCOLOR (14);                                  { Schreibfarbe gelb }
  747.  
  748.    SETLINESTYLE (SOLIDLN, 0, 4);                   { Rahmen }
  749.    SETCOLOR (15);
  750.    LINE (1, 1, 636, 1);
  751.    LINE (636, 1, 636, 455);
  752.    LINE (636, 455, 1, 455);
  753.    LINE (1, 455, 1, 1);
  754.  
  755.    Zeiger := 0;                                    { Dateizeiger }
  756.  
  757.      REPEAT
  758.       SEEK (Mess_Daten, Zeiger);                   { Dateizeiger an den Anfang }
  759.       IF EOF (Mess_Daten) THEN                     { wenn Dateiende dann }
  760.        BEGIN                                       { ist Datei leer }
  761.         CLOSEGRAPH;
  762.         Fehler_Fenster;
  763.         GOTOXY (3, 3);
  764.         WRITE ('GRAPHIKAUSWERTUNG:');
  765.         GOTOXY (3, 4);
  766.         WRITE ('Datei ist leer !');
  767.         GOTOXY (3, 6);
  768.         WRITE ('Zurück zum Hauptmenü mit Tastendruck. >');
  769.  
  770.          REPEAT UNTIL KEYPRESSED;
  771.          Antw := READKEY;
  772.          Antw := ' ';
  773.         EXIT;
  774.        END;
  775.  
  776.       READ (Mess_Daten, Messwert);                 { Dateinende suchen }
  777.       INC (Zeiger, 1);                             { Zeiger zeigt auf letzten Eintrag }
  778.      UNTIL EOF (Mess_Daten);
  779.  
  780.    RESET (Mess_Daten);                             { Datum des Ladevorganges }
  781.    READ (Mess_Daten, Messwert);
  782.    wtag := TRUNC (Messwert [1]);
  783.    tag := TRUNC (Messwert [2]);
  784.    mon := TRUNC (Messwert [3]);
  785.    jahr := TRUNC (Messwert [4]);
  786.  
  787.    STR (jahr, jahrstr);
  788.  
  789.    READ (Mess_Daten, Messwert);                    { Beginn der Ladung um: }
  790.    std := TRUNC (Messwert [1]);
  791.    Anf_std := std;
  792.    min := TRUNC (Messwert [2]);
  793.    Anf_min := min;
  794.    sek := TRUNC (Messwert [3]);
  795.    s100 := TRUNC (Messwert [4]);
  796.  
  797.    Puffer := ' Datum ' + TFormat (tag) + '.' + TFormat (mon) + '.' + jahrstr + ', Start: '+
  798.               TFormat (std) + ':' + TFormat (min) + ':' + TFormat (sek) + ' Uhr.';
  799.  
  800.    SETCOLOR (12);
  801.    OUTTEXTXY (1, 10, ' Graphische Auswertung des Ladevorganges von:');
  802.    SETCOLOR (7);
  803.    OUTTEXTXY (1, 25, Puffer);
  804.  
  805.    SETLINESTYLE (SOLIDLN, 0, 4);                   { Textausgaben }
  806.    SETCOLOR (10);
  807.    LINE (380, 14, 390, 14);
  808.    Puffer := 'Kanal 1';
  809.    OUTTEXTXY (395, 10, Puffer);
  810.    SETCOLOR (13);
  811.    LINE (380, 24, 390, 24);
  812.    Puffer := 'Kanal 2';
  813.    OUTTEXTXY (395, 20, Puffer);
  814.    SETCOLOR (7);
  815.    LINE (500, 14, 510, 14);
  816.    Puffer := 'Kanal 3';
  817.    OUTTEXTXY (515, 10, Puffer);
  818.    SETCOLOR (1);
  819.    LINE (500, 24, 510, 24);
  820.    Puffer := 'Kanal 4';
  821.    OUTTEXTXY (515, 20, Puffer);
  822.  
  823.    Puffer := '';
  824.    SEEK (Mess_Daten, Zeiger - 1);                  { Ende der Ladezeit ermitteln }
  825.    READ (Mess_Daten, Messwert);
  826.    std := TRUNC (Messwert [1]);
  827.    min := TRUNC (Messwert [2]);
  828.    sek := TRUNC (Messwert [3]);
  829.    s100 := TRUNC (Messwert [4]);
  830.    Puffer := '                   Ende : '+ TFormat (std) + ':' + TFormat (min) + ':' + TFormat (sek) + ' Uhr.';
  831.    SETCOLOR (7);
  832.    OUTTEXTXY (1, 35, Puffer);
  833.  
  834.    Puffer := ' MESSWERTDATEI: '+ Mess_Datei;
  835.    OUTTEXTXY (1,430, Puffer);
  836.    SETCOLOR (15);
  837.    SETLINESTYLE (SOLIDLN, 0, 2);                   { Koordinatensystem zeichnen }
  838.    LINE (50, 60, 50, 400);
  839.    LINE (50, 400, 600, 400);
  840.    LINE (50, 60, 48, 68);
  841.    LINE (50, 60, 52, 68);
  842.    LINE (600, 400, 592, 398);
  843.    LINE (600, 400, 592, 402);
  844.  
  845.    Y1 := 380;                                      { Skalierung Y-Achse }
  846.      REPEAT
  847.        LINE (45, Y1, 50, Y1);
  848.        DEC (Y1, 20);
  849.      UNTIL Y1 < 80;
  850.  
  851.    X1 := 50;                                       { Skalierung X-Achse }
  852.      REPEAT
  853.        LINE (X1, 400, X1, 405);
  854.        INC (X1, 20);
  855.      UNTIL X1 > 580;
  856.  
  857.    OUTTEXTXY (8, 45, 'Volt/Zelle');                { Beschriftungen }
  858.    OUTTEXTXY (8, 55, 'U (V)');
  859.    OUTTEXTXY (610, 408, 't');
  860.    OUTTEXTXY (500, 50, '+/- SCHIEBEN');
  861.    SETCOLOR (10);
  862.    OUTTEXTXY (1, 440, ' NI-CD-Akkulader V 2.0  (c) Carsten Stelling 1994');
  863.    SETCOLOR (15);
  864.  
  865.    IF Zoom = 1 THEN OUTTEXTXY (500, 430, '1TE = 10min.');
  866.    IF Zoom = 2 THEN OUTTEXTXY (500, 430, '1TE = 20min.');
  867.  
  868.  
  869.    OUTTEXTXY (10, 75, '1,60');                     { Beschriftung Y-Achse }
  870.    OUTTEXTXY (10, 95, '1,55');
  871.    OUTTEXTXY (10, 115, '1,50');
  872.    OUTTEXTXY (10, 135, '1,45');
  873.    OUTTEXTXY (10, 155, '1,40');
  874.    OUTTEXTXY (10, 175, '1,35');
  875.    OUTTEXTXY (10, 195, '1,30');
  876.    OUTTEXTXY (10, 215, '1,25');
  877.    OUTTEXTXY (10, 235, '1,20');
  878.    OUTTEXTXY (10, 255, '1,15');
  879.    OUTTEXTXY (10, 275, '1,10');
  880.    OUTTEXTXY (10, 295, '1,05');
  881.    OUTTEXTXY (10, 315, '1.00');
  882.    OUTTEXTXY (10, 335, '0,95');
  883.    OUTTEXTXY (10, 355, '0,90');
  884.    OUTTEXTXY (10, 375, '0,85');
  885.    OUTTEXTXY (10, 395, '0,80');
  886.  
  887.    SETCOLOR (4);
  888.    OUTTEXTXY (600, 236, '1,2V');
  889.  
  890.    Offs := 0;                                      { Initialisierung }
  891.    Clr := FALSE;
  892.  
  893.    Mausbereich (50, 55, 590, 400);                 { Mausbewegungsbereich im Grafikmodus }
  894.  
  895.    REPEAT;                                         { Schleife }
  896.     Gitternetz;                                    { Gitternetz zeichnen }
  897.     Plotten (Offs, Clr, Anf_std, Anf_min);         { Lade-/Entladekurven plotten }
  898.     Mausein (1);                                   { Grafik-Mauscursor einschalten }
  899.  
  900.      REPEAT;
  901.       Mausstatus;                                  { Mausstatus holen }
  902.        IF Maust = 2 THEN GOTO ENDE;                { linke Maustaste = Ende }
  903.  
  904.       IF Mausx <> X_POS THEN                       { Wurde X-Pos. seit letztem Aufruf verändert? }
  905.        BEGIN                                       { wenn ja, dann aktualisieren. }
  906.         SETCOLOR (0);                              { Farbe schwarz auf schwarz }
  907.         OUTTEXTXY (200, 60, '███████████');        { alten Wert löschen }
  908.         X_POS := Mausx;                            { X-Pos. aktualisieren }
  909.  
  910.         IF Zoom = 1 THEN Zeit := TRUNC ((X_POS - 42) / 2 + Offs - 4);
  911.         IF Zoom = 2 THEN Zeit := TRUNC (((X_POS - 46) * Zoom) / 2 + Offs - 4) ; { Zeit in min. berechnen }
  912.  
  913.         STR (Zeit, Zeit_Str);                      { Umwandeln in Stringformat }
  914.         Zeit_Str := Zeit_Str + ' min.';            { String erweitern }
  915.         SETCOLOR (9);                              { Farbe hellblau }
  916.         OUTTEXTXY (200, 60, Zeit_Str);             { Textausgabe }
  917.        END;
  918.  
  919.       IF Mausy <> Y_POS THEN                       { Wurde Y-Pos. seit letztem Aufruf verändert? }
  920.        BEGIN                                       { wenn ja, dann aktualisieren. }
  921.         SETCOLOR (0);                              { Farbe schwarz auf schwarz }
  922.         OUTTEXTXY (320, 60, '███████████');        { alten Wert löschen }
  923.         Y_POS := Mausy;                            { Y-Pos. aktualisieren }
  924.         Y_POS_Real := Mausy;                       { Word-Typ in Real-Typ wandeln }
  925.         Spng := 1.2 - ((Y_POS_Real - 240) / 400);  { Spannungswert berechnen }
  926.         STR (Spng:6:3, Spng_Str);                  { Umwandeln in Stringformat }
  927.         Spng_Str := Spng_Str + ' V.';              { String erweitern }
  928.         SETCOLOR (15);                             { Farbe weiß }
  929.         OUTTEXTXY (320, 60, Spng_Str);             { Textausgabe }
  930.        END;
  931.      UNTIL KEYPRESSED;                             { Ende wenn Taste gedrückt }
  932.  
  933.     Antw := READKEY;                               { Tastaturabfrage }
  934.      INC (X_POS, 1);                               { bewirkt Aktualisierung der Zeit nach Tastendruck }
  935.      INC (Y_POS, 1);                               { bewirkt Aktualisierung der Spannung }
  936.  
  937.      CASE Antw OF                                  { Fallunterscheidung }
  938.       '+' : BEGIN                                  { X-Achse nach links schieben }
  939.              Clr := TRUE;                          { Löschmodus aktiv }
  940.              Mausein (0);                          { Maus aus }
  941.              Plotten (Offs, Clr, Anf_std, Anf_min);{ Löschen }
  942.              Clr := FALSE;                         { Löschmodus inaktiv }
  943.              INC (Offs, 60 * (Zoom));          { Offset erhöhen = 1 Std.}
  944.             END;
  945.  
  946.       '-' : BEGIN                                  { X-Achse nach rechts schieben }
  947.              Clr := TRUE;
  948.              Mausein (0);
  949.              Plotten (Offs, Clr, Anf_std, Anf_min);
  950.              Clr := FALSE;
  951.              DEC (Offs, 60 * (Zoom));
  952.             END;
  953.      END;
  954.     IF Offs < 0 THEN Offs := 0;
  955.    UNTIL Antw = #27;                               { Wenn ESC gedrückt }
  956.  
  957. ENDE:
  958.    CLOSE (Mess_Daten);                             { Messdaten-Datei schließen }
  959.  
  960.   CLOSEGRAPH;                                      { Grafiktreiber deaktivieren }
  961.                                                    { Textmodus wiederherstellen }
  962. END;
  963.  
  964. { ┌────────────────────────────────────────────────────────────────────────┐
  965.   │    MESSDATEN-DATEINAMEN EINGEBEN                                       │
  966.   │    EINGABEN : VOLLSTÄNDIGER DATEINAME                                  │
  967.   │    AUSGABE  : GEÖFFNETE DATEI                                          │
  968.   └────────────────────────────────────────────────────────────────────────┘ }
  969. PROCEDURE Messdaten_Dateiname;
  970.  
  971. VAR  OK   : BOOLEAN;
  972.      Antw : CHAR;
  973.      Alt  : STRING [30];                           { Alter Dateiname }
  974.  
  975. BEGIN
  976.   Alt := Mess_Datei;                               { Dateiname sichern }
  977.  
  978.   WINDOW (10, 10, 58, 16);                         { neues Fenster öffnen }
  979.   TEXTBACKGROUND (3);
  980.   TEXTCOLOR (15);
  981.    CLRSCR;
  982.     WRITELN ('╔═ Neuer Dateiname ════════════════════════════╗');
  983.     WRITELN ('║  >                                           ║');
  984.     WRITELN ('║                                              ║');
  985.     WRITELN ('║                                              ║');
  986.     WRITELN ('║                                              ║');
  987.     WRITELN ('║                                              ║');
  988.     WRITE ('╚══════════════════════════════════════════════╝');
  989.  
  990.       GOTOXY (5,2);
  991.       READLN (Mess_Datei);                         { neuen Dateinamen lesen }
  992.       IF Mess_Datei = '' THEN                      { bei Leereingabe wird alter }
  993.        BEGIN                                       { Dateiname wiederhergestellt und }
  994.         Mess_Datei := Alt;                         { Eingaberoutine beendet. }
  995.         EXIT;
  996.        END;
  997.  
  998.        ASSIGN (Mess_Daten, Mess_Datei);            { Datei mit neuem Namen definieren }
  999.  
  1000.       {$I-}
  1001.        RESET (Mess_Daten);                         { Datei versuchen zu öffnen }
  1002.       {$I+}
  1003.       OK := IORESULT=0;                            { IO-Result auswerten }
  1004.        IF NOT OK THEN
  1005.          BEGIN                                     { Öffnen war Fehlerhaft }
  1006.           GOTOXY (5, 4);
  1007.           WRITE ('DATEINAME NICHT GEFUNDEN.');
  1008.           GOTOXY (5, 5);
  1009.           WRITE ('SOLL DATEI NEU ERSTELLT WERDEN ? (J/N) >');
  1010.  
  1011.            REPEAT
  1012.             Antw := READKEY;
  1013.            UNTIL (UPCASE(Antw) = 'J') OR (UPCASE(Antw) = 'N');
  1014.  
  1015.           IF UPCASE(Antw) = 'J' THEN               { Datei neu generieren }
  1016.            BEGIN
  1017.             {$I-}
  1018.              REWRITE (Mess_Daten);
  1019.             {$I+}
  1020.              OK := IORESULT=0;                     { IO-Result auswerten }
  1021.               IF NOT OK THEN
  1022.                BEGIN                               { Schreibversuch mislang }
  1023.                 GOTOXY (5, 4);
  1024.                 WRITE ('                          ');
  1025.                 GOTOXY (5, 5);
  1026.                 TEXTBACKGROUND (12);
  1027.                 TEXTCOLOR (15);
  1028.                 WRITE ('  DATEI KANN NICHT BESCHRIEBEN WERDEN!  ');
  1029.                 Mess_Datei := Alt;
  1030.                 DELAY (2000);
  1031.                END;
  1032.             END;
  1033.           IF UPCASE(Antw) = 'N' THEN Mess_Datei := Alt;
  1034.         END;
  1035. END;
  1036.  
  1037. { ┌────────────────────────────────────────────────────────────────────────┐
  1038.   │    VOREINSTELLUNGEN                                                    │
  1039.   │    EINGABEN : PORTS, KAPAZITÄT, NENNSPANNUNG                           │
  1040.   │    AUSGABE  : ANLEGEN EINER DATENDATEI                                 │
  1041.   └────────────────────────────────────────────────────────────────────────┘ }
  1042. PROCEDURE Einstellungen;
  1043.  
  1044. LABEL START;                                       { Sprungmarke }
  1045.  
  1046. VAR Nr      : BYTE;                                { Variablendeklaration }
  1047.     Err     : INTEGER;                             { Fehlerspeicher }
  1048.     Groesse : LONGINT;                             { Groesse der Messwertdatei }
  1049.     Antw    : CHAR;                                { Antwort von Tastatur }
  1050.     Aktion  : CHAR;                                { Menüauswahl }
  1051.     OK      : BOOLEAN;                             { Ergebnis der Dateioperationen }
  1052.     OKmess  : BOOLEAN;                             { Messdatei IORESULT }
  1053.     Eingabe : Akku_str;                            { Eingabestring }
  1054.     Zeitstr : STRING [5];                          { Zoom-Anzeige }
  1055.     Drckstr : STRING [4];                          { Protokoll-Anzeige }
  1056.  
  1057. BEGIN START:
  1058.  
  1059.   Par := '';                                       { Initialisierung }
  1060.   Ser := '';
  1061.   OK := FALSE;
  1062.   OKmess := FALSE;
  1063.  
  1064.   Mausbereich (1, 1, (80-1) * 8, (25-1) * 8);      { Maus-Bewegungsbereich im Textmodus }
  1065.  
  1066.     ASSIGN (Akku_Port, Akku_Pdatei);               { Datei Akku_Port öffnen }
  1067.     ASSIGN (Akku_Dat, Akku_Datei);                 { Datei Akku_Dat öffnen }
  1068.  
  1069.    IF Zoom = 2 THEN Zeitstr := 'fein';
  1070.    IF Zoom = 1 THEN Zeitstr := 'grob';
  1071.  
  1072.    IF Drucken = TRUE THEN Drckstr := 'ein';
  1073.    IF Drucken = FALSE THEN Drckstr := 'aus';
  1074.  
  1075.    WINDOW (1, 1, 80, 25);                          { Fenster max. Größe }
  1076.      Mausein (0);
  1077.      TEXTBACKGROUND (0);                           { Hintergrundf. }
  1078.      CLRSCR;                                       { Bildschirm löschen }
  1079.      TEXTBACKGROUND (7);
  1080.      TEXTCOLOR (4);
  1081.      WRITELN ('    NI-CD-LADESTEUERUNG   -   VERSION 2.0          (c) Carsten Stelling 1994   ');
  1082.      TEXTBACKGROUND (1);
  1083.      TEXTCOLOR (15);
  1084.      WRITELN;
  1085.      WRITELN;
  1086.      WRITELN ('╔═ Auswahl ═════════════════════════════╗');
  1087.      WRITELN ('║  1 = Lade-/Entladekurven betrachten   ║');
  1088.      WRITELN ('║  2 = Zeitraster ', Zeitstr,'                  ║');
  1089.      WRITELN ('║  3 = Parametrierung (Datei erstellen) ║');
  1090.      WRITELN ('║  4 = Ladevorgang starten              ║');
  1091.      WRITELN ('║  5 = Messdaten Dateiname ändern       ║');
  1092.      WRITELN ('║  6 = A/D-WANDLER Testprogramm         ║');
  1093.      WRITELN ('║  7 = Protokoll ', Drckstr, '                    ║');
  1094.      WRITELN ('║  8 = Informationen                    ║');
  1095.      WRITELN ('║  9 = Programm ENDE                    ║');
  1096.      WRITELN ('╚═══════════════════════════════════════╝');
  1097.      TEXTBACKGROUND (0);
  1098.      TEXTCOLOR (12);
  1099.      WRITELN;
  1100.      WRITELN ('Wählen Sie eine Aktion indem Sie die entsprechende Ziffer betätigen');
  1101.      WRITELN ('oder die entsprechende Zeile mit dem  Mauscursor  ansteuern und die');
  1102.      WRITELN ('linke Maustaste drücken.');
  1103.      TEXTCOLOR (15);
  1104.      GOTOXY (1, 22);
  1105.       WRITE ('PROTOKOLL: ');
  1106.       IF Drucken = TRUE THEN WRITE ('Druck an LPT1')
  1107.        ELSE WRITE ('nicht drucken');
  1108.  
  1109.      ASSIGN (Mess_Daten, Mess_Datei);
  1110.      {$I-}
  1111.       RESET (Mess_Daten);
  1112.      {$I+}
  1113.      OKmess := IORESULT=0;
  1114.       IF NOT OKmess THEN
  1115.        BEGIN
  1116.         Fehler_Fenster;
  1117.          GOTOXY (4, 3);
  1118.          WRITELN ('Standard-Messwertdatei nicht vorhanden!');
  1119.          GOTOXY (4, 4);
  1120.          WRITELN ('Erzeuge leere Datei: MESS_1.NCL');
  1121.          REWRITE (Mess_Daten);
  1122.          DELAY (1500);
  1123.          GOTOXY (4, 6);
  1124.          WRITELN ('NEUSTART...');
  1125.          DELAY (1500);
  1126.         GOTO START;
  1127.        END;
  1128.  
  1129.      Groesse := FILESIZE (Mess_Daten);
  1130.      CLOSE (Mess_Daten);
  1131.  
  1132.      GOTOXY (1, 24);
  1133.       WRITE ('MESSWERTDATEI: ',Mess_Datei,' (',Groesse,' Datensätze)');
  1134.  
  1135.        Mausein (1);
  1136.        Mausein (1);
  1137.  
  1138.      REPEAT;
  1139.       Aktion := '0';
  1140.       IF KEYPRESSED THEN Aktion := READKEY;
  1141.       Mausstatus;
  1142.        Mausx := (Mausx + 8) DIV 8;
  1143.        Mausy := (Mausy + 8) DIV 8;
  1144.         IF (Mausx > 1) AND (Mausx < 41) AND (Maust = 1) THEN Aktion := CHR (44 + Mausy);
  1145.  
  1146.      UNTIL (ORD (Aktion) > 48) AND (ORD (Aktion) < 58);
  1147.  
  1148.      CASE Aktion OF
  1149.       '7': BEGIN
  1150.             Drucken := NOT Drucken;
  1151.  
  1152.              IF (Drucken = TRUE) AND (AdrLPT = AdrLPT1) THEN
  1153.               BEGIN
  1154.                Fehler_Fenster;
  1155.                GOTOXY (3, 2);
  1156.                WRITE ('Drucken an LPT1 und Steuerung der');
  1157.                GOTOXY (3, 3);
  1158.                WRITE ('Zusatzplatine an LPT 1 ist nicht möglich.');
  1159.                GOTOXY (3, 4);
  1160.                WRITE ('Protokollierung wird ausgeschaltet.');
  1161.                GOTOXY (3, 6);
  1162.                WRITE ('Zurück zum Hauptmenü mit Tastendruck. >');
  1163.  
  1164.                  REPEAT UNTIL KEYPRESSED;
  1165.                 Antw := READKEY;
  1166.                 Antw := ' ';
  1167.                Drucken := NOT Drucken;
  1168.               END;
  1169.  
  1170.             DELAY (500);
  1171.             GOTO START;
  1172.            END;
  1173.  
  1174.       '5': BEGIN
  1175.             Mausein (0);
  1176.             Messdaten_Dateiname;
  1177.             Mausein (1);
  1178.             GOTO START;
  1179.            END;
  1180.  
  1181. { ┌────────────────────────────────────────────────────────────────────────┐
  1182.   │    A/D-WANDLER TESTPROGRAMM                                            │
  1183.   │    EINGABEN : COM-PORT DES WANDLERS                                    │
  1184.   │    AUSGABE  : SPANNUNG DER 8 MESSKANÄLE                                │
  1185.   └────────────────────────────────────────────────────────────────────────┘ }
  1186.       '6': BEGIN
  1187.              Mausein (0);
  1188.              WINDOW (15, 8, 47, 19);
  1189.              TEXTBACKGROUND (2);
  1190.               TEXTCOLOR (15);
  1191.              CLRSCR;
  1192.               WRITELN ('╔═ A/D-Test ═══════════════════╗');
  1193.               WRITELN ('║                              ║');
  1194.               WRITELN ('║  A/D-Wandler an Port ?       ║');
  1195.               WRITELN ('║  >                           ║');
  1196.               WRITELN ('║                              ║');
  1197.               WRITELN ('║                              ║');
  1198.               WRITELN ('║                              ║');
  1199.               WRITELN ('║                              ║');
  1200.               WRITELN ('║                              ║');
  1201.               WRITELN ('║                              ║');
  1202.               WRITELN ('║                              ║');
  1203.               WRITE ('╚══════════════════════════════╝');
  1204.  
  1205.               REPEAT;
  1206.                GOTOXY (5, 4);
  1207.                 WRITELN ('              ');
  1208.                GOTOXY (5, 4);
  1209.                READLN (Eingabe);
  1210.               UNTIL (Eingabe = 'COM1') OR (Eingabe = 'com1') AND (AdrCOM1 <> 0)
  1211.                  OR (Eingabe = 'COM2') OR (Eingabe = 'com2') AND (AdrCOM2 <> 0)
  1212.                  OR (Eingabe = 'COM3') OR (Eingabe = 'com3') AND (AdrCOM3 <> 0)
  1213.                  OR (Eingabe = 'COM4') OR (Eingabe = 'com4') AND (AdrCOM4 <> 0);
  1214.  
  1215.                  IF (Eingabe = 'COM1') OR (Eingabe = 'com1') THEN Portadr := AdrCOM1;
  1216.                  IF (Eingabe = 'COM2') OR (Eingabe = 'com2') THEN Portadr := AdrCOM2;
  1217.                  IF (Eingabe = 'COM3') OR (Eingabe = 'com3') THEN Portadr := AdrCOM3;
  1218.                  IF (Eingabe = 'COM4') OR (Eingabe = 'com4') THEN Portadr := AdrCOM4;
  1219.  
  1220.                 Ser := Eingabe;
  1221.  
  1222.               CLRSCR;
  1223.               WRITELN ('╔═ A/D-Test ═══════════════════╗');
  1224.               WRITELN ('║   KANAL     SPANNUNG         ║');
  1225.               WRITELN ('║     1:                       ║');
  1226.               WRITELN ('║     2:                       ║');
  1227.               WRITELN ('║     3:                       ║');
  1228.               WRITELN ('║     4:                       ║');
  1229.               WRITELN ('║     5:                       ║');
  1230.               WRITELN ('║     6:                       ║');
  1231.               WRITELN ('║     7:                       ║');
  1232.               WRITELN ('║     8:                       ║');
  1233.               WRITELN ('║ ESC, RECHTE MAUSTASTE = ENDE ║');
  1234.               WRITE ('╚══════════════════════════════╝');
  1235.  
  1236.                Mausein (1);
  1237.                CursorAus;
  1238.  
  1239.                 REPEAT;
  1240.                  FOR Z := 1 TO 8 DO
  1241.                   BEGIN
  1242.                    GOTOXY (14, Z + 2);
  1243.                    WRITE (AD_Messwert (Z):6:3, ' Volt');
  1244.                    DELAY (2);
  1245.                   END;
  1246.                  Mausstatus;
  1247.                  IF KEYPRESSED THEN Antw := READKEY;
  1248.                 UNTIL (Antw = CHR (27)) OR (Maust = 2);
  1249.               Antw := '0';
  1250.              CursorEin;
  1251.             GOTO START;
  1252.            END;
  1253.  
  1254.       '8': BEGIN
  1255.             WINDOW (1, 1, 80, 25);                 { Fenster max. Größe }
  1256.             Mausein (0);
  1257.             TEXTBACKGROUND (0);                    { Hintergrundf. }
  1258.             CLRSCR;                                { Bildschirm löschen }
  1259.             TEXTBACKGROUND (7);
  1260.             TEXTCOLOR (4);
  1261.             WRITELN ('    NI-CD-LADESTEUERUNG   -   VERSION 2.0          (c) Carsten Stelling 1994    ',#10);
  1262.             TEXTBACKGROUND (0);
  1263.             TEXTCOLOR (3);
  1264.             WRITELN ('PROGRAMM-INFORMATION:', #10);
  1265.             TEXTCOLOR (7);
  1266.             WRITELN ('Version 2.0');
  1267.             WRITELN ('Letzte Änderung am 15.04.1994  15:37', #10);
  1268.             WRITELN ('Unterstützte Schnittstellen:', #10);
  1269.             WRITELN ('       LPT1 : Zusatzplatine oder Protokoll-Drucker');
  1270.             WRITELN ('       LPT2 : Zusatzplatine');
  1271.             WRITELN ('       LPT3 : Zusatzplatine');
  1272.             WRITELN ('COM1 - COM4 : A/D-WANDLER Fa. Conrad Best.Nr. 97 97 67', #10);
  1273.             TEXTCOLOR (2);
  1274.             WRITELN ('Es wird vorausgesetzt, daß nur 1.2 V-Zellen geladen  werden.');
  1275.             WRITELN ('Bei Verwendung von Akku-Packs sind  die  Spannungsteiler  so');
  1276.             WRITELN ('zu dimensionieren, daß die Eingangsspannung des A/D-Wandlers');
  1277.             WRITELN ('bei Akku-Nennspannung 1.2V beträgt.', #10, #10, #10, #10);
  1278.             TEXTCOLOR (14);
  1279.             WRITE ('mehr Information...');
  1280.             DELAY (500);
  1281.              Warten;
  1282.  
  1283.             WINDOW (1, 3, 80, 23);
  1284.             Mausein (0);
  1285.             CLRSCR;
  1286.             TEXTCOLOR (7);
  1287.             WRITELN ('BELEGUNG DES SERIELLEN ANSCHLUSSES (D-SUB 9/M):');
  1288.             WRITELN ('┌─────┬────────────┬─────────────────────────────┐');
  1289.             WRITELN ('│ PIN │ SIGNALNAME │ BENENNUNG / FUNKTION        │');
  1290.             WRITELN ('├─────┼────────────┼─────────────────────────────┤');
  1291.             WRITELN ('│  4  │ DTR        │ Data Terminal Ready / SCLK  │');
  1292.             WRITELN ('│  5  │ GND        │ Ground / Bezugspotential    │');
  1293.             WRITELN ('│  7  │ RTS        │ Ready to Send / Daten Eing. │');
  1294.             WRITELN ('│  8  │ CTS        │ Clear to Send / Daten Ausg. │');
  1295.             WRITELN ('└─────┴────────────┴─────────────────────────────┘', #10);
  1296.  
  1297.             WRITELN ('BELEGUNG DES SERIELLEN ANSCHLUSSES (D-SUB 25/M):');
  1298.             WRITELN ('┌─────┬────────────┬─────────────────────────────┐');
  1299.             WRITELN ('│ PIN │ SIGNALNAME │ BENENNUNG / FUNKTION        │');
  1300.             WRITELN ('├─────┼────────────┼─────────────────────────────┤');
  1301.             WRITELN ('│  20 │ DTR        │ Data Terminal Ready / SCLK  │');
  1302.             WRITELN ('│   7 │ GND        │ Ground / Bezugspotential    │');
  1303.             WRITELN ('│   4 │ RTS        │ Ready to Send / Daten Eing. │');
  1304.             WRITELN ('│   5 │ CTS        │ Clear to Send / Daten Ausg. │');
  1305.             WRITELN ('└─────┴────────────┴─────────────────────────────┘');
  1306.             DELAY (500);
  1307.              Warten;
  1308.  
  1309.             WINDOW (1, 3, 80, 23);
  1310.             Mausein (0);
  1311.             CLRSCR;
  1312.             TEXTCOLOR (7);
  1313.             WRITELN ('BELEGUNG DES PARALLELEN ANSCHLUSSES (D-SUB 25/F):');
  1314.             WRITELN ('┌─────┬────────────┬─────────────────────────────┐');
  1315.             WRITELN ('│ PIN │ SIGNALNAME │ BENENNUNG / FUNKTION        │');
  1316.             WRITELN ('├─────┼────────────┼─────────────────────────────┤');
  1317.             WRITELN ('│   2 │   DATA 0   │ Akku 1 - Ladetransistor     │');
  1318.             WRITELN ('│   3 │   DATA 1   │ Akku 1 - Entlade-MOSFET     │');
  1319.             WRITELN ('│   4 │   DATA 2   │ Akku 2 - Ladetransistor     │');
  1320.             WRITELN ('│   5 │   DATA 3   │ Akku 2 - Entlade-MOSFET     │');
  1321.             WRITELN ('│   6 │   DATA 4   │ Akku 3 - Ladetransistor     │');
  1322.             WRITELN ('│   7 │   DATA 5   │ Akku 3 - Entlade-MOSFET     │');
  1323.             WRITELN ('│   8 │   DATA 6   │ Akku 4 - Ladetransistor     │');
  1324.             WRITELN ('│   9 │   DATA 7   │ Akku 4 - Entlade-MOSFET     │');
  1325.             WRITELN ('│  18 │   GND      │ Ground / Bezugspotential    │');
  1326.             WRITELN ('│  25 │   GND      │ Ground / Bezugspotential    │');
  1327.             WRITELN ('└─────┴────────────┴─────────────────────────────┘');
  1328.             DELAY (500);
  1329.              Warten;
  1330.  
  1331.             WINDOW (1, 3, 80, 25);
  1332.             Mausein (0);
  1333.             CLRSCR;
  1334.             TEXTCOLOR (7);
  1335.             WRITELN ('BERECHNUNGSFORMELN FÜR SPANNUNGSTEILER:',#10);
  1336.             WRITELN ('     AKKU + ──────┬────────── ');
  1337.             WRITELN ('                  │     │  │');
  1338.             WRITELN ('                 ┌┴┐    │  │                R2 * Ua');
  1339.             WRITELN ('              R1 │ │  U1│  │          R1 = ───────── - R2');
  1340.             WRITELN ('                 └┬┘    │  │                  1.2V');
  1341.             WRITELN ('                  │     V  │');
  1342.             WRITELN ('                  ├──────  │Ua');
  1343.             WRITELN ('                  │     │  │');
  1344.             WRITELN ('                 ┌┴┐    │  │                R1 * 1.2V');
  1345.             WRITELN ('              R2 │ │  U2│  │          R2 = ───────────');
  1346.             WRITELN ('                 └┬┘    │  │                Ua - 1.2V');
  1347.             WRITELN ('                  │     V  V');
  1348.             WRITELN ('     AKKU - ──────┴──────────');
  1349.             TEXTCOLOR (15);
  1350.             WRITELN ('                                     R2 sollte im Bereich von 1 kΩ');
  1351.             WRITELN ('                                     bis 10 kΩ gewählt werden.',#10);
  1352.             WRITELN ('Beispiel: Ua = 4.8 V, R2 gewählt 1 kΩ, R1 berechnet 3 kΩ');
  1353.             TEXTCOLOR (2);
  1354.             WRITELN ('(niederohmige Spannungsteiler vermindern Störungen)', #10);
  1355.             TEXTCOLOR (14);
  1356.             WRITELN ('Info Ende.');
  1357.             DELAY (500);
  1358.              Warten;
  1359.  
  1360.             GOTO START;
  1361.            END;
  1362.  
  1363.       '9': BEGIN
  1364.             Mausein (0);
  1365.             WINDOW (1, 1, 80, 25);
  1366.             CLRSCR;
  1367.             WRITELN;
  1368.             TEXTCOLOR(7);
  1369.             WRITELN ('NI-CD-Ladeprogramm beendet.');
  1370.              HALT;
  1371.            END;
  1372.  
  1373.       '1': BEGIN
  1374.             ASSIGN (Mess_Daten, Mess_Datei);
  1375.             {$I-}
  1376.              RESET (Mess_Daten);
  1377.             {$I+}
  1378.             OKmess := IORESULT=0;
  1379.              IF NOT OKmess THEN
  1380.               BEGIN
  1381.                TEXTCOLOR (31);
  1382.                GOTOXY (1, 24);
  1383.                WRITE ('DATEI ',Mess_Datei,' NICHT VORHANDEN !');
  1384.                DELAY (3000);
  1385.                 GOTO START;
  1386.             END;
  1387.  
  1388.             Auswertung; GOTO START; END;
  1389.  
  1390.       '2' : BEGIN
  1391.              IF Zoom = 1 THEN Zoom := 2 ELSE
  1392.              IF Zoom = 2 THEN Zoom := 1;
  1393.              DELAY (500);
  1394.              GOTO START;
  1395.             END;
  1396.  
  1397.       '3' : BEGIN
  1398.              REWRITE (Akku_Port);
  1399.              REWRITE (Akku_Dat);
  1400.              OK := FALSE;
  1401.             END;
  1402.  
  1403.       '4' : BEGIN
  1404.              {$I-}
  1405.               RESET (Akku_Port);
  1406.               RESET (Akku_Dat);
  1407.              {$I+}
  1408.              OK := IORESULT=0;
  1409.               IF NOT OK THEN
  1410.                BEGIN
  1411.                 REWRITE (Akku_Port);
  1412.                 REWRITE (Akku_Dat);
  1413.                END;  { END von '3': BEGIN }
  1414.            END;  { END von IF }
  1415.      END;  { END von CASE }
  1416.  
  1417.  
  1418.   REPEAT;
  1419.    Mausein (0);
  1420.    WINDOW (1, 1, 80, 25);                          { Eingabefenster }
  1421.      TEXTBACKGROUND (0);                           { für Akkuparameter }
  1422.      CLRSCR;
  1423.      TEXTBACKGROUND (7);
  1424.      TEXTCOLOR (4);
  1425.      WRITELN ('    NI-CD-LADESTEUERUNG   -   VERSION 2.0          (c) Carsten Stelling 1994   ');
  1426.      TEXTBACKGROUND (0);
  1427.      TEXTCOLOR (14);
  1428.      WRITELN ('═════════════════════════════ GRUNDEINSTELLUNGEN ══════════════════════════════');
  1429.      TEXTBACKGROUND (3);
  1430.      TEXTCOLOR (15);
  1431.      WRITELN ('╔═ I/O ═╤═ Adr.═╗');
  1432.       IF AdrLPT1 <> 0 THEN WRITELN ('║ LPT1: │ ',HexZahl (AdrLPT1, 3),'  ║');
  1433.       IF AdrLPT2 <> 0 THEN WRITELN ('║ LPT2: │ ',HexZahl (AdrLPT2, 3),'  ║');
  1434.       IF AdrCOM1 <> 0 THEN WRITELN ('║ COM1: │ ',HexZahl (AdrCOM1, 3),'  ║');
  1435.       IF AdrCOM2 <> 0 THEN WRITELN ('║ COM2: │ ',HexZahl (AdrCOM2, 3),'  ║');
  1436.       IF AdrCOM3 <> 0 THEN WRITELN ('║ COM3: │ ',HexZahl (AdrCOM3, 3),'  ║');
  1437.       IF AdrCOM4 <> 0 THEN WRITELN ('║ COM4: │ ',HexZahl (AdrCOM4, 3),'  ║');
  1438.      WRITELN ('╚═══════╧═══════╝');
  1439.  
  1440.      TEXTBACKGROUND (0);
  1441.        REPEAT;                                     { Welche Schnittstelle ? }
  1442.          GOTOXY (1, 14);
  1443.          WRITE ('Auswertung der A/D-Wandlersignale von Port: ');
  1444.          CLREOL;
  1445.          IF NOT OK THEN READLN (Eingabe) ELSE
  1446.            BEGIN
  1447.              READ (Akku_Port, Eingabe);
  1448.              WRITE (Eingabe);
  1449.            END;
  1450.        UNTIL (Eingabe = 'COM1') OR (Eingabe = 'com1') AND (AdrCOM1 <> 0)
  1451.      OR (Eingabe = 'COM2') OR (Eingabe = 'com2') AND (AdrCOM2 <> 0)
  1452.      OR (Eingabe = 'COM3') OR (Eingabe = 'com3') AND (AdrCOM3 <> 0)
  1453.      OR (Eingabe = 'COM4') OR (Eingabe = 'com4') AND (AdrCOM4 <> 0);
  1454.  
  1455.       IF (Eingabe = 'COM1') OR (Eingabe = 'com1') THEN Portadr := AdrCOM1;
  1456.       IF (Eingabe = 'COM2') OR (Eingabe = 'com2') THEN Portadr := AdrCOM2;
  1457.       IF (Eingabe = 'COM3') OR (Eingabe = 'com3') THEN Portadr := AdrCOM3;
  1458.       IF (Eingabe = 'COM4') OR (Eingabe = 'com4') THEN Portadr := AdrCOM4;
  1459.      Ser := Eingabe;
  1460.  
  1461.      TEXTCOLOR (7);
  1462.        REPEAT;                                     { Welche Schnittstelle ? }
  1463.          GOTOXY (1, 15);
  1464.          WRITE ('Ansteuerung der Zusatzplatine mit Port....: ');
  1465.          CLREOL;
  1466.           IF NOT OK THEN READLN (Eingabe) ELSE
  1467.             BEGIN
  1468.               READ (Akku_Port, Eingabe);
  1469.               WRITE (Eingabe);
  1470.             END;
  1471.        UNTIL (Eingabe = 'LPT1') OR (Eingabe = 'lpt1')
  1472.      OR (Eingabe = 'LPT2') OR (Eingabe = 'lpt2');
  1473.  
  1474.       IF (Eingabe = 'LPT1') OR (Eingabe = 'lpt1') AND (AdrLPT1 <> 0) THEN AdrLPT := AdrLPT1;
  1475.       IF (Eingabe = 'LPT2') OR (Eingabe = 'lpt2') AND (AdrLPT2 <> 0) THEN AdrLPT := AdrLPT2;
  1476.       IF (Eingabe = 'LPT3') OR (Eingabe = 'lpt3') AND (AdrLPT3 <> 0) THEN AdrLPT := AdrLPT3;
  1477.  
  1478.      Par := Eingabe;
  1479.      IF NOT OK THEN
  1480.        BEGIN
  1481.          WRITE (Akku_Port, Ser);                   { Benutzte Schnittstellen speichern }
  1482.          WRITE (Akku_Port, Par);
  1483.        END;
  1484.  
  1485.      TEXTBACKGROUND (1);
  1486.      TEXTCOLOR (11);
  1487.      GOTOXY (20, 5);
  1488.      WRITE ('╔═ Akku ══╤═ Kapaz.══╤═ Spng.══╤═ Algorithmus ════════╗');
  1489.      GOTOXY (20, 6);
  1490.      WRITE ('║ AKKU 1: │          │         │                      ║');
  1491.      GOTOXY (20, 7);
  1492.      WRITE ('║ AKKU 2: │          │         │                      ║');
  1493.      GOTOXY (20, 8);
  1494.      WRITE ('║ AKKU 3: │          │         │                      ║');
  1495.      GOTOXY (20, 9);
  1496.      WRITE ('║ AKKU 4: │          │         │                      ║');
  1497.      GOTOXY (20, 10);
  1498.      WRITE ('╚═════════╧══════════╧═════════╧══════════════════════╝');
  1499.      GOTOXY (20, 11);
  1500.      TEXTBACKGROUND (0);
  1501.      WRITE ('0 = nicht angeschlossen');
  1502.        FOR Nr := 1 TO 4 DO
  1503.          BEGIN
  1504.            REPEAT;
  1505.              GOTOXY (1, 16 + Nr);
  1506.              CLREOL;
  1507.              TEXTBACKGROUND (0);
  1508.              WRITE ('KAPAZITÄT AKKU ',Nr,' (mAh) ?: ');
  1509.              CLREOL;
  1510.               IF NOT OK THEN
  1511.                 BEGIN
  1512.                   READLN (Eingabe);
  1513.                   WRITE (Akku_Dat, Eingabe);
  1514.                 END
  1515.                ELSE BEGIN
  1516.                      READ (Akku_Dat, Eingabe);
  1517.                      WRITE (Eingabe);
  1518.                     END;
  1519.              VAL (Eingabe, Akku [Nr].Kap, Err);
  1520.            UNTIL (Err = 0) AND (Akku [Nr].Kap >=0) AND (Akku [Nr].Kap <=5000);
  1521.           GOTOXY (31, Nr+5);
  1522.           TEXTBACKGROUND (1);
  1523.           WRITE (Akku [Nr].Kap :5:0,' mAh');
  1524.         END;
  1525.  
  1526.        FOR Nr := 1 TO 4 DO
  1527.          BEGIN
  1528.           IF Akku [Nr].Kap > 0 THEN
  1529.             BEGIN
  1530.               REPEAT;
  1531.                 GOTOXY (34, 16 + Nr);
  1532.                 CLREOL;
  1533.                 TEXTBACKGROUND (0);
  1534.                 WRITE ('NENNSPANNUNG (V) ?: ');
  1535.                 CLREOL;
  1536.                  IF NOT OK THEN
  1537.                   BEGIN
  1538.                     READLN (Eingabe);
  1539.                     WRITE (Akku_dat, Eingabe);
  1540.                   END
  1541.                   ELSE BEGIN
  1542.                         READ (Akku_Dat, Eingabe);
  1543.                         WRITE (Eingabe);
  1544.                        END;
  1545.                 VAL (Eingabe, Akku [Nr].Spg, Err);
  1546.               UNTIL (Err = 0) AND (Akku [Nr].Spg >=0) AND (Akku [Nr].Spg <=20);
  1547.             GOTOXY (43, Nr+5);
  1548.             TEXTBACKGROUND (1);
  1549.             WRITE (Akku [Nr].Spg :5:1,' V');
  1550.           END
  1551.           ELSE
  1552.            BEGIN
  1553.             Eingabe := '0';
  1554.             VAL (Eingabe, Akku [Nr].Spg, Err);
  1555.             WRITE (Akku_dat, Eingabe);
  1556.            END;
  1557.         END;
  1558.  
  1559.        GOTOXY (1, 22);
  1560.        WRITE ('    ALGORITHMUS  (1 = NUR LADEN, 2 = VORHER ENTLADEN, 3 = REGENERIEREN)        ');
  1561.        FOR Nr := 1 TO 4 DO
  1562.          BEGIN
  1563.           IF Akku [Nr].Kap > 0 THEN
  1564.             BEGIN
  1565.               REPEAT;
  1566.                 GOTOXY (63, 16 + Nr);
  1567.                 CLREOL;
  1568.                 TEXTBACKGROUND (0);
  1569.                 WRITE ('ALGORITHMUS ?: ');
  1570.                 CLREOL;
  1571.                  IF NOT OK THEN
  1572.                   BEGIN
  1573.                     READLN (Eingabe);
  1574.                     WRITE (Akku_dat, Eingabe);
  1575.                   END
  1576.                   ELSE BEGIN
  1577.                         READ (Akku_Dat, Eingabe);
  1578.                         WRITE (Eingabe);
  1579.                        END;
  1580.                 VAL (Eingabe, Akku [Nr].Algor, Err);
  1581.               UNTIL (Err = 0) AND (Akku [Nr].Algor > 0) AND (Akku [Nr].Algor < 4);
  1582.             GOTOXY (56, Nr+5);
  1583.             TEXTBACKGROUND (1);
  1584.              CASE Akku [Nr].Algor OF
  1585.                1 : WRITE ('NUR LADEN');
  1586.                2 : WRITE ('VORHER ENTLADEN');
  1587.                3 : WRITE ('REGENERIEREN');
  1588.              END;
  1589.           END
  1590.           ELSE
  1591.            BEGIN
  1592.             Eingabe := '0';
  1593.             VAL (Eingabe, Akku [Nr].Algor, Err);
  1594.             WRITE (Akku_dat, Eingabe);
  1595.            END;
  1596.         END;
  1597.  
  1598.      TEXTBACKGROUND (4);
  1599.      TEXTCOLOR (15);
  1600.      GOTOXY (1 , 23);
  1601.      WRITE ('    SIND ALLE EINGABEN RICHTIG (J/N) ?                                         ');
  1602.      Antw := READKEY;
  1603.  
  1604.       IF Antw = #27 THEN
  1605.        BEGIN
  1606.         Antw := ' ';
  1607.         CLOSE (Akku_Port);
  1608.         CLOSE (Akku_Dat);
  1609.         GOTO START;
  1610.        END;
  1611.  
  1612.       IF UPCASE (Antw) <> 'J' THEN BEGIN
  1613.                                      REWRITE (Akku_Dat);
  1614.                                      REWRITE (Akku_Port);
  1615.                                     OK := FALSE;
  1616.                                    END;
  1617.    UNTIL UPCASE (Antw) = 'J';
  1618.  
  1619.    CLOSE (Akku_Port);
  1620.    CLOSE (Akku_Dat);
  1621.    IF Aktion = '3' THEN GOTO START;
  1622.  
  1623.      IF (Drucken = TRUE) AND (AdrLPT = AdrLPT1) THEN
  1624.       BEGIN
  1625.        Fehler_Fenster;
  1626.        GOTOXY (3, 2);
  1627.        WRITE ('Drucken an LPT1 und Steuerung der');
  1628.        GOTOXY (3, 3);
  1629.        WRITE ('Zusatzplatine an LPT 1 ist nicht möglich.');
  1630.        GOTOXY (3, 4);
  1631.        WRITE ('Protokollierung wird ausgeschaltet.');
  1632.        GOTOXY (3, 6);
  1633.        WRITE ('Zurück zum Hauptmenü mit Tastendruck. >');
  1634.          REPEAT UNTIL KEYPRESSED;
  1635.         Antw := READKEY;
  1636.         Antw := ' ';
  1637.        Drucken := NOT Drucken;
  1638.       GOTO START;
  1639.      END;
  1640.  
  1641.      FOR Nr := 1 TO 4 DO
  1642.        BEGIN
  1643.          WITH Akku [Nr] DO
  1644.            BEGIN
  1645.              Laden := FALSE;
  1646.              Entladen := FALSE;
  1647.              V_Summe  := 0.0;
  1648.              V_Mittel := 0.0;
  1649.              V_Vorher := 0.0;
  1650.            END;
  1651.        END;
  1652.  
  1653.    TEXTBACKGROUND (0);                             { Messdaten-Fenster }
  1654.    TEXTCOLOR (7);
  1655.    WINDOW (1, 2, 80, 25);
  1656.    CLRSCR;
  1657.    GOTOXY (1, 3);
  1658.    WRITELN ('╔═ Akku ═╤═ CH 0 ════════╤═ φ U ════════════╤═ Status ══╤═ Kap.══════════╗');
  1659.    WRITELN ('║ Nr: 1  │               │                  │           │                ║');
  1660.    WRITELN ('║        ├─ CH 1 ────────┼─ I max ──────────┼─ Zeit ────┼─ Alg.──────────╢');
  1661.    WRITELN ('║        │               │                  │           │                ║');
  1662.    WRITELN ('╠═ Akku ═╪═ CH 2 ════════╪═ φ U ════════════╪═ Status ══╪═ Kap.══════════╣');
  1663.    WRITELN ('║ Nr: 2  │               │                  │           │                ║');
  1664.    WRITELN ('║        ├─ CH 3─────────┼─ I max ──────────┼─ Zeit ────┼─ Alg.──────────╢');
  1665.    WRITELN ('║        │               │                  │           │                ║');
  1666.    WRITELN ('╠═ Akku ═╪═ CH 4 ════════╪═ φ U ════════════╪═ Status ══╪═ Kap.══════════╣');
  1667.    WRITELN ('║ Nr: 3  │               │                  │           │                ║');
  1668.    WRITELN ('║        ├─ CH 5 ────────┼─ I max ──────────┼─ Zeit ────┼─ Alg.──────────╢');
  1669.    WRITELN ('║        │               │                  │           │                ║');
  1670.    WRITELN ('╠═ Akku ═╪═ CH 6 ════════╪═ φ U ════════════╪═ Status ══╪═ Kap.══════════╣');
  1671.    WRITELN ('║ Nr: 4  │               │                  │           │                ║');
  1672.    WRITELN ('║        ├─ CH 7 ────────┼─ I max ──────────┼─ Zeit ────┼─ Alg.──────────╢');
  1673.    WRITELN ('║        │               │                  │           │                ║');
  1674.    WRITELN ('╚════════╧═══════════════╧══════════════════╧═══════════╧════════════════╝');
  1675.    WRITELN ('MESSWERTDATEI : ', Mess_Datei);
  1676.    TEXTCOLOR (13);
  1677.    WRITE ('SCHNITTSTELLEN: ',Ser, ' / ', Par);
  1678.    TEXTBACKGROUND (1);
  1679.    TEXTCOLOR (14);
  1680.    GOTOXY (57, 21);
  1681.    WRITE (' ESC = Abbrechen ');
  1682.    TEXTBACKGROUND (0);
  1683.  
  1684.      FOR Nr := 1 TO 4 DO
  1685.        BEGIN
  1686.          TEXTCOLOR (3);
  1687.          GOTOXY (3, (Nr - 1) * 4 + 5);
  1688.          IF Akku [Nr].Spg > 0 THEN WRITE (Akku [Nr].Spg :0:1,' V');
  1689.  
  1690.          GOTOXY (60, (Nr - 1) * 4 + 4);
  1691.          IF Akku [Nr].Kap > 0 THEN WRITE (Akku [Nr].Kap :0:0,' mAh');
  1692.  
  1693.          TEXTCOLOR (14);
  1694.          GOTOXY (60, (Nr - 1) * 4 + 6);
  1695.            CASE Akku [Nr].Algor OF
  1696.              1 : WRITE ('NUR LADEN');
  1697.              2 : WRITE ('VORHER ENTLAD.');
  1698.              3 : WRITE ('REGENERIEREN');
  1699.            END;
  1700.        END;
  1701.    TEXTCOLOR (10);
  1702. END;
  1703.  
  1704. { ┌────────────────────────────────────────────────────────────────────────┐
  1705.   │    TABELLENEINTRAG                                                     │
  1706.   │    EINGABEN : LADEPLATZ-NUMMER                                         │
  1707.   │    AUSGABE  : WERTE IN DIE TABELLE SCHREIBEN                           │
  1708.   └────────────────────────────────────────────────────────────────────────┘ }
  1709. PROCEDURE TabEintrag (Platz : BYTE);
  1710.  
  1711. VAR  ZE, CO  : BYTE;
  1712.  
  1713. BEGIN
  1714.   CASE Platz OF
  1715.    1: BEGIN
  1716.        ZE := 4;
  1717.        CO := 10;
  1718.       END;
  1719.    2: BEGIN
  1720.        ZE := 8;
  1721.        CO := 13;
  1722.       END;
  1723.    3: BEGIN
  1724.        ZE := 12;
  1725.        CO := 7;
  1726.       END;
  1727.    4: BEGIN
  1728.        ZE := 16;
  1729.        CO := 1;
  1730.       END;
  1731.   END; { END von CASE }
  1732.  
  1733.    GOTOXY (12, ZE);
  1734.    TEXTCOLOR (CO);
  1735.    WRITE (Mess1[Platz]:6:3,' VOLT');
  1736.    GOTOXY (28, ZE);
  1737.    WRITE (Akku [Platz].V_Mittel :7:4,' VOLT');
  1738.    GOTOXY (12, ZE+2);
  1739.    WRITE (Mess2[Platz]:6:3,' VOLT');
  1740.    GOTOXY (28, ZE+2);
  1741.    WRITE ((Mess1[Platz] - Mess2[Platz]) / R[Platz] : 6:3,' AMPERE');
  1742.    GOTOXY (47, ZE);
  1743.    IF Akku [Platz].Laden = TRUE THEN WRITE ('LADEN ', Akku [Platz].Zyklus, ' ') ELSE
  1744.    IF Akku [Platz].Entladen = TRUE THEN WRITE ('ENTLADEN') ELSE
  1745.    IF Akku [Platz].Defekt = TRUE THEN
  1746.     BEGIN
  1747.       TEXTCOLOR (28);
  1748.       WRITE ('DEFEKT !');
  1749.       TEXTCOLOR (CO);
  1750.        END ELSE
  1751.         BEGIN TEXTCOLOR (31);
  1752.          WRITE ('VOLL   ');
  1753.          TEXTCOLOR (CO);
  1754.         END;
  1755.       GOTOXY (47, ZE+2);
  1756.       GETTIME (std,min,sek,s100);
  1757.      WRITE (TFormat (std),':',TFormat (min),':',TFormat (sek));
  1758. END;
  1759.  
  1760. { ┌────────────────────────────────────────────────────────────────────────┐
  1761.   │    STARTPROTOKOLL AUF DRUCKER AUSGEBEN                                 │
  1762.   │    EINGABEN : KEINE                                                    │
  1763.   │    AUSGABE  : PROTOKOLL AN STANDARDDRUCKER LPT1                        │
  1764.   └────────────────────────────────────────────────────────────────────────┘ }
  1765. PROCEDURE Startprotokoll;
  1766.  
  1767. VAR Z       : BYTE;
  1768.  
  1769. BEGIN;
  1770. {$I-}
  1771.  WRITELN (LST,'            ╔════════════════════════════════════════════════╗');
  1772.  WRITELN (LST,'            ║        NI-CD-AKKULADER   Version 2.0           ║');
  1773.  WRITELN (LST,'            ║        (c) Carsten Stelling                    ║');
  1774.  WRITELN (LST,'            ║            Alleestraße 10                      ║');
  1775.  WRITELN (LST,'            ║            56566 Neuwied                       ║');
  1776.  WRITELN (LST,'            ║            Tel: 02622 / 4062                   ║');
  1777.  WRITELN (LST,'            ╚════════════════════════════════════════════════╝',#10);
  1778.  
  1779.  WRITE (LST,'        PROTOKOLL DES LADEVORGANGES VOM: ');
  1780.  WRITELN (LST, tag,'.',mon,'.',jahr,' - ',TFormat (Std),':',TFormat (min),':',TFormat (sek),' Uhr');
  1781.  
  1782.  WRITELN (LST,'        Messdatenerfassung in Datei: ',Mess_Datei);
  1783.  WRITELN (LST,'        Steuern mit Schnittstelle  : ',Par);
  1784.  WRITELN (LST,'        ADU an ser. Schnittstelle  : ',Ser, #10);
  1785.  
  1786.  FOR Z := 1 TO 4 DO
  1787.   BEGIN
  1788.    WRITELN (LST,'         AKKU ',Z,': Nennspannung : ',Akku [Z].Spg:4:1,' Volt');
  1789.    WRITELN (LST,'                 Nennkapazität: ',Akku [Z].Kap:5:0,' mAh');
  1790.    WRITE (LST,'                 Algorithmus..: ');
  1791.     CASE Akku [Z].Algor OF
  1792.      0: WRITELN (LST,'---');
  1793.      1: WRITELN (LST,'nur laden');
  1794.      2: WRITELN (LST,'vorher entladen');
  1795.      3: WRITELN (LST,'regenerieren in 3 Zyklen');
  1796.     END;
  1797.    WRITE (LST,'                 Status.......: ');
  1798.    IF Akku [Z].Online = TRUE THEN WRITELN (LST, 'ONLINE') ELSE
  1799.    IF Akku [Z].Online = FALSE THEN WRITELN (LST, 'OFFLINE');
  1800.    IF Akku [Z].Defekt = TRUE THEN WRITELN (LST,'                 *** AKKU DEFEKT ***');
  1801.   WRITELN (LST,'       ────────────────────────────────────────────────────────────────────');
  1802.   END;
  1803. {$I+}
  1804. Dr_OK := IORESULT=0;
  1805. END;
  1806.  
  1807. { ┌────────────────────────────────────────────────────────────────────────┐
  1808.   │    ENDPROTOKOLL AUF DRUCKER AUSGEBEN                                   │
  1809.   │    EINGABEN : KEINE                                                    │
  1810.   │    AUSGABE  : PROTOKOLL AN STANDARDDRUCKER LPT1                        │
  1811.   └────────────────────────────────────────────────────────────────────────┘ }
  1812. PROCEDURE Endprotokoll;
  1813.  
  1814. VAR Z : BYTE;
  1815.  
  1816. BEGIN
  1817. {$I-}
  1818.  WRITE (LST,'        ENDE DES LADEVORGANGES AM: ');
  1819.  WRITE (LST, tag,'.',mon,'.',jahr,' - ',TFormat (Std),':',TFormat (min),':',TFormat (sek),' Uhr',#10,#10,#13);
  1820.  
  1821.  FOR Z := 1 TO 4 DO
  1822.   BEGIN
  1823.    WRITELN (LST,'         AKKU ',Z,': Istspannung..: ',Akku [Z].V_Mittel:6:3,' Volt');
  1824.      WRITE (LST,'                 Status.......:  ');
  1825.    IF Akku [Z].Online = TRUE THEN WRITELN (LST, 'ONLINE') ELSE
  1826.    IF Akku [Z].Online = FALSE THEN WRITELN (LST, 'OFFLINE');
  1827.    IF Akku [Z].Defekt = TRUE THEN WRITELN (LST,'                 *** AKKU DEFEKT ***');
  1828.   WRITELN (LST,'       ────────────────────────────────────────────────────────────────────');
  1829.   END;
  1830.   IF Bed_Abr = TRUE THEN WRITELN (LST, #10,'          LADEVORGANG WURDE VORZEITIG ABGEBROCHEN !!');
  1831.   WRITELN (LST, #12);
  1832. {$I+}
  1833. Dr_OK := IORESULT=0;
  1834. END;
  1835.  
  1836. { ┌────────────────────────────────────────────────────────────────────────┐
  1837.   │    PROGRAMM-ENDE                                                       │
  1838.   │    EINGABEN : KEINE                                                    │
  1839.   │    AUSGABE  : RÜCKKEHR ZUR DOS- ODER PASCAL UMGEBUNG                   │
  1840.   └────────────────────────────────────────────────────────────────────────┘ }
  1841.  {$F+}
  1842.  PROCEDURE Programm_Ende;
  1843.  {$F-}
  1844.  VAR Nr   : BYTE;
  1845.      OK   : BOOLEAN;
  1846.      Antw : CHAR;
  1847.  
  1848. BEGIN
  1849.    EXITPROC := Exit_Adr;
  1850.  
  1851.    FOR Nr := 1 TO 4 DO
  1852.      BEGIN
  1853.        Laden_aus (Nr);
  1854.        Entladen_aus (Nr);
  1855.      END;
  1856.  
  1857.     FOR Nr := 1 TO 4 DO
  1858.      BEGIN
  1859.       IF Akku [Nr].Defekt = TRUE THEN Messwert [Nr] := 999
  1860.        ELSE
  1861.       IF (Akku [Nr].Defekt = FALSE) AND (Akku [Nr].Laden = FALSE) AND
  1862.          (Akku [Nr].Entladen = FALSE) THEN Messwert [Nr] := 888
  1863.        ELSE
  1864.       IF ((Akku [Nr].Laden = TRUE) OR (Akku [Nr].Entladen = TRUE)) AND
  1865.          (Bed_Abr = TRUE) THEN Messwert [Nr] := 777
  1866.        ELSE
  1867.          Messwert [Nr] := 999;
  1868.      END;
  1869.     WRITE (Mess_Daten, Messwert);
  1870.  
  1871.     GETTIME (std,min,sek,s100);
  1872.     Messwert [1] := std;
  1873.     Messwert [2] := min;
  1874.     Messwert [3] := sek;
  1875.     Messwert [4] := s100;
  1876.     WRITE (Mess_Daten, Messwert);
  1877.  
  1878.     IF Dr_OK = FALSE THEN
  1879.      BEGIN
  1880.       GOTOXY (1, 23);
  1881.       TEXTBACKGROUND (12);
  1882.       TEXTCOLOR (15);
  1883.       WRITE (' ALARM:  DRUCKER NICHT BETRIEBSBEREIT AN LPT1                                 ');
  1884.      END;
  1885.  
  1886.     GOTOXY (1, 24);
  1887.     TEXTBACKGROUND (0);
  1888.     TEXTCOLOR (31);
  1889.     WRITE (' LADEVORGANG ABGESCHLOSSEN.  -  BITTE EINE BELIEBIGE TASTE DRÜCKEN.');
  1890.  
  1891.     IF Drucken = TRUE THEN Endprotokoll;
  1892.  
  1893.     CLOSE (Mess_Daten);
  1894.  
  1895.      Mausein (1);
  1896.      CursorEin;
  1897.  
  1898.      DELAY (1000);
  1899.  
  1900.      REPEAT
  1901.       Mausstatus;
  1902.      UNTIL (KEYPRESSED) OR (Maust = 1);
  1903.      IF KEYPRESSED THEN
  1904.       BEGIN
  1905.        Antw := READKEY;
  1906.        Antw := ' ';
  1907.       END;
  1908.  
  1909.      Mausein (0);
  1910.   END;
  1911.  
  1912. { ┌────────────────────────────────────────────────────────────────────────┐
  1913.   │    H A U P T P R O G R A M M                                           │
  1914.   │    EINGABEN : KEINE                                                    │
  1915.   │    AUSGABE  : STEUERUNG DER AKKU LADE- UND ENTLADEZYKLEN               │
  1916.   └────────────────────────────────────────────────────────────────────────┘ }
  1917. BEGIN
  1918.   IF AdrLPT1 <> 0 THEN PORT [AdrLPT1] := 0;        { LPT-Ports initialisieren }
  1919.   IF AdrLPT2 <> 0 THEN PORT [AdrLPT2] := 0;
  1920.   IF AdrLPT3 <> 0 THEN PORT [AdrLPT3] := 0;
  1921.  
  1922.   CursorErmitteln;                                 { Cursorpos. und Erscheinungsbild ermitteln }
  1923.   CursorEin;                                       { Cursor darstellen }
  1924.   Wid_Werte;                                       { Widerstandswerte aus SETUP holen }
  1925.   Drucken := FALSE;                                { Voreinstellung: kein Protokoll }
  1926.   Zoom := 2;                                       { Voreinstellung feines Zeitraster }
  1927.   Mausinit;                                        { Maustreiber initialisieren }
  1928.   Mausein (1);                                     { Mauscursor einschalten }
  1929.  
  1930. START:
  1931.   Dr_OK := TRUE;                                   { Druck OK }
  1932.   Bed_Abr := FALSE;                                { kein Bedienerabbruch }
  1933.   AD_Init_Err := FALSE;                            { kein Init-Fehler }
  1934.   PORT [AdrLPT] := 0;                              { aktuellen Port initialisieren }
  1935.  
  1936.   Einstellungen;                                   { Parametrierung }
  1937.  
  1938.   AD_Wandler_init;                                 { A/D-Wandler initialisieren und feststellen }
  1939.                                                    { ob dieser überhaupt vorhanden ist. }
  1940.   IF AD_Init_Err = TRUE THEN GOTO START;           { Neustart bei Initialisierungsfehler }
  1941.  
  1942.   Exit_Adr := EXITPROC;                            { Zeiger der System-Rücksprungadresse sichern }
  1943.   EXITPROC := @Programm_Ende;                      { Zeiger auf Adresse der eigenen Prozedur einstellen }
  1944.  
  1945.   ASSIGN (Mess_Daten, Mess_Datei);                 { Messwert-Datei öffnen }
  1946.   REWRITE (Mess_Daten);                            { Messwert-Datei überschreiben }
  1947.  
  1948.   GETTIME (std, min, sek, s100);                   { akt. Datum und Uhrzeit }
  1949.   GETDATE (jahr, mon, tag, wtag);
  1950.   Messwert [1] := wtag;
  1951.   Messwert [2] := tag;
  1952.   Messwert [3] := mon;
  1953.   Messwert [4] := jahr;
  1954.   WRITE (Mess_Daten, Messwert);                    { Datum in Rec. 1 speichern }
  1955.  
  1956.   Messwert [1] := std;
  1957.   Messwert [2] := min;
  1958.   Messwert [3] := sek;
  1959.   Messwert [4] := s100;
  1960.   WRITE (Mess_Daten, Messwert);                    { Zeit in Rec. 2 speichern }
  1961.  
  1962. { *** Akkus testen *** }
  1963.   FOR Zaehler := 1 TO 4 DO
  1964.    BEGIN
  1965.     IF Akku [Zaehler].Kap = 0 THEN Akku [Zaehler].Online := FALSE ELSE
  1966.        Akku [Zaehler].Online := TRUE;
  1967.  
  1968.     IF (Akku [Zaehler].Kap > 0) AND ((AD_Messwert (Zaehler*2-1) < 0.4) OR (AD_Messwert (Zaehler * 2 - 1) > 1.7)) THEN
  1969.       Akku [Zaehler].Defekt := TRUE ELSE
  1970.         BEGIN
  1971.          Akku [Zaehler].Defekt := FALSE;
  1972.          Akku [Zaehler].Proben := 0;
  1973.          Akku [Zaehler].V_Mittel := 0;
  1974.          Akku [Zaehler].V_Summe := 0;
  1975.          Akku [Zaehler].Zyklus := 1;
  1976.         END;
  1977.  
  1978.     IF (Akku [Zaehler].Online = TRUE) AND (Akku [Zaehler].Algor = 1) THEN
  1979.        Akku [Zaehler].Laden := TRUE;
  1980.  
  1981.     IF (Akku [Zaehler].Online = TRUE) AND ((Akku [Zaehler].Algor = 2) OR
  1982.        (Akku [Zaehler].Algor = 3)) THEN
  1983.        BEGIN
  1984.         Akku [Zaehler].Entladen := TRUE;
  1985.        END;
  1986.    END;
  1987.  
  1988.    IF Drucken = TRUE THEN Startprotokoll;
  1989.      IF Dr_OK = FALSE THEN
  1990.       BEGIN
  1991.        Programm_Ende;
  1992.        GOTO START;
  1993.       END;
  1994.  
  1995.     FOR Zaehler := 1 TO 4 DO
  1996.      BEGIN
  1997.       Messwert [Zaehler] := Akku [Zaehler].Kap;
  1998.      END;
  1999.       WRITE (Mess_Daten, Messwert);
  2000.  
  2001.     FOR Zaehler := 1 TO 4 DO
  2002.      BEGIN
  2003.       Messwert [Zaehler] := Akku [Zaehler].Spg;
  2004.      END;
  2005.       WRITE (Mess_Daten, Messwert);
  2006.  
  2007.     FOR Zaehler := 1 TO 4 DO
  2008.      BEGIN
  2009.       Messwert [Zaehler] := Akku [Zaehler].Algor;
  2010.      END;
  2011.       WRITE (Mess_Daten, Messwert);
  2012.  
  2013.     GETTIME (std, min, sek, s100);
  2014.     minalt := min;
  2015.  
  2016.     Mausein (1);
  2017.     CursorAus;
  2018.  
  2019.   REPEAT;                                          { Wiederholen bis alle A. offline }
  2020.    FOR Zaehler := 1 TO 5 DO                        { Umlaufender Zähler }
  2021.     BEGIN
  2022.      CASE Zaehler OF
  2023.       5 : BEGIN                                    { 5. Schritt }
  2024.            GETTIME (std,min,sek,s100);             { Uhrzeit }
  2025.            IF min <> minalt THEN                   { eine Minute ist um dann }
  2026.             BEGIN                                  { Testen ob Steigung der Ladekurve negativ }
  2027.              minalt := min;
  2028.               FOR Z := 1 TO 4 DO
  2029.                BEGIN
  2030.                 IF Akku [Z].Online = TRUE THEN
  2031.                  BEGIN
  2032.                   IF Akku [Z].Proben = 0 THEN Akku [Z].Proben := 1;
  2033.                    Akku [Z].V_Mittel := Akku [Z].V_Summe / Akku [Z].Proben;
  2034.                    Akku [Z].Proben := 0;
  2035.                    Akku [Z].V_Summe := 0;
  2036.                   IF (Akku [Z].V_Mittel + 0.0001 < Akku [Z].V_Vorher) AND (Akku [Z].Entladen = FALSE) THEN
  2037.                     BEGIN
  2038.                       IF (Akku [Z].Algor = 3) AND (Akku [Z].Zyklus < 2) THEN
  2039.                        BEGIN
  2040.                         Akku [Z].Laden := FALSE;
  2041.                         Akku [Z].Entladen := TRUE;
  2042.                         INC (Akku [Z].Zyklus, 1);
  2043.                         Tabeintrag (Z);
  2044.                        END ELSE BEGIN
  2045.                       WITH Akku [Z] DO
  2046.                         BEGIN
  2047.                          Laden := FALSE;
  2048.                          Entladen := FALSE;
  2049.                          Online := FALSE;
  2050.                          Tabeintrag (Z);
  2051.                         END;  { END von WITH }
  2052.                       END;  { END von IF }
  2053.                     END; {END von IF }
  2054.                   Akku [Z].V_Vorher := Akku [Z].V_Mittel;
  2055.                   Messwert [Z] := Akku [Z].V_Mittel;
  2056.                  Tabeintrag (Z);
  2057.                 END;    { END von IF }
  2058.                END;    { END von FOR DO }
  2059.  
  2060.               WRITE (Mess_Daten, Messwert);
  2061.  
  2062.              END;  { END von IF }
  2063.           END; { END von BEGIN }
  2064.  
  2065. 1,2,3,4 : BEGIN
  2066.            IF Akku [Zaehler].Online = TRUE THEN
  2067.             BEGIN
  2068.              IF (Akku [Zaehler].Algor = 1) AND (Akku [Zaehler].Laden = TRUE) AND
  2069.                 (Akku [Zaehler].Online = TRUE) THEN GOTO LADEN;
  2070.              IF ((Akku [Zaehler].Algor = 2) OR (Akku [Zaehler].Algor = 3)) AND
  2071.                 (Akku [Zaehler].Entladen = TRUE) AND (Akku [Zaehler].Online = TRUE)
  2072.                   THEN GOTO ENTLADEN;
  2073.  
  2074.              LADEN:
  2075.               Laden_ein (Zaehler);
  2076.               DELAY (200);
  2077.               Laden_aus (Zaehler);
  2078.               Pruef := AD_Messwert (Zaehler);
  2079.               Mess1 [Zaehler] := AD_Messwert (Zaehler * 2 - 1);
  2080.               Mess2 [Zaehler] := AD_Messwert (Zaehler * 2);
  2081.               Tabeintrag (Zaehler);
  2082.  
  2083.               Entladen_ein (Zaehler);
  2084.               DELAY (1);
  2085.               Entladen_aus (Zaehler);
  2086.               GOTO EINTRAG;
  2087.  
  2088.              ENTLADEN:
  2089.               Laden_aus (Zaehler);                 { zur Sicherheit }
  2090.               Entladen_ein (Zaehler);
  2091.               Microdelay (TRUNC(Akku [Zaehler].Kap * 50));
  2092.               Pruef := AD_Messwert (Zaehler);
  2093.               Mess1 [Zaehler] := AD_Messwert (Zaehler * 2 - 1);
  2094.               Mess2 [Zaehler] := AD_Messwert (Zaehler * 2);
  2095.               Tabeintrag (Zaehler);
  2096.               Entladen_aus (Zaehler);
  2097.               Microdelay (TRUNC(Akku [Zaehler].Kap * 50));
  2098.  
  2099.              EINTRAG:
  2100.               Akku [Zaehler].V_summe := Akku [Zaehler].V_Summe + Mess1 [Zaehler];
  2101.               Akku [Zaehler].Proben := Akku [Zaehler].Proben + 1;
  2102.             END; { END von IF }
  2103.          END; { END von BEGIN CASE }
  2104.       END; { END von CASE OF }
  2105.  
  2106.    { *** SICHERHEITSTESTS *** }
  2107.  
  2108.    IF Akku [Zaehler].Online = TRUE THEN
  2109.     BEGIN
  2110.      IF (Mess1 [Zaehler] < 0.4) OR (Mess1 [Zaehler] > 1.8) THEN
  2111.        BEGIN
  2112.          WITH Akku[Zaehler] DO
  2113.           BEGIN
  2114.             Online := FALSE;
  2115.             Defekt := TRUE;
  2116.             Laden := FALSE;
  2117.             Entladen := FALSE;
  2118.             Tabeintrag (Zaehler);
  2119.          END;
  2120.        END;
  2121.      END;
  2122.  
  2123.    IF (Akku [Zaehler].Online = TRUE) AND (Akku [Zaehler].Entladen = TRUE) AND
  2124.       (Mess1 [Zaehler] < 0.8) THEN
  2125.         BEGIN
  2126.          Akku [Zaehler].Entladen := FALSE;
  2127.          Akku [Zaehler].Laden := TRUE;
  2128.          Akku [Zaehler].V_Mittel := Akku [Zaehler].V_Summe / Akku [Zaehler].Proben;
  2129.          Akku [Zaehler].V_Vorher := Akku [Zaehler].V_Mittel;
  2130.          Tabeintrag (Zaehler);
  2131.         END;
  2132.  
  2133.    END;  { END von FOR }
  2134.  
  2135. { *** Tastatur bedienen *** }
  2136.  
  2137.    IF KEYPRESSED THEN
  2138.     BEGIN
  2139.      Taste := READKEY;
  2140.      IF Taste = CHR (27) THEN
  2141.       BEGIN
  2142.        Bed_Abr := TRUE;
  2143.        Programm_Ende;
  2144.        GOTO START;
  2145.       END;
  2146.     END;
  2147.  
  2148.    Mausstatus;
  2149.     Mausx := (Mausx + 8) DIV 8;
  2150.     Mausy := (Mausy + 8) DIV 8;
  2151.     IF (Maust = 1) AND (Mausx > 56) AND (Mausx < 74) AND (Mausy = 22) THEN
  2152.      BEGIN
  2153.       Bed_Abr := TRUE;
  2154.       Programm_Ende;
  2155.       GOTO START;
  2156.      END;
  2157.  
  2158. { *** Schleife wiederholen bis kein Akku mehr Online *** }
  2159.  
  2160.    UNTIL (Akku [1].Online = FALSE) AND (Akku [2].Online = FALSE) AND
  2161.          (Akku [3].Online = FALSE) AND (Akku [4].Online = FALSE);
  2162.  
  2163.   Programm_Ende;
  2164.   GOTO START;
  2165. END.