Dec 062017
 
Analog to Digital functions in C using the 2801 series A/D converters.
File ADC_IN_C.ZIP from The Programmer’s Corner in
Category C Source Code
Analog to Digital functions in C using the 2801 series A/D converters.
File Name File Size Zip Size Zip Type
VIBERTAD.DOC 13856 2854 deflated

Download File ADC_IN_C.ZIP Here

Contents of the VIBERTAD.DOC file


This is a complete program of an article dealing with analog/digital
conversion on a PC using a Data Translation board. The article
appreared in C Users Journal issue 7(1) Dec/Jan 89, page 39-48.
This program is functional and is written for 2801 series. However,
the program should be of educational value to those who are
interested in doing A/D conversion using C. The principle should
be applicable to other third party hardwares to some degree.
Although, many companies make subroutines in various languages
available with their boards.

If you want to distribute this, please preserve the header. It
contains information on who wrote it and e-mail/street address
of where to get help. Dr. Vibert is a French physiologist working on
respiratory physiology, in Paris.

Dan Bulyalert
Physiology, Emory School of Medicine
Atlanta, GA 30322
[email protected]

----------------------------------------------------------------------
program starts here.
----------------------------------------------------------------------

/***************************************************************************
*
* Sampling Modules for DT2801-A board
*
* characteristics of the board :
* - A/D resolution : 12 bits,
* - A/D conversion time : 10 microseconds
* - Software programmable gain range : 1, 2, 4 ou 8
* - Number of analog Inputs : 16 single-ended A/D inputs
* 8 differential inputs
* - programmable clock
* - Digital Input/Output : 2
* - D/A converter : 2
*
* Base address of the board 2ec(hexadecimal) (default address)
*
* Microsoft C version 4.00
*
*Jean-Francois VIBERT & Beatrice COINTOT
*Department of Physiology
*CHU Saint-Antoine
*Universite Paris 6
*27 rue Chaligny
*F-75571 Paris Cedex 12
*
*Dr. Vibert's BITNET address is VIBERT@FRSIM51
****************************************************************************/

#include
#include

float askfval();

int command_reg, /* command register */
status_reg, /* status register */
data_reg, /* data register */
base_adress, /* base address of the board*/
command_wait, /* command bit in status register */
write_wait, /* Data in full bit in status register */
read_wait; /* Data out Ready bit in status register */

int first_channel, /* first channel used */
last_channel, /* last channel used */
gain; /* gain range */

float periode; /* sampling period */

/************************************************************************
* *
* Test programm *
* *
************************************************************************/
main()
{
int data[512][2], /*data array, 2 channels and 512
data on each channel */
*p_data, /* pointer on the data array */
num_pts, /* total number of samples */
i,point;

init_value();
parametres();
init_carte();
num_pts = 512;
p_data = &data[0][0];
carte_go();
while (num_pts)
{
*p_data = lect_point(); /* read one sample */
p_data++;
num_pts--;
}
stop_carte();
error();

/* read and print data array */
for (i = 0 ; i < 512 ; i++)
{
/* conversion in volts*/
printf ("value = %d, channel 1 = %f, channel 2 = %f \n",i,5.-((f
loat)data[0][i]*10./4096.),5.-((float)data[1][i]*10./4096.));
}
}


/************************************************************************
* *
* Routine INIT_VALUE *
* *
*************************************************************************/
init_value()
{
/* initialisation program */
/* bord's base address */
base_adress = 0x2ec;
command_reg = base_adress + 1; /* command register address */
status_reg = base_adress + 1; /* status register address */
data_reg = base_adress; /* data register address */

command_wait = 4;/* command bit in status register */
write_wait = 2; /* Data in full bit in status register */
read_wait = 5; /* Data out Ready bit in status register */
}
/************************************************************************
* *
* Routine PARAMETRES *
* *
*************************************************************************/
parametres()
{
/* user dependant parameters */

first_channel = askival("first channel used ([0] a 15) : ",0);

last_channel = askival("last channel used ([0] a 15) : ",0);

gain = askival ("gain used ([1], 2, 4 ou 8) : ",1);

periode = askfval("sampling period's in msec (0.03 a 81.9) :",0.03);

}

/************************************************************************
* *
* Routine INIT_CARTE *
* *
*************************************************************************/
init_carte()
{
int tempo, /* temporary variable */
carte_gain, /* value to send to the board for select gain */
low_period, /* low byte for period */
high_period; /* high byte for period */

double temp_period; /* temporary variable */

/* initialisation of the board with user parameters */

/* Stop and RAZ the board */
outp(command_reg,15); /* stop the board */
tempo = inp(data_reg);
while (!(inp(status_reg) & command_wait)); /* wait until board OK *
/
outp(command_reg,1); /* RAZ the board */

/* send parameters to the board */
while (!(((inp(status_reg)) : write_wait) & write_wait)); /* wait unit*/
while (!(inp(status_reg) & command_wait)); /* board OK*/
outp (command_reg, 13); /* command : set A/D parameters */

switch (gain)
{
case 1 :
carte_gain = 0;
break;

case 2 :
carte_gain = 1;
break;

case 4 :
carte_gain = 2;
break;

case 8 :
carte_gain = 3;
break;
}
while (!(((inp(status_reg)) : write_wait) & write_wait)); /* wait */
outp (data_reg, carte_gain); /* write A/D gain code */

while (!(((inp(status_reg)) : write_wait) & write_wait)); /*wait */
outp (data_reg, first_channel); /* write A/D start channel */

while (!(((inp(status_reg)) : write_wait) & write_wait)); /* wait*/
outp (data_reg, last_channel); /* write A/D end channel */

while (!(((inp(status_reg)) : write_wait) & write_wait)); /* wait*/
outp (data_reg, 0); /* write number of conversion, low byte */

while (!(((inp(status_reg)) : write_wait) & write_wait)); /* wait */
outp (data_reg, 4); /* write number of conversion, high byte */

/* set clock period */
/* calculation of low-byte and high-byte period */
temp_period = (double) periode /0.00125;/* number of ticks*/
high_period = (int)(temp_period/256.);
low_period = (int) (temp_period - (high_period * 256));
while (!(inp(status_reg) & command_wait)) /*wait until board OK */
outp (command_reg, 3); /* set internal clock period */

while (!(((inp(status_reg)) : write_wait) & write_wait)); /* wait */
outp (data_reg,low_period); /* low byte */

while (!(((inp(status_reg)) : write_wait) & write_wait)); /* wait */
outp (data_reg, high_period); /* high byte */

}

/************************************************************************
* *
* Routine LECT_POINT *
* *

*************************************************************************/
lect_point()
{
/* read one point on one channel */
int i,
point,
low_point, /* the low_byte of the get point */
high_point; /* the high_byte of the get point */

while (!(inp(status_reg) & read_wait)); /* wait */
low_point = inp(data_reg); /* low byte */

while (!(inp(status_reg) & read_wait)); /* wait */
high_point = inp(data_reg); /* high byte */

point = (high_point << 8 ) | low_point;
return(point);

}
/************************************************************************
* *
* Routine CARTE_GO *
* *
*************************************************************************/
carte_go()
{
/* to start sampling */

while (!((inp(status_reg) : write_wait) & write_wait)); /* wait */
while (!(inp(status_reg) & command_wait)); /* board OK*/
outp(command_reg,46); /* read A/D in continu mode */
}

/************************************************************************
* *
* Routine STOP_CARTE *
* *
************************************************************************/
stop_carte()
{
/* stop the board */
int tempo;

outp(command_reg,15); /* stop the board */
tempo = inp(data_reg);
}
/************************************************************************
* *
* Routine ERROR *
* *
************************************************************************/
error()
{
/* Error on the board ? */
int tempo,
low_error,
high_error;

while (!(((inp(status_reg)) : write_wait) & write_wait)); /* wait*/
while (!(inp(status_reg) & command_wait));
tempo = inp(status_reg);
/* error ? */
if ((tempo & 0x80) == 128)
{ /* error - YES */
printf ("error in sampling \n");
while (!(inp(status_reg) & command_wait));
outp (command_reg, 2); /* for read error code */
while (!(inp(status_reg) & read_wait));
low_error = inp(data_reg); /* read low_byte*/
while (!(inp(status_reg) & read_wait));
high_error = inp(data_reg); /* read high_ byte*/
printf ("low_byte = %d, high_byte = %d \n",low_error,high_error)
;
}
}

/************************************************************************
* *
* Routine ASKIVAL *
* *
*************************************************************************

ask an integer */

askival(prompt,defaut)
char *prompt;
int defaut;

{
char ch_recu[10];
fputs(prompt,stderr);
gets (ch_recu);
if (strlen(ch_recu)) return(atoi(ch_recu));
return (defaut);
}

/************************************************************************
* *
* Routine ASKFVAL *
* *
*************************************************************************

ask a float */

float askfval(prompt,defaut)
char *prompt;
float defaut;

{
float f_val;
char ch_recu[10];
fputs(prompt,stderr);
gets (ch_recu);
if (strlen(ch_recu))
{
sscanf(ch_recu,"%f",&f_val);
return (f_val);
}
return(defaut);
}

----------------------------------------------------------------------
END
----------------------------------------------------------------------


 December 6, 2017  Add comments

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)