(1) install advantech 32-bit dll...
TRANSCRIPT
(1) Install Advantech 32-bit DLL driver
Introduction to 32-bit High Speed DLL Driver V1.xx for
Windows NT and Windows 95
How to install 32-bit DLL driver
Please follow below procedure to install Advantech 32-bit DLL Driver and setup a supported device in the driver for your first time.
(1) When you download the 32-bit driver from Advantech WWW server, www.advantech-usa.com/techhome/tech1.htm. In tech1.htm page, there is a list of driver for each product. As you get any file from above server, please unzip the file before you install.
DLL3295.100
: Advantech Driver for Windows 95 Ver 1.00
DLL32NT.100
: Advantech Driver for Windows NT Ver 1.00
The driver supports 32-bit Operating System environment, Windows 95/NT, and 100 means the version number of Advantech 32-bit DLL driver. It is in ZIP file format which needs to be uncompressed by any available WINZIP utility. Because the default file type for WINZIP is ZIP, you should use full filename in the command line. For example,
Pkunzip -d DLL32NT.100
(2) After you unzip the 32-bit DLL driver, please use SETUP.EXE on /DISK1 directory to install the driver. When it comes to below diagram, you should select correct Operating System for your current working PC.
(3)
devinst.exe
devinst.exe
After you finish the driver installation, you should run Device Installation (DEVINST.EXE) under Advantech Driver for NT (for Windows NT) / Advantech Driver for 95 folder to setup supported devices. Please refer to DEVINST.HLP for more information.
(4) The necessary files for programming:
Below files are located in \Program Files\Advantech\Adsapi\ directory after you install 32-bit DLL driver for Windows 95/NT.
\DEVINST.EXE: To install any supported device for Advantech 32-bit DLL driver.
\MANUAL.DOC: Users Manual for Advantech 32-bit DLL driver.
\Examples\VC\LIB\ADSAPI32.LIB: Header library of ADSAPI32.DLL for Visual C++.
\Examples\BC\LIB\ADSAPIBC.LIB: Header library of ADSAPI32.DLL for Borland C++.
\Examples\BCB\LIB\ADSAPIBC.LIB: Header library of ADSAPI32.DLL for Borland C++ Builder.
\Include \DRIVER.H: Header file for Visual C++, Borland C++ /Builder.
\Include \OS.H: Header file for Visual C++, Borland C++ /Builder.
\Include \DRIVER.PAS: Header library of ADSAPI32.DLL for Borland Delphi.
\Include \DRIVER.BAS: Header library of ADSAPI32.DLL for Visual Basic.
How to install device through Device Installation
Please follow below procedure to setup any Advantech DA&C products.
(1) Launch Device Installation to setup any supported device. You will see below diagram as you launch it.
(2) Select Device... item from Setup menu, it will shows below I/O Device Installation dialog. Press Add>> button to show lists of device and press Install button to add a device.
(3) Here is an example to setup PCL-818L. When you run into any trouble while setting the device, please press Help button for advanced help.
(4) The Device Installation Utility will start up the device driver automatically under Windows NT. But you must make sure that you dont run any application program which is accessing the Device Registry (using DRV_DeviceOpen () function to open any supported device) as you launch this utility. For safety, please close any program using Advantech 32-bit DLL driver before you launch Device Installation Utility. Now it is ready for coding.
(5) The Device Installation Utility will start up the device driver automatically.
Registry of Advantech 32-bit DLL driver
The following is the registry of Advantech 32-bit DLL driver, please take a look by using REGEDIT utility to find its path:
Note: If you are not familiar with Windows NT device configuration, you are not adviced to change registry data. Device installation will configure the default data for each registry. If you want to change it, it will be better to save the default data at another file.
For the detailed information of DLL drivers setup, you can refer to Windows NT Registry. DLL Drivers create file associate ADSxxx in Registry. To access Registry information, please execute Regedit.exe in Windows directory. After executing Regedit.exe, you can access DLL drivers data through the following path:
Windows 95/NT Registry Keys Layout
HKEY_LOCAL_MACHINE(SYSTEM ( CurrentControlSet ( Services ( ADSDAQ
For example:
1. ADSDAQ key is used for all devices
Key location for Windows 95/NT:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ ADSDAQ
2. ADS818S key is used for PCL-818 series
Key location for Windows 95/NT:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ADS818S
Select hardware related Key Name in the listing at the left side of REGEDIT dialog, please refer to the following figure:
How to compile in Mircosoft Visual C++ V2.0 or above?
(1) Please new a Project which you should set it in using class library.
(2) Import \Program Files\Advantech\Examples\VC\LIB\ADSAPI32.LIB.
(3) Add your filename of source code into this project.
How to compile in Borland C++ Builder, Borlanc C++ V5.0 or above?
(1) Please new a Project which you should set it in using class library, dont use OWL.
(2) Import \Program Files\Advantech\Examples\BC\LIB\ADAPIBC.LIB for Borland C++ or \Program Files\Advantech\Examples\BCB\LIB\ADAPIBC.LIB for Borland C++ Builder. The Header Libraries for BC++/BC++ Builder are the same, but it is different from the .LIB file for VC++. If you want to call to any DLL by BC++/BC++ Builder, you can apply IMPLIB utility to create new .LIB files.
Syntax: IMPLIB [options] libname[.lib] dllname[.dll]
Example:
1) IMPLIBC:\Program Files\Advantech\Adsapi\Examples\BC\LIB \ADSAPIBC.LIB
C:\WinNT\ADSAPI32.DLL
2) IMPLIBC:\Program Files\Advantech\Adsapi\Examples\BC\LIB \ADSAPIBC.LIB C:\Windows\ADSAPI32.DLL
(3) Add your filename of source code into this project.
(4) You configure the Data Alignment to Quad Word (8-Byte) in the Processor item of 32-bit Compiler setup of Project Options. Because the default Data Alignment of Visual C++, Visual Basic and Delphi are in Quad Word (8-Byte), you dont have to change the configuration in those programming language environment.
How to compile in Mircosoft Visual Basic V4.0 or above?
(1) Please new a Project which you should set it in using class library.
(2) Add \Include\DRIVER.BAS into this project.
(3) Add your filename of source code into this project.
How to compile in Borland Delphi V2.0 or above?
(1) Please Open a Project which you should set it in using class library.
(2) Add \Include\DRIVER.PAS into this project.
Add your filename of source code into this project.
(3) A table of DLL drivers filename and its supported devices.
No.
Supported Hardware
File Name
Device Driver
Key Names in Registry
1
PCL-818 series
ADS818.DLL
ADS818S.SYS
ADS818S.VxD
ADS818S
2
PCL-711S
ADS711.DLL
ADS711S.SYS
ADS711S.VxD
ADS711S
3
PCL-812PG
ADS812.DLL
ADS812S.SYS
ADS812S.VxD
ADS812S
4
PCL-813B
ADS813.DLL
ADSIO.SYS
ADSIO.VxD
ADSIO
5
PCL-816
ADS816.DLL
ADS816S.SYS
ADS816S.VxD
ADS816S
6
PCL-1800
ADS1800.DLL
ADS1800S.SYS
ADS1800S.VxD
ADS1800S
7
PCL-726/727/728
ADS726.DLL
ADSIO.SYS
ADSIO.VxD
ADSIO
8
PCL-720/722/724/725
ADSDIO.DLL
ADSIO.SYS
ADSIO.VxD
ADSIO
9
PCL-730/731/733/734/735
ADSDIO.DLL
ADSIO.SYS
ADSIO.VxD
ADSIO
10
ADAM-4000 series
ADS4000.DLL
ADSDAQ
11
ADAM-5000/485 series
ADS5000.DLL
ADSDAQ
12
PCL-833
ADS833.DLL
ADSIO.SYS
ADSIO.VxD
ADSIO
13
MIC-2000 series
ADSMIC.DLL
ADSMICS.SYS
ADSMICS.VxD
ADSMICS
14
PCM-3680/3718/3724/3730
ADSPCM.DLL
ADSPCMS.SYS
ADSPCMS.VxD
ADSPCMS
15
Virtual DEMO I/O board
ADSDEMO.DLL
ADSDAQ
16
RS-232 COM Port
ADSCOMM.DLL
ADSDAQ
17
PCL-836
ADS836.DLL
ADSIO.SYS
ADSIO.VxD
ADSIO
18
PCL-841
ADS841.DLL
ADS841S.SYS
ADS841S.VxD
ADS841S
19
ADAM-5000/DeviceNet
ADSDN5K.DLL
ADS841S.SYS
ADS841S.VxD
ADS841S
20
Direct I/O for unlisted I/O Board
ADSIO.DLL
ADSIO.SYS
ADSIO.VxD
ADSIO
The files in .DLL type contains Advantech API functions for application program to call to. You can find ADSAPI32.DLL in \Windows directory and the other .DLL files \Windows\System directories for Windows 95, ADSAPI32.DLL in \WINNT directory and the other .DLL files in \WINNT\SYSTEM32 directories for Windows NT.
The files in .SYS type are Device Driver for Windows NT. You can find the files in \WINNT\SYSTEM32\Drivers.
The files in .VxD type are Device Driver for Windows 95. You can find the files in \Windows\SYSTEM.
Report for Advantech 32-bit DLL Driver for Windows 95/NT Version 1.0
1. Functions of Polling mode method test (PC-Lab cards)
Functions
Product Name
Analog Input
Analog Output
Digital Input
Digital Output
Counter / Qcounter
Frequency
Pulse Output
DEMO Board
Sine Wave (0)
Saw Tooth (1)
( (Simulation)
( (Simulation)
MIC-2718
(
MIC-2728
(
MIC-2730/2732
(
MIC-2750/2752
( (Isolation)
PCIA-71A/B
No Solution(NT)
No Solution(NT)
No Solution(NT)
PCIA-71C
No Solution(NT)
No Solution(NT)
No Solution(NT)
PCL-1800
(
(
( (TTL)
( (TTL)
PCL-711/711B
(
(
( (TTL)
( (TTL)
PCL-718/818
(
(
( (TTL)
( (TTL)
PCL-720
( (TTL)
( (TTL)
(
(
(
PCL-721
?
?
?
?
?
?
?
PCL-722
(
(8255 Mode 0)
(
(8255 Mode 0)
PCL-723
?
?
?
?
?
?
?
PCL-724
(
(8255 Mode 0)
(
(8255 Mode 0)
PCL-725
(
(Photo Couple)
(
(Relay Out)
PCL-726
(
(
(
PCL-727
(
PCL-728
(
PCL-730
( (Isolation)
( (TTL)
( (Isolation )
( (TTL)
PCL-731
(
(8255 Mode 0)
(
(8255 Mode 0)
PCL-733
( (Isolation)
PCL-734
( (Isolation)
PCL-735
( (Relay Out)
PCL-812/812PG
(
(
( (TTL)
( (TTL)
(
(
(
Functions
Product Name
Analog Input
Analog Output
Digital Input
Digital Output
Counter / Qcounter
Frequency
Pulse Output
PCL-813B/813
(
PCL-816
(
(
(TTL on board)
( (8255 Mode)
(
(TTL on board)
( (8255 Mode)
PCL-818H
(
(
( (TTL)
( (TTL)
(
(
(
PCL-818HD
(
(
( (TTL)
( (TTL)
(
(
(
PCL-818HG
(
(
( (TTL)
( (TTL)
(
(
(
PCL-818L
(
(
( (TTL)
( (TTL)
(
(
(
PCL-830
PCL-833
( (Isolation, Differential) #
(
PCL-836
(
(
(
(
(
PCM-3718
(
( (TTL)
( (TTL)
PCM-3724
( (8255 Mode)
( (8255 Mode)
PCM-3730
( (Isolation)
( (TTL)
( (Isolation )
( (TTL)
How to test the functions of Polling mode method:
Analog Input (Single or Multiple channels, +/-10V, +/-5V, +/-2.5V and 0V)
Analog Output (+/-10V, +/-5V, +/-2.5V and 0V)
Digital Input (Isolation / TTL mode / 8255 mode)
Digital Output (Isolation / TTL mode / 8255 mode)
Counter / QCounter
Frequency
Pulse Output
Perform multiple functions on one specific card at the same time
Test AI/AO, DI/DO and Counter/Frequency/Pulse Out functions on each card of different I/O address (Hex 200 or Hex 300)
Test AI/AO, DI/DO and Counter/Frequency/Pulse Out functions on two card of same model with different I/O address (Hex 200 and Hex 300)
Test AI/AO, DI/DO and Counter/Frequency/Pulse Out functions on two cards of different model with different I/O address (Hex 200 and Hex 300)
2. Functions of Polling mode method test (ADAM /RS-485 modules)
Functions
Product Name
Analog Input
Analog Output
Digital Input
Digital Output
Counter
Temp/RTD
Alarm
ADAM-4011
(
(
(
(
( (T/C)
(
ADAM-4012
(
(
(
ADAM-4013
(
(T/C and RTD)
ADAM-4014D
(
(
(
(
(
ADAM-4016
(
(
(
ADAM-4017
(
(Strain Gauge)
(
(
ADAM-4018(M)
( (T/C)
ADAM-4021
(
ADAM-4050
(
(
ADAM-4052
(
ADAM-4053
(
ADAM-4060
(
(
ADAM-4080(D)
(
(
(
ADAM-5017
(
(
ADAM-5018
(
( (T/C)
(
ADAM-5024
(
ADAM-5050
(
(
ADAM-5051
(
ADAM-5052
(
ADAM-5056
(
ADAM-5060
(
How to test the functions of Polling mode method:
Analog Input
Analog Output
Digital Input (Isolation / Relay Output)
Digital Output (Isolation )
Counter / Frequency
Thermocouple (Temperature)
Alarm
Perform multiple functions on one specific ADAM module at the same time
Test AI/AO, DI/DO, Counter, Temp/RTD and Alarm functions on different ADAM modules with different I/O address (Hex 01, Hex 02)
Test AI/AO, DI/DO, Counter, Temp/RTD and Alarm functions on different ADAM modules with different I/O address (Hex 01, Hex 02)
Test AI/AO, DI/DO, Counter, Temp/RTD and Alarm functions on different ADAM modules with different I/O address (Hex 01, Hex 02)
Test ADAM module in different BAUD rate, 300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600 or 115200. (the 57600 and 115200 BAUD rate can be used for ADAM-5000 serial module only)
3. Functions of Interrupt/DMA mode method test
Functions
Product Name
INT/AI
INT/AI
DMA/AI
DMA/MAI
INT with FIFO/AI
INT/AO
PCL-711
(
(
PCL-812PG
(
(
(
(
PCL-718/818
(
(
(
(
PCL-816
(
(
(
(
PCL-818H
(
(
(
(
PCL-818HD
(
(
(
(
(
PCL-818HG
(
(
(
(
(
PCL-818L
(
(
(
(
How to test the functions of Interrupt/DMA mode method:
INT/AI Analog Input (+/-10V, +/-5V, +/-2.5V and 0V)
INT/AI Analog Output (+/-10V, +/-5V, +/-2.5V and 0V)
DMA/AI Digital Input (+/-10V, +/-5V, +/-2.5V and 0V)
DMA/MAI Digital Output (+/-10V, +/-5V, +/-2.5V and 0V)
Test INT/AI or INT/MAI Analog Input on each card of different I/O address (Hex 200 or Hex 300).
Test DMA/AI or DMA/MAI Analog Input on each card of different I/O address (Hex 200 or Hex 300).
Test INT/AI or INT/MAI Analog Input function by launch one identical program twice on two identical devices at the same time (test the INT detection while one INT is busy, one cannot access the INT once more)
Test INT/AI or INT/MAI Analog Input function by launch two programs on two identical or different devices of different IRQ at the same time (test the INT detection while one INT is busy, one cannot access the INT once more)
Test DMA/AI or DMA/MAI Analog Input function by launch one identical program twice on two identical devices at the same time (test the INT detection while one INT is busy, one cannot access the INT once more)
Test DMA/AI or DMA/MAI Analog Input function by launch two programs on two identical or different devices of different IRQ and DMA channel on two identical devices at the same time (test if use can use two DMA at the same time)
4. Functions of Interrupt/DMA mode method test
Functions
Product Name
INT/AI
INT/AI
DMA/AI
DMA/MAI
Conditional/
AI
Dual DMA/
AI
INT/AO
DMA/AO
PCL-1800
(
(
(
(
(
(
(
(
How to test the functions of Interrupt/DMA mode method:
INT/AI Analog Input (+/-10V, +/-5V, +/-2.5V and 0V)
INT/AI Analog Output (+/-10V, +/-5V, +/-2.5V and 0V)
DMA/AI Digital Input (+/-10V, +/-5V, +/-2.5V and 0V)
DMA/MAI Digital Output (+/-10V, +/-5V, +/-2.5V and 0V)
Test INT/AI or INT/MAI Analog Input on each card of different I/O address (Hex 200 or Hex 300).
Test DMA/AI or DMA/MAI Analog Input on each card of different I/O address (Hex 200 or Hex 300).
Test INT/AI or INT/MAI Analog Input function by launch one identical program twice on two identical devices at the same time (test the INT detection while one INT is busy, one cannot access the INT once more)
Test INT/AI or INT/MAI Analog Input function by launch two programs on two identical or different devices of different IRQ at the same time (test the INT detection while one INT is busy, one cannot access the INT once more)
Test DMA/AI or DMA/MAI Analog Input function by launch one identical program twice on two identical devices at the same time (test the INT detection while one INT is busy, one cannot access the INT once more)
Test DMA/AI or DMA/MAI Analog Input function by launch two programs on two identical or different devices of different IRQ and DMA channel on two identical devices at the same time (check if user can use two DMA at the same time)
Watchdog Timer test
5. Functions of INT/DI test
Functions
Product Name
INT/DI
PCL-722
(
PCL-724
(
PCL-731
(
PCL-733
(
PCL-833
(
PCL-836
(
Unlisted Board
(
I/O range:
0000~FFFF
How to test the functions of Interrupt mode method:
Digital with interrupt
Test Digital with interrupt on each card of different I/O address (Hex 200 or Hex 300).
Test Digital with interrupt by launch one identical program twice on two identical devices at the same time (test the INT detection while one INT is busy, one cannot access the INT once more)
6. Functions of CAN-Open and Device-Net protocol test for ADAM/CAN module through MIC-2630, PCL-841 or PCM-3680 CAN interface card
Functions
Product Name
Analog Input
Temp/RTD
Analog Output
Digital Input
Digital Output
Event AI
Event DI
Multiple Event
Polling Event
ADAM-5050
ADAM-5052
How to test the functions of Interrupt/DMA mode method:
7. MAX speed for INT/DMA functions on Advantech product
Functions
Product Name
INT/AI
DMA/AI
INT with FIFO/AI
INT/AO
DMA/AO
INT/DI
MIC-2718
40KHz
100KHz
100KHz
PCL-711
25KHz
PCL-812PG
30(KHz
30KHz
PCL-718/818
40KHz
100KHz
PCL-816
40KHz
100KHz
40KHz
100KHz
PCL-818H
40KHz
100KHz
PCL-818HD
40KHz
100KHz
100KHz
PCL-818HG
40KHz
100KHz
100KHz
PCL-818L
40KHz
40KHz
PCL-1800
40KHz
200KHz
330KHz
40KHz
200KHz
PCL-722
35KHz
PCL-724
35KHz
PCL-731
35KHz
PCL-733
35KHz #
PCL-833
35KHz
PCL-836
35KHz
PCM-3718
40KHz
40KHz
PCM-3724
35KHz
PCM-3730
35KHz
Unlisted Board
35KHz
The hardware for above test
CPU
(Pentium MMX 200
RAM
( 64 Mbytes
Mother Board(Advantech MIC-2350 (A) / ASUS TX-97 (B)
Test Utility
((1) INT/AI, DMA/AI and INT with FIFO/AI functions are tested by MDIAPP.EXE program
(2) INT/AO and DMA/AO functions are tested by \Examples\VC\AO.INT\DAINT and \Examples\VC\AO.DMA\DADMA program. This test should apply a Oscilloscope to check the Analog output.
(3) INT/DI function is tested by \Examples\VC\FDIGIN\Fdigin.EXE program
How can we check the Analog Input with Interrupt/DMA transfer?
We try to increase the frequency of TTL signal from Function Generator step by step to make the CPU usage in 50%, then record the frequency of TTL signal.
For those card with Isolation features, you can connect the TTL signal to IRQ jumper directly.
To get the MAX Analog Input Sampling rate, you should set GAIN = 1.
You should set the CLK = 10MHz when check PCL-1800 at 200KHz sampling rate or above.
How can we check the Analog Output with Interrupt/DMA transfer?
Connect the Analog Output signal to one Oscilloscope to check the waveform and amplitude of signal directly, there are SINE, TRIANGLE and SQUARE waveform in the example program.
How can we check the Digital Input with Interrupt?
We try to increase the frequency of TTL signal from Function Generator step by step to make the CPU usage in 50%, then record the frequency of TTL signal. Please also refer to the Performance Monitor diagram on next page.
For those cards with Isolation feature, you can connect the TTL signal to IRQ jumper directly or the input signal should be enough (5V ~ 40V) to produce an Interrupt.
You can find below utility from Start ( Administrative Tools (Common) ( Performance Monitor
The functions must be called in order, as shown in the following flow charts.
Function Flow Chart
All device-specific drivers flow chart
Fig 2-3
P.19
Analog input flow chart
Fig 2-4
P.20~21
Analog output flow chart
Fig 2-5
P.22
Digital I/O flow chart
Fig 2-6
P.23~24
Event counter flow chart
Fig 2-7
P.19
Frequency measurement flow chart
Fig 2-8
P.20~21
Pulse output flow chart
Fig 2-9
P.22
Quadratic counter flow chart
Fig 2-10
P.23~24
Alarm operations flow chart
Fig 2-11
P.19
Analog input for single channel data acquisition with interrupt transfer
Fig 2-12
P.20~21
Analog input for single channel data acquisition with interrupt transfer and event function
Fig 2-12-A
P.22
Analog input for single channel data acquisition with DMA transfer
Fig 2-13
P.23~24
Analog input for single channel data acquisition with DMA transfer and event function
Fig 2-13-A
P.19
Analog input for multiple channel data acquisition with interrupt transfer
Fig 2-14
P.20~21
Analog input for multiple channel data acquisition with interrupt transfer and event function
Fig 2-14-A
P.22
Analog input for multiple channel data acquisition with DMA transfer
Fig 2-15
P.23~24
Analog input for multiple channel data acquisition with DMA transfer and event function
Fig 2-15-A
P.19
Analog input for multiple channel watchdog with interrupt transfer
Fig 2-16
P.20~21
Analog input for multiple channel watchdog with interrupt transfer and event function
Fig 2-16-A
P.22
Analog input for multiple channel watchdog with DMA transfer
Fig 2-17
P.23~24
Analog input for multiple channel watchdog with DMA transfer
and event function
Fig 2-17-A
P.19
Analog output for single channel with DMA transfer
Fig 2-18
P.20~21
Analog output for single channel with DMA transfer and event function
Fig 2-18-A
P.22
Analog output for single channel with interrupt transfer
Fig 2-19
P.23~24
Analog output for single channel with interrupt transfer and event function
Fig 2-19-A
P.23~24
The structure of the Demo Program
All device-specific drivers flow chart:
Fig 2-3. Function Flow Overview
DRV_DeviceGetList() ( Get the configuration information of device, not including the attached devices on COM port or CAN, from Windows System Registry, and the Device Number (The number in the first column which you can see through Device Installation utility) can be applied for DRV_DeviceOpen().This function, DRV_DeviceOpen(), retrieves parameters pertaining to the devices operation from the Registry or configuration file, and allocate memory to store it for quick reference. This function returns a Driver Handle (second parameter) which pointers to the configuration for calling any other functions before it calls the DRV_DeviceClose() function. After the I/O operations, user has to call DRV_DeviceClose to release the memory allocated by DRV_DeviceOpen.
In the Function Group, you can call any supported function which is necessary for your application, please also refer to the following Flow Diagram for each feature for your applied board. If you cannot make sure that if the calling function is supported for the specific card or not, you can refer to MANUAL.DOC for more information.
When your program call to those functions in Function Group, it will call to the function in specific .DLL file. For example, when you open a PCL-818HG device
The calling flow in your program
DRV_DeviceOpen ( DRV_AIConfig ( DRV_AIVoltageIn ( DRV_DeviceClose
The calling flow inside the DLL driver
DRV_DeviceOpen() (ADSAPI32.DLL) ( DeviceOpen() (ADS818.DLL) ( DRV_AIConfig() (ADSAPI32.DLL) ( AIConfig() (ADS818.DLL) ( ADS818.SYS ( Access the register on Hardware ( DRV_AIVoltageIn() (ADSAPI32.DLL) ( AIVoltageIn() (ADS818.DLL) ( ADS818.SYS ( Access the register on Hardware ( DRV_DeviceClose() (ADSAPI32.DLL) ( DeviceClose() (ADS818.DLL)
Analog Input Flow Chart:
Fig 2-4. Function Flow Overview
For Single Channel
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *)&DriverHandle);
// Configures the gain for the specific analog input channel
// Gain Code or Input Range, Please refer to Hardware Users Manual for more information
ptAIConfig.DasGain = usGainCde;
ptAIConfig.DasChan = gwChannel;
// 2nd Step: Call to DRV_AIConfig() function to configure the Analog input channel and its Gain Code
if ((ErrCde = DRV_AIConfig(DriverHandle, (LPT_AIConfig) &ptAIConfig)) != 0)
{
// If any error happen, please call below function to get the error message for the Error Code, ErrCde.
DRV_GetErrorMessage(ErrCde, (LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Driver Message",MB_OK);
// You should call the DRV_DeviceClose() function whenever it exits the appliaction
DRV_DeviceClose((LONG far *) &DriverHandle);
return 0;
}
// Analog Iiput channel
ptAIVoltageIn.chan = gwChannel;
// Gain Code or Input Range, Please refer to Hardware Users Manual for more information
ptAIVoltageIn.gain = usGainCde;
// 0 for internal trigger, 1 for external trigger
ptAIVoltageIn.TrigMode = 0;
// ptAIVoltageIn.voltage keeps the address of fVoltage where the driver store the analog input value.
// In Delphi, you can use @ operator.
// In Visual Basic, please use DRV_GetAddress(parameter) function to return the parameters
// address.
ptAIVoltageIn.voltage = (FLOAT far *) &fVoltage;
// 3rd Step: Call to DRV_AIVoltageIn () function to get analog input value
if ((ErrCde = DRV_AIVoltageIn(DriverHandle, (LPT_AIVoltageIn) &ptAIVoltageIn)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
KillTimer(hWnd, 1);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Driver Message",MB_OK);
// You should call the DRV_DeviceClose() function whenever it exits the appliaction
DRV_DeviceClose((LONG far *)&DriverHandle);
return 0;
}
// 4th Step : When you want to exit the I/O, please call to DRV_DeviceClose() function
DRV_DeviceClose((LONG far *) &DriverHandle);
For Multiple Channels
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *)&DriverHandle);
// Gain Code or Input Range, Please refer to Hardware Users Manual for more information
ptMAIConfig.NumChan = usStopChan - usStartChan + 1;
ptMAIConfig.StartChan = usStartChan;
// Configures the gain list for the each analog input channel
for (i=0 ; i< ptMAIConfig.NumChan ; i++)
usGainCode[i+usStartChan] = DevFeatures.glGainList[usGainIndex[i+usStartChan]].usGainCde;
ptMAIConfig.GainArray = (USHORT far *) &usGainCode[usStartChan];
// 2nd Step: Call to DRV_MAIConfig() function to configure the multiple Analog input channels and its
// Gain Code
if ((ErrCde = DRV_MAIConfig(DriverHandle, (LPT_MAIConfig) &ptMAIConfig)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Driver Message",MB_OK);
DRV_DeviceClose((LONG far *)&DriverHandle);
return 0;
}
ptMAIVoltageIn.NumChan = usStopChan - usStartChan + 1;
ptMAIVoltageIn.StartChan = usStartChan;
for (i=0 ; i< ptMAIVoltageIn.NumChan ; i++)
usGainCode[i+usStartChan] = DevFeatures.glGainList[usGainIndex[i+usStartChan]].usGainCde;
ptMAIVoltageIn.GainArray = (USHORT far *) &usGainCode[usStartChan];
ptMAIVoltageIn.TrigMode = 0; // internal trigger
ptMAIVoltageIn.VoltageArray = (FLOAT far *)&fVoltage[usStartChan];
// 3rd Step: Call to DRV_MAIVoltageIn () function to get analog input value
if ((ErrCde = DRV_MAIVoltageIn(DriverHandle, (LPT_MAIVoltageIn)&ptMAIVoltageIn)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Driver Message",MB_OK);
KillTimer(hWnd, 1);
DRV_DeviceClose((LONG far *)&DriverHandle);
return 0;
}
// 4th Step : When you want to exit the I/O, please call to DRV_DeviceClose() function
DRV_DeviceClose((LONG far *) &DriverHandle);
Analog Output Flow Chart:
Fig 2-5. Function Flow Overview
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *)&DriverHandle);
ptAOConfig.chan = gwChannel;
ptAOConfig.MaxValue = 5.0;// Identical to the jumper setting on board
ptAOConfig.MinValue = 0.0;
// 2nd Step: Call to DRV_AOConfig() function to configure the analog output channel
// Please dont call to DRV_AOConfig() for ADAM modules, or it will return Error Message
if ((ErrCde = DRV_AOConfig(DeviceHandle, ptAOConfig)) != 0)
{
DRV_GetErrorMessage(ErrCde, (LPSTR)szErrMsg);
MessageBox(hWnd, (LPCSTR)szErrMsg, "Driver Message",MB_OK);
DRV_DeviceClose((LONG far *) &DriverHandle);
return 0;
}
ptAOVoltageOut.chan = gwChannel;
ptAOVoltageOut.OutputValue = fData;// The output voltage value
// 3rd Step: Call to DRV_ AOVoltageOut () function to perform analog output
if((ErrCde = DRV_AOVoltageOut(DriverHandle, (LPT_AOVoltageOut) &ptAOVoltageOut)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
KillTimer(hWnd, 1);
MessageBox(hWnd, (LPCSTR)szErrMsg, "Driver Message", MB_OK);
return TRUE;
}
// 4th Step : When you want to exit the I/O, please call to DRV_DeviceClose() function
DRV_DeviceClose((LONG far *) &DriverHandle);
Digital Input /Output Flow Chart:
Fig 2-6. Function Flow Overview
For Digital Input
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
// For those digital I/O cards in 8255 Mode 0, such as PCL-722, PCL-724 and so on, to set up I/O
// direction dynamically. If you dont execute the DRV_DioSetPortMode function for above cards, it
// works as the setup in Device Installation utility.
// Bit 0 ~ Bit 7 ( Port 0
// Bit 8 ~ Bit 15 ( Port 1
// Bit 16 ~ Bit 31 ( Port 2
// .
lpDioPortMode.port := gwPort;
lpDioPortMode.dir := INPORT;// Set the specific port as Input Port
// 2nd Step: Call to DRV_DioSetPortMode() function to configure the mode of Digital I/O channel
// dynamically. This function affect those digital I/O cards in 8255 Mode 0 only.
// If you dont call to DRV_DioSetPortMode() function, the mode of Digital I/O channel will be identical to
// the setup in Device Installation utility.
if ((ErrCde = DRV_DioSetPortMode(DeviceHandle, lpDioPortMode)) != 0)
{
DRV_GetErrorMessage(ErrCde, (LPSTR)szErrMsg);
KillTimer(hWnd, 1);
MessageBox(hWnd, (LPCSTR)szErrMsg, "Driver Message", MB_OK);
return TRUE;
}
ptDioReadPortByte.port = gwPort;
ptDioReadPortByte.value = (USHORT far *) &gwValue;
// 3rd Step: Read the digital input status
if ((ErrCde = DRV_DioReadPortByte(DriverHandle,
(LPT_DioReadPortByte) &ptDioReadPortByte)) != 0)
{
DRV_GetErrorMessage(ErrCde, (LPSTR) szErrMsg);
KillTimer(hWnd, 1);
MessageBox(hWnd, (LPCSTR) szErrMsg, "Driver Message", MB_OK);
return TRUE;
}
// 4th Step : When you want to exit the I/O, please call to DRV_DeviceClose() function
DRV_DeviceClose((LONG far *) &DriverHandle);
For Digital Output
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
// For those digital I/O cards in 8255 Mode 0, such as PCL-722, PCL-724 and so on, to set up I/O
// direction dynamically. If you dont execute the DRV_DioSetPortMode function for above cards, it
// works as the setup in Device Installation utility.
lpDioPortMode.port := gwPort;
lpDioPortMode.dir := OUTPORT;// Set the specific port as Output Port
// 2nd Step: Call to DRV_DioSetPortMode() function to configure the mode of Digital I/O channel
// dynamically. This function affect those digital I/O cards in 8255 Mode 0 only.
// If you dont call to DRV_DioSetPortMode() function, the mode of Digital I/O channel will be identical to
// the setup in Device Installation utility.
if ((ErrCde = DRV_DioSetPortMode(DeviceHandle, lpDioPortMode)) != 0)
{
DRV_GetErrorMessage(ErrCde, (LPSTR)szErrMsg);
KillTimer(hWnd, 1);
MessageBox(hWnd, (LPCSTR)szErrMsg, "Driver Message", MB_OK);
return TRUE;
}
ptDioWritePortByte.port = gwPort;
// Only those bits in 1 can be set ON/OFF. For example, you have mask equal 0x0F, then you can turn
// on Bit 0 ~ Bit 3
ptDioWritePortByte.mask = gwMask;
ptDioWritePortByte.state = gwData;
// 3rd Step: Write the digital output status
if((ErrCde = DRV_DioWritePortByte(DriverHandle,
(LPT_DioWritePortByte)&ptDioWritePortByte)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hDlg,(LPCSTR)szErrMsg,"Driver Message",MB_OK);
return 0;
}
// 4th Step : When you want to exit the I/O, please call to DRV_DeviceClose() function
DRV_DeviceClose((LONG far *) &DriverHandle);
Event Counter Flow Chart:
Fig 2-7. Function Flow Overview
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
ptCounterEventStart.counter = gwChannel;
// The GateMode parameter is for PCL-830 only.
ptCounterEventStart.GateMode = gwGateMode;
// 2nd Step: Call to DRV_CounterEventStart() to configure the specific counter channel of 8253/8254 on
// board for reading input pulse.
if((ErrCde = DRV_CounterEventStart(DriverHandle,
(LPT_CounterEventStart) &ptCounterEventStart)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg, "Driver Message", MB_OK);
return TRUE;
}
ptCounterEventRead.counter = gwChannel;
// the overflow state of the counter, 1 means overflow, otherwise 0
ptCounterEventRead.overflow = (USHORT far *) &gwOverflow;
ptCounterEventRead.count = (ULONG far *) &gdwReading;
// 3rd Step: Call to function DRV_CounterEventRead() to read the input pulse number.
if ((ErrCde = DRV_CounterEventRead(DriverHandle,
(LPT_CounterEventRead) &ptCounterEventRead)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
KillTimer(hWnd, 1);
MessageBox(hWnd,(LPCSTR) szErrMsg, "Driver Message", MB_OK);
DRV_DeviceClose((LONG far *) &DriverHandle);
return TRUE;
}
// 4th Step: Call to DRV_CounterReset() function to turns off the specified counter operation. This
// function supports boards with the timer/counter chip (i.e. Intel 8254 or AMD Am9513A) and PCL-833.
if( (ErrCde = DRV_CounterReset(DriverHandle,
(LPARAM) gwChannel)) != 0)
{
DRV_GetErrorMessage(ErrCde, (LPSTR) szErrMsg);
MessageBox(hWnd,(LPCSTR) szErrMsg, "Driver Message", MB_OK);
}
// 5th Step : When you want to exit the I/O, please call to DRV_DeviceClose() function
DRV_DeviceClose((LONG far *) &DriverHandle);
Frequency Measurement Flow Chart:
Fig 2-8. Function Flow Overview
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
ptCounterFreqStart.counter = gwChannel;
// gating period in seconds unit
ptCounterFreqStart.GatePeriod = gwGatePeriod;
// gating mode to be used for AMD Am9513A only
ptCounterFreqStart.GateMode = gwGateMode;
// 2nd Step: Call to DRV_CounterFreqStart() function to configure the specific counter channel of
// 8253/8254 on board for measuring the frequency of input signal.
if ((ErrCde = DRV_CounterFreqStart(DriverHandle,
(LPT_CounterFreqStart)&ptCounterFreqStart)) != 0)
{
DRV_GetErrorMessage(ErrCde, (LPSTR) szErrMsg);
MessageBox(hWnd,(LPCSTR) szErrMsg, "Driver Message", MB_OK);
return TRUE;
}
ptCounterFreqRead.counter = gwChannel;
ptCounterFreqRead.freq = (FLOAT far *)&gfFreq;
// 3rd Step: Call to DRV_CounterFreqRead() function to read the frequency of input signal
if ((ErrCde = DRV_CounterFreqRead(DriverHandle,
(LPT_CounterFreqRead)&ptCounterFreqRead)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg, "Driver Message", MB_OK);
return TRUE;
}
// 4th Step: Call to DRV_CounterReset() function to turns off the specified counter operation. This
// function supports boards with the timer/counter chip (i.e. Intel 8254 or AMD Am9513A) and PCL-833.
if( (ErrCde = DRV_CounterReset(DriverHandle,
(LPARAM) gwChannel)) != 0)
{
DRV_GetErrorMessage(ErrCde, (LPSTR) szErrMsg);
MessageBox(hWnd,(LPCSTR) szErrMsg, "Driver Message", MB_OK);
}
// 5th Step : When you want to exit the I/O, please call to DRV_DeviceClose() function
DRV_DeviceClose((LONG far *) &DriverHandle);
Pulse Output Flow Chart:
Fig 2-9. Function Flow Overview
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
ptCounterPulseStart.counter = gwChannel;
// total period in seconds
ptCounterPulseStart.period = gfGatePeriod;
// the first 1/2 cycle length in seconds
ptCounterPulseStart.UpCycle = gfUpCycle;
ptCounterPulseStart.GateMode = gwGateMode;
// 2nd Step: Call to DRV_CounterPulseStart() function to configure the specific counter channel of
// 8253/8254 on board and perform pulse output.
if((ErrCde = DRV_CounterPulseStart(DriverHandle,
(LPT_CounterPulseStart)&ptCounterPulseStart)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg, "Driver Message", MB_OK);
return TRUE;
}
// 3rd Step: Call to DRV_CounterReset() function to turns off the specified counter operation. This
// function supports boards with the timer/counter chip (i.e. Intel 8254 or AMD Am9513A) and PCL-833.
if( (ErrCde = DRV_CounterReset(DriverHandle, (LPARAM) gwChannel)) != 0)
{
DRV_GetErrorMessage(ErrCde, (LPSTR) szErrMsg);
MessageBox(hWnd, (LPCSTR) szErrMsg, "Driver Message", MB_OK);
}
// 4th Step : When you want to exit the I/O, please call to DRV_DeviceClose() function
DRV_DeviceClose((LONG far *) &DriverHandle);
Quadratic Counter Flow Chart:
Fig 2-10. Function Flow Overview
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
ptCounterPulseStart.counter = gwChannel;
// total period in seconds
ptCounterPulseStart.period = gfGatePeriod;
// the first 1/2 cycle length in seconds
ptCounterPulseStart.UpCycle = gfUpCycle;
ptCounterPulseStart.GateMode = gwGateMode;
// 2nd Step: Call to DRV_CounterPulseStart() function to configure the specific counter channel of
// 8253/8254 on board and perform pulse output.
if((ErrCde = DRV_CounterPulseStart(DriverHandle,
(LPT_CounterPulseStart)&ptCounterPulseStart)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg, "Driver Message", MB_OK);
return TRUE;
}
// 3rd Step: Call to DRV_CounterReset() function to turns off the specified counter operation. This
// function supports boards with the timer/counter chip (i.e. Intel 8254 or AMD Am9513A) and PCL-833.
if( (ErrCde = DRV_CounterReset(DriverHandle, (LPARAM) gwChannel)) != 0)
{
DRV_GetErrorMessage(ErrCde, (LPSTR) szErrMsg);
MessageBox(hWnd, (LPCSTR) szErrMsg, "Driver Message", MB_OK);
}
// 4th Step : When you want to exit the I/O, please call to DRV_DeviceClose() function
DRV_DeviceClose((LONG far *) &DriverHandle);
Alarm Operations Flow Chart:
Fig 2-11. Function Flow Overview
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
// 2nd Step: Configures the alarm limits
ptAlarmConfig.chan = gwChannel;
ptAlarmConfig.LoLimit = gfLoLimit;
ptAlarmConfig.HiLimit = gfHiLimit;
// 2nd Step: Configures the alarm limits
ErrCde = DRV_AlarmConfig(DriverHandle, (LPT_AlarmConfig) &ptAlarmConfig);
// enable alarm
ptAlarmEnable.chan = gwChannel;
ptAlarmEnable.LatchMode = gwLatchMode;
ptAlarmEnable.enabled = 1;
// 3rd Step: Enable alarm, this function will take some seconds (about 7 seconds) to re-program the
// High/Low Alarm setting of ADAM module.
ErrCde = DRV_AlarmEnable(DriverHandle, (LPT_AlarmEnable) &ptAlarmEnable);
// check alarm status
ptAlarmCheck.chan = gwChannel;
ptAlarmCheck.LoState = (USHORT far *)&gwLoState;
ptAlarmCheck.HiState = (USHORT far *)&gwHiState;
// 4th Step: Check the Alarm status
ErrCde = DRV_AlarmCheck(DriverHandle, (LPT_AlarmCheck) &ptAlarmCheck);
// 5th Step: Resets the alarm monitoring of the specified channel, send @AACA command to
// ADAM-4000 module, chan ( channel of ADAM module
ErrCde = DRV_AlarmReset(DriverHandle, chan);
// 6th Step : When you want to exit the I/O, please call to DRV_DeviceClose() function
DRV_DeviceClose((LONG far *) &DriverHandle);
Single Analog Input Channel Acquisition with Interrupt Transfer:
Fig 2-12. The Call Flow for Single-channel Data Acquisition with interrupt transfer
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
ptFAIIntStart.TrigSrc = gwExtTrig;
ptFAIIntStart.SampleRate = gdwPacerRate;
ptFAIIntStart.chan = gwStartChl;
ptFAIIntStart.gain = DevFeatures.glGainList[gwGainCode].usGainCde;
ptFAIIntStart.count = gulConvNum;
ptFAIIntStart.cyclic = gwCyclicMode;
if (gwFifoEnable)
ptFAIIntStart.IntrCount = FIFO_SIZE;
else
ptFAIIntStart.IntrCount = 1;// FIFO no enable
// 2nd Step: Start Interrupt transfer
ErrCde = DRV_FAIIntStart(DriverHandle, (LPT_FAIIntStart)&ptFAIIntStart);
ptFAICheck.ActiveBuf = &gwActiveBuf;
ptFAICheck.stopped = &gwStopped;
ptFAICheck.retrieved = &gulRetrieved;
ptFAICheck.overrun = &gwOverrun;
// FAICheck.HalfReady = 0 ( not ready, 1 ( first half ready, 2 ( second half ready
ptFAICheck.HalfReady = &gwHalfReady;
// 3rd Step: Checks if the current data acquisition is complete and return current status
// Get Interrupt transfer status
ErrCde = DRV_FAICheck(DriverHandle, (LPT_FAICheck) &ptFAICheck);
// 4th Step: Transfers the data from the buffer being used for the data acquisition operation to the
// specified data buffer
// If your program want to acquire data continusly, please put the Step 3 and 4 in a loop
if (gwHalfReady == 1) // first ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = 0;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer)&ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
}
else if (gwHalfReady == 2) // second half ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = gulConvNum/2;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer) &ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
gwCyclicCount ++;
}
// 5th Step: Cancels the current data acquisition operation and resets the hardware and software
ErrCde = DRV_FAIStop(DriverHandle)
// 6th Step: When you want to exit the I/O, please call to DRV_DeviceClose() function
ErrCde = DRV_DeviceClose((LONG far *) &DriverHandle);
Single Analog Input Channel Acquisition with Interrupt Transfer (with event):
Fig 2-12-A. The Call Flow for Single-channel Data Acquisition with interrupt transfer and event function
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
ptEnableEvent.EventType = ADS_EVT_INTERRUPT | ADS_EVT_BUFCHANGE |
ADS_EVT_TERMINATED | ADS_EVT_OVERRUN;
ptEnableEvent.Enabled = gwEvtFlag;
ptEnableEvent.Count = 512;
// 1.5th Step: Enable Event, then it calls to DRV_CheckEvent() instead of
// DRV_FAICheck()
ErrCde = DRV_EnableEvent(DriverHandle, (LPT_EnableEvent) &ptEnableEvent);
ptFAIIntStart.TrigSrc = gwExtTrig;
ptFAIIntStart.SampleRate = gdwPacerRate;
ptFAIIntStart.chan = gwStartChl;
ptFAIIntStart.gain = DevFeatures.glGainList[gwGainCode].usGainCde;
ptFAIIntStart.count = gulConvNum;
ptFAIIntStart.cyclic = gwCyclicMode;
if (gwFifoEnable)
ptFAIIntStart.IntrCount = FIFO_SIZE;
else
ptFAIIntStart.IntrCount = 1;// FIFO no enable
// 2nd Step: Start Interrupt transfer
ErrCde = DRV_FAIIntStart(DriverHandle, (LPT_FAIIntStart)&ptFAIIntStart);
// Implement Users Thread
void UserThread()
{
USHORT usEventType;
LONG ErrCde;
DWORD TickValue;
TickValue = GetTickCount();
TickValue = TickValue + 500000;
while(TickValue > GetTickCount())
{
// Check message
ptCheckEvent.EventType = &usEventType;
ptCheckEvent.Milliseconds = 5000;
// 3 th Step: Clear event and read current status
if ((ErrCde = DRV_CheckEvent(DriverHandle,
(LPT_CheckEvent)&ptCheckEvent)) != 0)
{
MessageBox(hWnd,"Check Event Error !","Thread Message",MB_OK);
return ;
}
// Process interrupt event
if (usEventType & ADS_EVT_INTERRUPT)
adInterruptEvent();
// Process buffer change event
if (usEventType & ADS_EVT_BUFCHANGE)
adBufChangeEvent();
// Process overrun event
if (usEventType & ADS_EVT_OVERRUN)
adOverrunEvent();
// Process terminate event
if (usEventType & ADS_EVT_TERMINATED)
{
adTerminateEvent();
return ;
}
}
MessageBox(hWnd,"Never Get Any Event !","Thread Message",MB_OK);
}
// 4th Step: Transfers the data from the buffer being used for the data acquisition operation to the
// specified data buffer
// If your program want to acquire data continusly, please put the Step 3 and 4 in a loop
if (gwHalfReady == 1) // first ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = 0;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer)&ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
}
else if (gwHalfReady == 2) // second half ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = gulConvNum/2;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer) &ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
gwCyclicCount ++;
}
// 5th Step: Cancels the current data acquisition operation and resets the hardware and software
ErrCde = DRV_FAIStop(DriverHandle);
// 6th Step: When you want to exit the I/O, please call to DRV_DeviceClose() function
ErrCde = DRV_DeviceClose((LONG far *) &DriverHandle);
Single Analog Input Channel Acquisition with DMA Transfer:
Fig 2-13. The Call Flow for Single-channel Data Acquisition with DMA transfer
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
ptAllocateDMABuffer.CyclicMode = gwCyclicMode;
ptAllocateDMABuffer.RequestBufSize = gulConvNum * 2;
ptAllocateDMABuffer.ActualBufSize = &gwActualBufSize;
ptAllocateDMABuffer.buffer = &pBuffer;
// 2nd Step: Allocate DMA buffer for DMA transfer
ErrCde = DRV_AllocateDMABuffer(DriverHandle, (LPT_AllocateDMABuffer) &ptAllocateDMABuffer);
ptFAIDmaStart.TrigSrc = gwExtTrig;
ptFAIDmaStart.SampleRate = gdwPacerRate;
ptFAIDmaStart.chan = gwStartChl;
ptFAIDmaStart.gain = DevFeatures.glGainList[gwGainCode].usGainCde;
ptFAIDmaStart.count = gulConvNum;
ptFAIDmaStart.buffer = (USHORT far *) pBuffer;
// 3th Step: Start DMA transfer
ErrCde = DRV_FAIDmaStart(DriverHandle, (LPT_FAIDmaStart)&ptFAIDmaStart);
// Get Interrupt transfer status
ptFAICheck.ActiveBuf = &gwActiveBuf;
ptFAICheck.stopped = &gwStopped;
ptFAICheck.retrieved = &gulRetrieved;
ptFAICheck.overrun = &gwOverrun;
ptFAICheck.HalfReady = &gwHalfReady;
// 4th Step: Checks if the current data acquisition is complete and return current status
ErrCde = DRV_FAICheck(DriverHandle, (LPT_FAICheck) &ptFAICheck);
// 5th Step: Transfers the data from the buffer being used for the data acquisition operation to the
// specified data buffer
// If your program want to acquire data continusly, please put the Step 4 and 5 in a loop
if (gwHalfReady == 1) // first ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = 0;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer)&ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
}
else if (gwHalfReady == 2) // second half ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = gulConvNum/2;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer) &ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
gwCyclicCount ++;
}
// 6th Step: Cancels the current data acquisition operation and resets the hardware and software
ErrCde = DRV_FAIStop(DriverHandle);
// 7th Step: Releases the buffer allocated by DRV_AllocateDMABuffer
ErrCde = DRV_FreeDMABuffer(DriverHandle, (LPARAM)&pBuffer);
// 8th Step: When you want to exit the I/O, please call to DRV_DeviceClose() function
ErrCde = DRV_DeviceClose((LONG far *) &DriverHandle);
Single Analog Input Channel Acquisition with DMA Transfer (with Event):
Fig 2-13-A. The Call Flow for Single-channel Data Acquisition with DMA transfer and event function
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
ptEnableEvent.EventType = ADS_EVT_INTERRUPT | ADS_EVT_BUFCHANGE |
ADS_EVT_TERMINATED | ADS_EVT_OVERRUN;
ptEnableEvent.Enabled = gwEvtFlag;
ptEnableEvent.Count = 512;
// 1.5th Step: Enable Event, then it calls to DRV_CheckEvent() instead of
// DRV_FAICheck()
ErrCde = DRV_EnableEvent(DriverHandle, (LPT_EnableEvent) &ptEnableEvent);
ptAllocateDMABuffer.CyclicMode = gwCyclicMode;
ptAllocateDMABuffer.RequestBufSize = gulConvNum * 2;
ptAllocateDMABuffer.ActualBufSize = &gwActualBufSize;
ptAllocateDMABuffer.buffer = &pBuffer;
// 2nd Step: Allocate DMA buffer for DMA transfer
ErrCde = DRV_AllocateDMABuffer(DriverHandle, (LPT_AllocateDMABuffer) &ptAllocateDMABuffer);
ptFAIDmaStart.TrigSrc = gwExtTrig;
ptFAIDmaStart.SampleRate = gdwPacerRate;
ptFAIDmaStart.chan = gwStartChl;
ptFAIDmaStart.gain = DevFeatures.glGainList[gwGainCode].usGainCde;
ptFAIDmaStart.count = gulConvNum;
ptFAIDmaStart.buffer = (USHORT far *) pBuffer;
// 3th Step: Start DMA transfer
ErrCde = DRV_FAIDmaStart(DriverHandle, (LPT_FAIDmaStart)&ptFAIDmaStart);
// Implement Users Thread
void UserThread()
{
USHORT usEventType;
LONG ErrCde;
DWORD TickValue;
TickValue = GetTickCount();
TickValue = TickValue + 500000;
while(TickValue > GetTickCount())
{
// Check message
ptCheckEvent.EventType = &usEventType;
ptCheckEvent.Milliseconds = 5000;
// 4 th Step: Clear event and read current status
if ((ErrCde = DRV_CheckEvent(DriverHandle,
(LPT_CheckEvent)&ptCheckEvent)) != 0)
{
MessageBox(hWnd,"Check Event Error !","Thread Message",MB_OK);
return ;
}
// Process interrupt event
if (usEventType & ADS_EVT_INTERRUPT)
adInterruptEvent();
// Process buffer change event
if (usEventType & ADS_EVT_BUFCHANGE)
adBufChangeEvent();
// Process overrun event
if (usEventType & ADS_EVT_OVERRUN)
adOverrunEvent();
// Process terminate event
if (usEventType & ADS_EVT_TERMINATED)
{
adTerminateEvent();
return ;
}
}
MessageBox(hWnd,"Never Get Any Event !","Thread Message",MB_OK);
}
// 5th Step: Transfers the data from the buffer being used for the data acquisition operation to the
// specified data buffer
// If your program want to acquire data continusly, please put the Step 4 and 5 in a loop
if (gwHalfReady == 1) // first ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = 0;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer)&ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
}
else if (gwHalfReady == 2) // second half ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = gulConvNum/2;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer) &ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
gwCyclicCount ++;
}
// 6th Step: Cancels the current data acquisition operation and resets the hardware and software
ErrCde = DRV_FAIStop(DriverHandle);
// 7th Step: Releases the buffer allocated by DRV_AllocateDMABuffer
ErrCde = DRV_FreeDMABuffer(DriverHandle, (LPARAM)&pBuffer);
// 8th Step: When you want to exit the I/O, please call to DRV_DeviceClose() function
ErrCde = DRV_DeviceClose((LONG far *) &DriverHandle);
Multiple Analog Input Channel Acquisition with Interrupt Transfer:
Fig 2-14. The Call Flow for Multiple-channel Data Acquisition with interrupt transfer
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
ptFAIIntScanStart.TrigSrc = gwExtTrig;
ptFAIIntScanStart.StartChan = gwStartChl;
ptFAIIntScanStart.NumChans = gwNumChl;
ptFAIIntScanStart.GainList = &gwGainCde[0];
ptFAIIntScanStart.SampleRate = gdwPacerRate;
ptFAIIntScanStart.count = gulConvNum;
ptFAIIntScanStart.cyclic = gwCyclicMode;
if (gwFifoEnable)
ptFAIIntScanStart.IntrCount = FIFO_SIZE;
else
ptFAIIntScanStart.IntrCount = 1;
// 2nd Step: Start Interrupt transfer
ErrCde = DRV_FAIIntScanStart(DriverHandle, (LPT_FAIIntScanStart)&ptFAIIntScanStart);
ptFAICheck.ActiveBuf = &gwActiveBuf;
ptFAICheck.stopped = &gwStopped;
ptFAICheck.retrieved = &gulRetrieved;
ptFAICheck.overrun = &gwOverrun;
// FAICheck.HalfReady = 0 ( not ready, 1 ( first half ready, 2 ( second half ready
ptFAICheck.HalfReady = &gwHalfReady;
// 3rd Step: Checks if the current data acquisition is complete and return current status
// Get Interrupt transfer status
ErrCde = DRV_FAICheck(DriverHandle, (LPT_FAICheck) &ptFAICheck);
// 4th Step: Transfers the data from the buffer being used for the data acquisition operation to the
// specified data buffer
// If your program want to acquire data continusly, please put the Step 3 and 4 in a loop
if (gwHalfReady == 1) // first ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = 0;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer)&ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
}
else if (gwHalfReady == 2) // second half ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = gulConvNum/2;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer) &ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
gwCyclicCount ++;
}
// 5th Step: Cancels the current data acquisition operation and resets the hardware and software
ErrCde = DRV_FAIStop(DriverHandle)
// 6th Step: When you want to exit the I/O, please call to DRV_DeviceClose() function
ErrCde = DRV_DeviceClose((LONG far *) &DriverHandle);
Multiple Analog Input Channel Acquisition with Interrupt Transfer (with Event):
Fig 2-14-A. The Call Flow for Multiple-channel Data Acquisition with interrupt transfer and event function
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
ptEnableEvent.EventType = ADS_EVT_INTERRUPT | ADS_EVT_BUFCHANGE |
ADS_EVT_TERMINATED | ADS_EVT_OVERRUN;
ptEnableEvent.Enabled = gwEvtFlag;
ptEnableEvent.Count = 512;
// 1.5th Step: Enable Event, then it calls to DRV_CheckEvent() instead of
// DRV_FAICheck()
ErrCde = DRV_EnableEvent(DriverHandle, (LPT_EnableEvent) &ptEnableEvent);
ptFAIIntScanStart.TrigSrc = gwExtTrig;
ptFAIIntScanStart.StartChan = gwStartChl;
ptFAIIntScanStart.NumChans = gwNumChl;
ptFAIIntScanStart.GainList = &gwGainCde[0];
ptFAIIntScanStart.SampleRate = gdwPacerRate;
ptFAIIntScanStart.count = gulConvNum;
ptFAIIntScanStart.cyclic = gwCyclicMode;
if (gwFifoEnable)
ptFAIIntScanStart.IntrCount = FIFO_SIZE;
else
ptFAIIntScanStart.IntrCount = 1;
// 2nd Step: Start Interrupt transfer
ErrCde = DRV_FAIIntScanStart(DriverHandle, (LPT_FAIIntScanStart)&ptFAIIntScanStart);
ptFAICheck.ActiveBuf = &gwActiveBuf;
ptFAICheck.stopped = &gwStopped;
ptFAICheck.retrieved = &gulRetrieved;
ptFAICheck.overrun = &gwOverrun;
// FAICheck.HalfReady = 0 ( not ready, 1 ( first half ready, 2 ( second half ready
ptFAICheck.HalfReady = &gwHalfReady;
// Implement Users Thread
void UserThread()
{
USHORT usEventType;
LONG ErrCde;
DWORD TickValue;
TickValue = GetTickCount();
TickValue = TickValue + 500000;
while(TickValue > GetTickCount())
{
// Check message
ptCheckEvent.EventType = &usEventType;
ptCheckEvent.Milliseconds = 5000;
// 3 th Step: Clear event and read current status
if ((ErrCde = DRV_CheckEvent(DriverHandle,
(LPT_CheckEvent)&ptCheckEvent)) != 0)
{
MessageBox(hWnd,"Check Event Error !","Thread Message",MB_OK);
return ;
}
// Process interrupt event
if (usEventType & ADS_EVT_INTERRUPT)
adInterruptEvent();
// Process buffer change event
if (usEventType & ADS_EVT_BUFCHANGE)
adBufChangeEvent();
// Process overrun event
if (usEventType & ADS_EVT_OVERRUN)
adOverrunEvent();
// Process terminate event
if (usEventType & ADS_EVT_TERMINATED)
{
adTerminateEvent();
return ;
}
}
MessageBox(hWnd,"Never Get Any Event !","Thread Message",MB_OK);
}
// 4th Step: Transfers the data from the buffer being used for the data acquisition operation to the
// specified data buffer
// If your program want to acquire data continusly, please put the Step 3 and 4 in a loop
if (gwHalfReady == 1) // first ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = 0;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer)&ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
}
else if (gwHalfReady == 2) // second half ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = gulConvNum/2;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer) &ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
gwCyclicCount ++;
}
// 5th Step: Cancels the current data acquisition operation and resets the hardware and software
ErrCde = DRV_FAIStop(DriverHandle)
// 6th Step: When you want to exit the I/O, please call to DRV_DeviceClose() function
ErrCde = DRV_DeviceClose((LONG far *) &DriverHandle);
Multiple Analog Input Channel Acquisition with DMA Transfer:
Fig 2-15. The Call Flow for Multiple-channel Data Acquisition with DMA transfer
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
ptAllocateDMABuffer.CyclicMode = gwCyclicMode;
ptAllocateDMABuffer.RequestBufSize = gulConvNum * 2;
ptAllocateDMABuffer.ActualBufSize = &gwActualBufSize;
ptAllocateDMABuffer.buffer = &pBuffer;
// 2nd Step: Allocate DMA buffer for DMA transfer
ErrCde = DRV_AllocateDMABuffer(DriverHandle, (LPT_AllocateDMABuffer) &ptAllocateDMABuffer);
ptFAIDmaScanStart.TrigSrc = gwExtTrig;
ptFAIDmaScanStart.StartChan = gwStartChl;
ptFAIDmaScanStart.NumChans = gwNumChl;
ptFAIDmaScanStart.GainList = &gwGainCde[0];
ptFAIDmaScanStart.SampleRate = gdwPacerRate;
ptFAIDmaScanStart.count = gulConvNum;
ptFAIDmaScanStart.buffer = (USHORT far *)pBuffer;
// 3th Step: Start DMA transfer
ErrCde = DRV_FAIDmaScanStart(DriverHandle, (LPT_FAIDmaScanStart) &ptFAIDmaScanStart);
// Get Interrupt transfer status
ptFAICheck.ActiveBuf = &gwActiveBuf;
ptFAICheck.stopped = &gwStopped;
ptFAICheck.retrieved = &gulRetrieved;
ptFAICheck.overrun = &gwOverrun;
ptFAICheck.HalfReady = &gwHalfReady;
// 4th Step: Checks if the current data acquisition is complete and return current status
ErrCde = DRV_FAICheck(DriverHandle, (LPT_FAICheck) &ptFAICheck);
// 5th Step: Transfers the data from the buffer being used for the data acquisition operation to the
// specified data buffer
// If your program want to acquire data continusly, please put the Step 4 and 5 in a loop
if (gwHalfReady == 1) // first ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = 0;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer)&ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
}
else if (gwHalfReady == 2) // second half ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = gulConvNum/2;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer) &ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
gwCyclicCount ++;
}
// 6th Step: Cancels the current data acquisition operation and resets the hardware and software
ErrCde = DRV_FAIStop(DriverHandle);
// 7th Step: Releases the buffer allocated by DRV_AllocateDMABuffer
ErrCde = DRV_FreeDMABuffer(DriverHandle, (LPARAM)&pBuffer);
// 8th Step: When you want to exit the I/O, please call to DRV_DeviceClose() function
ErrCde = DRV_DeviceClose((LONG far *) &DriverHandle);
Fig 2-15-A. The Call Flow for Multiple-channel Data Acquisition with DMA transfer and event function
// 1st Step: Call to DRV_DeviceOpen() function get a DriverHandle which can be applied for the other
// funcitons.
ErrCde = DRV_DeviceOpen(DeviceNum, (LONG far *) &DriverHandle);
ptEnableEvent.EventType = ADS_EVT_INTERRUPT | ADS_EVT_BUFCHANGE |
ADS_EVT_TERMINATED | ADS_EVT_OVERRUN;
ptEnableEvent.Enabled = gwEvtFlag;
ptEnableEvent.Count = 512;
// 1.5th Step: Enable Event, then it calls to DRV_CheckEvent() instead of
// DRV_FAICheck()
ErrCde = DRV_EnableEvent(DriverHandle, (LPT_EnableEvent) &ptEnableEvent);
ptAllocateDMABuffer.CyclicMode = gwCyclicMode;
ptAllocateDMABuffer.RequestBufSize = gulConvNum * 2;
ptAllocateDMABuffer.ActualBufSize = &gwActualBufSize;
ptAllocateDMABuffer.buffer = &pBuffer;
// 2nd Step: Allocate DMA buffer for DMA transfer
ErrCde = DRV_AllocateDMABuffer(DriverHandle, (LPT_AllocateDMABuffer) &ptAllocateDMABuffer);
ptFAIDmaScanStart.TrigSrc = gwExtTrig;
ptFAIDmaScanStart.StartChan = gwStartChl;
ptFAIDmaScanStart.NumChans = gwNumChl;
ptFAIDmaScanStart.GainList = &gwGainCde[0];
ptFAIDmaScanStart.SampleRate = gdwPacerRate;
ptFAIDmaScanStart.count = gulConvNum;
ptFAIDmaScanStart.buffer = (USHORT far *)pBuffer;
// 3th Step: Start DMA transfer
ErrCde = DRV_FAIDmaScanStart(DriverHandle, (LPT_FAIDmaScanStart) &ptFAIDmaScanStart);
// Implement Users Thread
void UserThread()
{
USHORT usEventType;
LONG ErrCde;
DWORD TickValue;
TickValue = GetTickCount();
TickValue = TickValue + 500000;
while(TickValue > GetTickCount())
{
// Check message
ptCheckEvent.EventType = &usEventType;
ptCheckEvent.Milliseconds = 5000;
// 4 th Step: Clear event and read current status
if ((ErrCde = DRV_CheckEvent(DriverHandle,
(LPT_CheckEvent)&ptCheckEvent)) != 0)
{
MessageBox(hWnd,"Check Event Error !","Thread Message",MB_OK);
return ;
}
// Process interrupt event
if (usEventType & ADS_EVT_INTERRUPT)
adInterruptEvent();
// Process buffer change event
if (usEventType & ADS_EVT_BUFCHANGE)
adBufChangeEvent();
// Process overrun event
if (usEventType & ADS_EVT_OVERRUN)
adOverrunEvent();
// Process terminate event
if (usEventType & ADS_EVT_TERMINATED)
{
adTerminateEvent();
return ;
}
}
MessageBox(hWnd,"Never Get Any Event !","Thread Message",MB_OK);
}
// 5th Step: Transfers the data from the buffer being used for the data acquisition operation to the
// specified data buffer
// If your program want to acquire data continusly, please put the Step 4 and 5 in a loop
if (gwHalfReady == 1) // first ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = 0;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer)&ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
}
else if (gwHalfReady == 2) // second half ready
{
ptFAITransfer.ActiveBuf = 0; // single buffer
ptFAITransfer.DataType = gwDataType;
ptFAITransfer.start = gulConvNum/2;
ptFAITransfer.count = gulConvNum/2;
ptFAITransfer.overrun = &gwOverrun;
if ((ErrCde = DRV_FAITransfer(DriverHandle, (LPT_FAITransfer) &ptFAITransfer)) != 0)
{
DRV_GetErrorMessage(ErrCde,(LPSTR)szErrMsg);
MessageBox(hWnd,(LPCSTR)szErrMsg,"Thread Message",MB_OK);
return ;
}
gwCyclicCount ++;
}
// 6th Step: Cancels the current data acquisition operation and resets the hardware and software
ErrCde = DRV_FAIStop(DriverHandle);
// 7th Step: Releases the buffer allocated by DRV_AllocateDMABuffer
ErrCde = DRV_FreeDMABuffer(DriverHandle, (LPARAM)&pBuffer);
// 8th Step: When you want to exit the I/O, please call to DRV_DeviceClose() function
ErrCde = DRV_DeviceClose((LONG far *) &DriverHandle);
EMBED Package
New Device Installation Utility for Windows NT and 95
Differential Mode (same with RS-485)
If VCDI0+ - VCDI0- > 200mV ( Active High Status
If VCDI0+ - VCDI0- < -200mV ( Active Low Status
Single Ended
Minimal input voltage for Active High Signal ( 2.5 Volt
Maximize input voltage for Active Low Signal > 200mV ( 2.0 Volt
To check the Digital Input with interrupt of PCL-733 by using two IRQ setup, you should set it into two device number, for example
001 : PCL-733 I/O=300H ( IRQ = 5
001 : PCL-733 I/O=300H ( IRQ = 7
When we run two Fdigin.EXE, the processing input interrupt speed can be up to 18.5KHz for each Fdigin.EXE.
60
_952253950.vsd_952254074.vsd_952263219.vsd_952266258.vsd_952263206.vsd_952260564.vsd_952253968.vsd_952253976.vsd_952253980.vsd_952253974.vsd_952253959.vsd_952253956.vsd_952253936.vsd_952253944.vsd_952253948.vsd_952253895.vsd_952253933.vsd_944897938/devinst.exe