-
Please Help! Urgent!
I need to write a programe executable in DOS to control a hardware, a 12-bit analog-to-digital converter card using C++. I've the manual about this card and the procedures to develop the programe is given. However, i have many uncertainties about the procedures. Would any one help to solve them.
Here I show briefy the manual as below(deails of manual refer to attachment 128-bit.zip):
The I/O port address are &h278-27F or &H2F8-2FF selectable.
&H278 / 2F8 : Output A/D channel number. (low nibble).
279 / 2F9 : Input A/D low byte data. (8 bits).
27A / 2FA : Input A/D high byte data.
27B / 2FB : Clear A/D register.
27C / 2FC : A/D conversion loop. (low)
27D / 2FD : A/D conversion loop (high)
27E / 2FE : Output D/A low byte data. (8 bits)
27F / 2FF : Output D/A high byte data. (low nibble).
Analog to digital (A/D) procedure:
(1) Output channel number to port
OUT port channel
(2) Clear register
OUT (port + 3), 0
(3) Start convert
FOR I=1 to 5
A = INP (port + 4)
NEXT I=1 TO 9
A = INP (port + 5)
NEXT I
(4) Read high byte (low nibble)
C = INP (port + 2)
HB = (C/16 ¡V INT (C/16)) * 16
(5) READ LOW BYTE (8 BITS)
LB = INP (port + 1)
(6) Data:
A/D = HB * 256 + LB
My questions are:
1. In procedure (3), it seems that there should be two for-loop, one inside another, is there a typing error in the guideline. And if it is so, why should it take a total 45 times 'INP'. What's the purpose of that?
2. In procedure(4), to my understanding, INP(port +2) return the high byte from a 12-bit data. So, why shouldn't I directly multiply it by 256 to shift it by 8 bits higher like that is done in
procedure(6)? what's the use of that?
3. I've writen my own programe and compiled it using Turbo C++ 3, but some unexpected result usually obtained. I use "inp()" to get the HOB and LOB, but the HOB is always equal to 255 while the LOB results in range from 0- 194. Why is it so? Pls give comments on my programe (128-bit.zip)
Any help is apprepicate! Thanks
-
That is the worst documentation I've ever seen!!! It is incorrect and imcomplete. Notice the "GOSUB 550" in the test program - there is no line 550!!
You could never get A/D to work with that kind of documentation.
From you questions:
1) Yep, that's a "typing error". This is how they sample and convert.
2) "(C/16 - INT (C/16)) * 16" is just taking the lower nibble (4 bits) of C. This is because it's a 12bit A/D (4 bits in the hight byte and 8 bits in the low byte)
3) Well, I found the German version of the documentation!!! And it has Pascal and C source! I've attached the documentation I found. It looks like this documentation had several "typing error's" as well, but I combined all the info together to come up with something that hopefully is correct.
Code:
#include <iostream.h>
#include <dos.h>
//convenient types
typedef unsigned short WORD;
typedef unsigned char BYTE;
//Port# card if configured for
const WORD PORT = 0x278;
//Millisecond delay to use during conversion...
//this was used in the Pascal version of the code, I would reduce this # until
//it stops working correctly
const WORD MS_DELAY = 100;
//Function to perform A/D conversion on given channel (0-15)
WORD ad(BYTE channel);
int main()
{
for (BYTE n = 0; n < 16; n++)
{
cout << "A/D on channel " << n << " is " << ad(n) << endl;
}
return 0;
}
WORD ad(BYTE channel)
{
//check parameter
if (channel > 15)
channel = 15;
//select channel
outportb(PORT,channel);
//clear register
outportb(PORT+3,0);
//perform sampling/conversion
int i;
for (i = 0; i < 5; i++)
{
inportb(PORT+4);
delay(MS_DELAY);
}
for (i = 0; i < 9; i++)
{
inportb(PORT+5);
delay(MS_DELAY);
}
//return lower 12bits of result
return inport(PORT+1) & 0x0FFF;
}
gg