$linenum 10001,sysprog$ $ucsd, modcal$ $lines 20000$ $sysprog$ module k196_con; export FUNCTION K196_Error : BOOLEAN; PROCEDURE trigger_K196; PROCEDURE Init_K196; PROCEDURE Set_k196_Res (res : integer); PROCEDURE Set_k196_Range (range : integer); PROCEDURE Set_k196_Mode (M,T : CHAR); PROCEDURE Set_k196_Filter(filter: integer); FUNCTION Read_k196: REAL; { Reads Keithley 196 DVM } PROCEDURE Reset_k196; implement import iodeclarations,general_0,general_2, general_1,sysdevs,hpib_1,hpib_2,hpib_3,hpib_0, newasm,sysglobals; const k196Addr = 707; var waitsecs,waitread,waitset :integer; PROCEDURE Wait(sec: REAL); {wait for sec seconds} var t:INTEGER; begin t := sysclock; while t + sec*100 > sysclock do ; end; FUNCTION Ready : BOOLEAN; {Performs a Serial Poll of the Keithley 196 and waits until it gets a ready bit set.} var status: integer; done : boolean; begin done:=false; repeat Status:= SPOLL (k196Addr); {read serial pole byte} IF na_test (4,Status) THEN done:=true; until done; ready:=true; end; {ready} FUNCTION Readingdone : BOOLEAN; {Performs a Serial Poll of the Keithley 196 and waits until it gets a reading done bit set.} var status,i : integer; done : boolean; begin done:=false; i:=0; repeat Status:= SPOLL (k196Addr); {read serial pole byte} IF na_test (3,Status) THEN done:=true; i:=i+1; (* if i >= 500 then begin writeln('Timeout Error in Keithley 196, Reading cycle not ending'); done:=true; end; *) until done; readingdone:=true; end; {readingdone} FUNCTION K196_Error : BOOLEAN; { Performs an error check of the Keithley 196. Returns : TRUE if error condition exists. FALSE otherwise } VAR ErrStr : STRING[255]; status: integer; BEGIN K196_Error := FALSE; Status:= SPOLL (k196Addr); IF na_test (5,Status) THEN begin K196_Error :=true; if ready then WRITESTRINGLN (K196Addr,'G1U1X'); if ready then READSTRING (K196Addr, ErrStr); writeln('Error String= ',ErrStr); if ErrStr[1]='1' then writeln('Trigger Error'); if ErrStr[12]='1' then writeln('Illegal Command Option'); if ErrStr[13]='1' then writeln('Illegal Command'); if ErrStr[11]='1' then writeln('No Remote'); end; END; {K196_Error} PROCEDURE TRIGGER_K196; {triggers the Keithley 196 } begin if ready then WRITESTRINGLN (k196Addr, 'T5X'); {trigger Keithley 196} end; {trigger_k196} PROCEDURE Init_K196; {Auto,Disable SRQ,Trigger on X,No prefix,4 1/2 digits,(Trigger)} BEGIN if ready then WRITESTRINGLN (K196Addr, 'R0M0T5G1S1X'); IF K196_Error THEN WRITELN ('Error occurred initializing Keithley 196'); END; {Init_K196} PROCEDURE Set_k196_Res(res : integer); { Sets the resolution of the 196 3 = 3 1/2 digits - S0 4 = 4 1/2 digits - S1 5 = 5 1/2 digits - S2 6 = 6 1/2 digits - S3 } VAR Cmd_Str : STRING[255]; Length,j : INTEGER; begin IF NOT (res IN [3..6]) THEN WRITELN ('ILLEGAL resolution for K196 : ',res:0) ELSE BEGIN Cmd_Str := ' '; waitsecs:=0; case res of 3: j:=0; 4: j:=1; 5: j:=2; 6: begin j:=3; waitsecs :=4; {with 6 1/2 digit resolution the 196 takes 3 secs. for 1 reading} end; end; {case} STRWRITE (Cmd_Str, 1, Length, 'S', j:1, 'X'); if ready then WRITESTRINGLN (K196Addr, Cmd_Str); IF K196_Error THEN WRITELN ('Error occurred in Set_196_Res, with Cmd_Str=',Cmd_Str); END; end; PROCEDURE Set_k196_Range (range : integer); {Sets the 196 range to Auto if 0 or to the range selected by the integer 1 thru 7} VAR Cmd_Str : STRING[255]; Length : INTEGER; begin IF NOT (range IN [0..7]) THEN WRITELN ('ILLEGAL range for K196 : ',range:0) ELSE BEGIN Cmd_Str := ' '; STRWRITE (Cmd_Str, 1, Length, 'R', range:1, 'X'); if ready then WRITESTRINGLN (K196Addr, Cmd_Str); wait(waitset); IF K196_Error THEN WRITELN ('Error occurred in Set_196_Range, with Cmd_Str=',Cmd_Str); END; end; PROCEDURE Set_k196_Mode (M,T : CHAR); { Determines the mode of operation of the Keithley 196 System DMM "M" 'V' ==> Voltmeter 'A' ==> Ammeter 'R' ==> Ohmmeter "T" 'A' ==> AC 'D' ==> DC 'B' ==> dB } VAR Cmd_Str : STRING[255]; Length, j : INTEGER; BEGIN M:=charupper(M); { Change lower case letters to upper case } T:=charupper(T); IF NOT ((M IN ['V','A','R']) or (T IN ['A','D','B'])) THEN WRITELN ('ILLEGAL mode for K196 : ',T,M) ELSE BEGIN waitread:=0; IF (M='V') and (T='D') then j:= 0 else IF (M='V') and (T='A') then begin j:= 1; waitread:=1; end else IF (M='R') then j:= 2 else IF (M='A') and (T='D') then j:= 3 else IF (M='A') and (T='A') then j:= 4 else IF (M='V') and (T='B') then j:= 5 else IF (M='A') and (T='B') then j:= 6; Cmd_Str := ' '; STRWRITE (Cmd_Str, 1, Length, 'F', j:1, 'X'); if ready then WRITESTRINGLN (K196Addr, Cmd_Str); wait(waitset); IF K196_Error THEN WRITELN ('Error occurred in Set_k196_Mode, with Cmd_Str=',Cmd_Str); END; END; {Set_k196_Mode} Procedure Set_k196_filter(filter: integer); {Sets filter function to off if filter = 0 Number of readings averaged if filter = 1-99} VAR Cmd_Str : STRING[255]; Length, status : INTEGER; Done : boolean; begin IF NOT (filter IN [0..99]) then writeln('Illegal number of readings to be averaged in Set_k196_filter(1-99)') ELSE begin Cmd_Str := ' '; IF filter =0 then begin if ready then WRITESTRINGLN(k196Addr,'P0X'); end ELSE begin IF (filter IN [1..9]) then STRWRITE (Cmd_Str, 1, Length, 'P',0:1, filter:1, 'X') ELSE IF (filter IN [10..99]) then STRWRITE (Cmd_Str, 1, Length, 'P', filter:2, 'X'); if ready then WRITESTRINGLN (K196Addr, Cmd_Str); end; IF K196_Error THEN WRITELN ('Error occurred in Set_k196_Filter, with Cmd_Str=',Cmd_Str); end; end; {Set_k196_filter} FUNCTION Read_k196: REAL; { Reads Keithley 196 DVM } VAR Answer : STRING[255]; Length, status: INTEGER; Dummy : REAL; Done : boolean; BEGIN wait(waitread); {wait for meter to settle after input change} wait(waitsecs); {wait for meter to get data accurately with resolution} if ready then TRIGGER_K196; {Start a new set of data reading} if readingdone then if ready then WRITESTRINGLN (K196Addr, 'G0X'); {send prefix back with data ,trigger} READSTRING (K196Addr, Answer); IF K196_Error THEN BEGIN WRITELN ('Error occurred in Read_k196'); Read_k196 := 0; END ELSE {no error} BEGIN STRREAD (Answer,5,Length,Dummy); Read_k196 := Dummy; {Place to hold data} IF Answer[1]='O' THEN WRITELN ( '*** K196 OVERFLOW ***'); END; END; {Read_k196} PROCEDURE Reset_k196; {put 196 into continous trigger and local mode} VAR Cmd_Str : STRING[255]; Length : INTEGER; begin if ready then WRITESTRINGLN (K196Addr,'T4X'); CLEAR (K196Addr); LOCAL (K196Addr); call(cleariohook); end; end.