{*------------------------------------------------------------------- * SAMPLE3.C * * DA12-16 C language sample 3. Program illustrates access to * simultaneous and automatic modes. * * Last Modified: 2/5/98 SMG *------------------------------------------------------------------*} Uses Crt; Var Base, EBase : Word; Key : Char; Channel : Byte; PortVal : Word; Valid : Boolean; Done : Boolean; (**************************************************************************** * * * FUNCTION: Cal * * * * PURPOSE: Calibrate * * * * INPUT: Value and channel * * * * OUTPUT: Calibrated value * * * ****************************************************************************) Function Cal(InValue: Word; Ch: Word) : Word; var a, b: byte; OutValue: Word; begin a:=Port[EBase+((ch*2)+(Port[EBase+240+ch]*32))+1]; b:=Port[EBase+((ch*2)+(Port[EBase+240+ch]*32))]; OutValue:=Round(((4095.0-a-b)/4095.0)*InValue+b); Cal:=OutValue; end; {*-------------------------------------------------------------------- * Function Deci * * Convert a hex string into a decimal word. *-------------------------------------------------------------------} Function Deci(DS : String) : Word; var BS : String; Er : Integer; DI : Word; begin BS := '$' + DS; Val(BS, DI, Er); Deci := DI; end; {*-------------------------------------------------------------------- * Function Hex * * Convert a decimal word into a hex string. *-------------------------------------------------------------------} Function Hex(BB : Word) : String; var AA, CC : Byte; DD : String; HexTable : String; begin HexTable := '0123456789ABCDEF'; DD := '000'; DD[3] := HexTable[(BB AND $00F) + 1]; DD[2] := HexTable[((BB AND $0F0) SHR 4) + 1]; DD[1] := HexTable[((BB AND $F00) SHR 8) + 1]; Hex := DD; end; {*-------------------------------------------------------------------- * Procedure AskForBaseAddress * * Prompt user to enter the base address for their I/O card. *-------------------------------------------------------------------} 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 } function AskForCalBaseAddress(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)'); 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); AskForCalBaseAddress := Dummy; end; { end of AskForBaseAddress } {*-------------------------------------------------------------------- * Procedure Intro * * Present user with introductory information and prompt for I/O * card's base address. *-------------------------------------------------------------------} Procedure Intro; begin clrscr; Writeln('Sample 3 DA12-16 '); Writeln; Writeln('Sample program demonstrating mode changes for the DA12-16'); writeln; writeln; writeln; writeln('Please press ENTER to set base addresses.'); readln; ClrScr; Base := AskForBaseAddress('$300'); Writeln; EBase := AskForCalBaseAddress('$300'); ClrScr; end; { of Intro } {*-------------------------------------------------------------------- * Procedure OutputValue * * Output a specified DAC count value to a specified channel. *-------------------------------------------------------------------} Procedure OutputValue(ch : Byte; Value : Word); begin PortW[Base + (ch*2)] := Cal(Value, ch); end; { of OutputValue } {*-------------------------------------------------------------------- * Main Program *-------------------------------------------------------------------} Begin Intro; ClrScr; Writeln; Writeln('Turbo Pascal sample for the DA12-16.'); Writeln; Writeln('Sample assumes ñ 5 volt range on all DACs'); Writeln; Writeln; Writeln('Do you wish to perform a hardware-reset clear?'); Writeln; Writeln(' Answer "Y" if the card has just been powered up,'); Writeln(' or "N" if this has already been performed since '); Writeln(' the last reset.'); Writeln; Write('Reset? '); Repeat Key := UpCase(ReadKey); Until Key in ['Y','N']; if Key = 'Y' then begin for Channel := 0 to 15 do OutputValue(Channel, $800); { Note: $000 if in a unipolar mode (per channel). } { Be aware that OutputValue does not neccessarily } { update the outputs. In this particular case, it } { does not. The card powers up in Simultaneous } { Update mode, therefore output command is not } { reflected in the voltages until after an update } { command is issued, as in the next line. } PortVal := PortW[Base + 10]; { Release zero latch } PortVal := PortW[Base + 15]; { This command updates the outputs, and terminates } { Simultaneous Update mode. We could have stayed in } { Simultaneous Update mode and still have updated the } { outputs using Base+8 instead of Base+10. } ClrScr; Writeln('All of the outputs have been updated with bipolar zero ($800).'); Writeln('Assuming a power-on condition, nothing should have changed.'); Writeln('Incidentally, any channels that are in a unipolar range'); Writeln('should have simultaneously changed to their half scale values'); Writeln('(i.e. unipolar 10v would read 5v).'); end; { of if Key is 'Y' } ClrScr; Writeln; Writeln('Press any key to output 2« volts on all channels, non-simultaneously'); Key := ReadKey; { Exit Simultaneous mode (offset 10 would also work) } PortVal := PortW[Base + 2]; for Channel := 0 to 15 do OutputValue(Channel, $C00); { Return to Simultaneous mode } PortVal := PortW[Base + 0]; { These setttings don't do anything -- yet! } for Channel := 0 to 15 do OutputValue(Channel, $FFF); ClrScr; Writeln('All channels have had the value $FFF written to them but'); Writeln('their outputs do not change. Press any key to initiate'); Writeln('simultaneous update of all channels. All channel outputs'); Writeln('will simultaneously change to +4.9998v DC'); { Wait for user response } Key := ReadKey; { Update outputs and place card in Simultaneous Update mode } PortVal := PortW[Base + 8]; Writeln; Writeln('All channels have been updated to full scale values.'); Key := ReadKey; { Note that we do not issue a Simultaneous Update mode read } { command -- we're still in Simultaneous Update mode from } { above. } { These commands do not affect output yet } for Channel := 0 to 3 do OutputValue(Channel*2 + 1, $000); ClrScr; Writeln('Channels 1,3,5,7 have been written to with $000 but'); Writeln('their outputs have not yet changed.'); Writeln; Writeln('Press any key to update channels 1,3,5,7 to -5v simultaneously'); Key := ReadKey; { Update and remove from Simultaneous mode } PortVal := PortW[Base + 10]; Writeln; Writeln('Channels 1,3,5,7 should have changed now.'); Writeln; Writeln; Writeln('Press any key to continue ... '); Key := ReadKey; repeat ClrScr; Writeln('Program will now permit you to enter a DAC count value'); Writeln('for output on a specified channel.'); Writeln; Valid := False; while Not Valid do begin Write('Enter channel for output (0..15): '); Readln(Channel); if Channel in [0..15] then Valid := True else begin Sound(600); Delay(400); NoSound; end; end; Valid := False; while Not Valid do begin Write('Enter DAC count value (0..4095): '); Readln(PortVal); if (PortVal >= 0) And (PortVal <= 4095) then Valid := True else begin Sound(600); Delay(400); NoSound; end; end; OutputValue(Channel, PortVal); Writeln; Writeln('Channel ', Channel, ' set to count value ', PortVal); Writeln; Writeln('Press ENTER to quit, any other key to continue ...'); Key := ReadKey; if Key = #13 then Done := True until Done; End. { of program }