Manual PCI-A12-16A
21
Programming Guide
A/D Data Acquisition
Taking data from an A/D can seem confusing at first, but it all boils down to a few simple steps.
Set Point List
Offset 2 Writes (16-bit words)
Offset 2 Read
Start Conversion
Offset 0 Write
Wait for End of Conversion
Offset 4 Read
Read Data
Offset 0 Read (16-bit integer)
Repeat
To set the point list, you must build the point from its component parts. It consists of the channel, the range,
and the differential or single-ended control bit. The range is in the low 3 bits, the SE/DIFF bit is next, then the
channel. From the table in the programming section, you can pick the range number for the desired range,
and in most programs the channel number will come from a FOR loop. Assuming the channel number is in
CH, the range is in RNG, and the SE/DIFF bit is in SEDIFF, you can build a control word with:
control = (CH << 4) + (SEDIFF << 3) + RNG;
This seems fairly complex, but it is made easier if you take into account that most programs will acquire data
from a single range and usually at a single SE/DIFF setting. These two values, then, can be hard-coded into
the program, and the code becomes:
control = (CH << 4) + 1; // for Single-ended, + 5 VDC operation
Write two or more of these points to the point list, and that is all there is for polled mode A/D conversions. The
data comes back in counts, and must be converted to engineering units to be useful. The data is returned in
two's complement form, but resides in only 12 bits. To get a true two's complement integer, you must sign-
extend the data. The following line reads the data and converts it to the simplest form:
data = ((int)inport(base + 0) << 4) >> 4; //C or C++
data := (portw[base + 0] shl 4) DIV 16; {Pascal}
The variable "data" now holds a number from -2048 to 2047 for bipolar ranges, 0 to 4095 for unipolar. A
simple Y = mX + b equation (where X is the data) would convert this to engineering units.
In order to tag the data, a shift becomes easier than a multiply when setting the point list:
control = (CH * 0x1010) + 1; // for Single-ended, + 5 VDC operation
And the read then also retrieves the tag:
rawdata = inport(base + 0); //C or C++
chan = (unsigned)rawdata >> 12;
data = (rawdata << 4) >> 4;
rawdata := portw[base + 0]; {Pascal}
chan := rawdata shr 12;
data := (rawdata shl 4) DIV 16;