(***************************************************************************** * SAMPLE2.PAS : FREQUENCY MEASUREMENT * * * * This is a demonstration program to be used with the CTR-5 Counter * * timer board. The program will measure frequency from about 1Hz up to * * 65KHz. By changing the number of 1ms periods, the frequency range can * * be changed, but resolution is still only 16 bits. A modification of this* * program cascading two counters could yield 32 bit accuracy. * * * * The board should be set as follows: * * -- On board clock set to 1 MHz * * -- Input is applied to pin 13, counter 5 input. * * * * LAST MODIFICATION: 2/5/98 * * * *****************************************************************************) program sample2; {$L ctr5drv} {$F+} USES crt; TYPE param_array = array[1..10] of integer; (* These variable MUST be declared as global. They are the ones whose offsets are passed to the CTR5DRVC routine. If they are not global then the driver will not find their segment. *) VAR status,task :integer; params :param_array; procedure ctr5drv(t_off:word;p_off:word;st_off:word);external; function AskForBaseAddress(OldOne : String) : Word; const Msg : string[4] = '0'; var NewOne, Success, Dummy, Error : Word; AddrInputPosX, AddrInputPosY : Word; begin if (OldOne = 'OLD') then OldOne := Msg; WriteLn('Please enter the Base Address (0000-FFFF) for your card (in hex)'); WriteLn('or press ENTER for ', OldOne, '. '); Write('>'); AddrInputPosX := WhereX; AddrInputPosY := WhereY; repeat GotoXY(AddrInputPosX, AddrInputPosY); ClrEol; Readln(Msg); Val('$' + Msg, NewOne, Error); if (error=0) then begin Success := 1; Dummy := NewOne; end else if (Msg = '') then begin GotoXY(AddrInputPosX, AddrInputPosY); WriteLn(OldOne); Msg := OldOne; Success := 1; Val('$' + Msg, Dummy, Error); end; until (Success = 1); AskForBaseAddress := Dummy; end; { end of AskForBaseAddress } (***************************************************************************** * PROCEDURE: call_driver -- local routine * * * * PURPOSE: Performs the call to the driver package. * * * * INPUT: None. * * * * CALLS: ctr5drv - entry point to driver package. * * * *****************************************************************************) procedure call_driver; var t_off,p_off,st_off :word; begin (* this section extracts the offset of the parameters that we will pass to the assembly driver *) t_off := ofs(task); (* offset of task number *) p_off := ofs(params[1]); (* offset of param list *) st_off := ofs(status); (* offset of status code *) status := 0; ctr5drv(t_off,p_off,st_off); (* call the driver *) (* this section checks for an error code *) if status > 0 then begin WriteLn('A status error code of ',status,' was detected.'); WriteLn('Program terminated.'); end; end; (* end call_driver *) (***************************************************************************** * PROCEDURE: setup -- local routine * * * * PURPOSE: Sets up the driver and counter board. * * * * INPUT: None. * * * * CALLS: call_driver - entry point to driver package. * * * *****************************************************************************) procedure setup(Address:word); var I :integer; begin GotoXY(20,10); write('FREQUENCY: Hz'); (* display frequency label on screen*) GotoXY(15,13); write('Press any key to exit the program.'); (* initialize the board *) params[1] := Address; (* starting board address *) params[2] := 1; (* FOUT divider ratio = 1 *) params[3] := 14; (* FOUT source = F4 *) params[4] := 0; (* counter 2 compare disabled *) params[5] := 0; (* counter 1 compare disabled *) params[6] := 0; (* disable time of day *) task := 0; call_driver; (* call driver *) end; (* setup *) (***************************************************************************** * PROCEDURE: get_readings -- local routine * * * * PURPOSE: Uses the driver to measure the freqency of an input. * * * * INPUT: None. * * * * CALLS: call_driver - entry point to driver package. * * * *****************************************************************************) procedure get_readings; var value :word; begin params[1] := 1000; (* 1000 1ms intervals = 1 second *) params[2] := 5; (* counter 5 input is source *) params[3] := 0; (* this param returns counts *) task := 10; call_driver; (* call driver *) GotoXY(31,10); value := params[3]; WriteLn(value:8); (* display the value *) end; (* get_readings *) (***************************************************************************** * PROCEDURE: main -- local routine * * * * PURPOSE: Controls program flow, detects when user is ready to exit. * * * * INPUT: None. * * * * CALLS: setup - set up program and drivers. * * get_readings - read the frequency and display. * * * *****************************************************************************) var ch :char; Address :word; BEGIN (* main procedure *) ClrScr; WriteLn(' SAMPLE2.PAS : FREQUENCY MEASUREMENT '); WriteLn(' '); WriteLn(' This is a demonstration program to be used with the CTR-5 Counter '); WriteLn(' timer board. The program will measure frequency from about 1Hz up to '); WriteLn(' 65KHz. By changing the number of 1ms periods, the frequency range can '); WriteLn(' be changed, but resolution is still only 16 bits. A modification of this'); WriteLn(' program cascading two counters could yield 32 bit accuracy. '); WriteLn(' '); WriteLn; Address := AskForBaseAddress('350'); ClrScr; WriteLn; WriteLn; WriteLn; WriteLn(' Board Configuration:'); WriteLn; WriteLn(' -- On board clock set to 1 MHz (required) '); WriteLn(' -- Input should be applied to pin 13, counter 5 input (required) '); WriteLn(' -- All remaining jumper settings should not be altered.'); WriteLn; WriteLn; WriteLn; WriteLn; WriteLn('Press ENTER to continue'); ReadLn; ClrScr; setup(Address); (* set up program and the driver *) if status <> 0 then exit; (* is status > 0 then board error *) while not keypressed do begin get_readings; (* read the frequency *) if status <> 0 then exit; (* if status > 0 then error *) end; ch := ReadKey; (* clear the exit char *) ClrScr; END. (* main program *)