/* AD.C * * Analog Input Routines for the SBC1190 with 8 Channel A/D option * * This example can be compiled to an EXE file that polls the A/D convertor * until the conversion is complete or to an EXE file that uses an * interrupt to signal completion of the conversion. * * 8/3/98 * 10/15/99 fix editing error that removed convdone reset */ #define INTDRIVEN /* comment this line out for polled conversion */ #include #include #define INTCTRLLD 0 #define RANGE5V 0 #define RANGE10V 1 #define UNIPOLAR 0 #define BIPOLAR 1 #ifdef __TURBOC__ #ifndef inpw #define inpw inport #endif #ifndef outpw #define outpw outport #endif #ifndef _dos_setvect #define _dos_setvect setvect #endif #endif #define ADCTRL 0xFE44 /* write only */ #define ADDATA 0xFE44 /* read only */ #define ADDATALO 0xFE44 /* read only */ #define ADDATAHI 0xFE45 /* read only */ #define PCB 0x0FF00 /* default base address after reset */ #define EOI PCB+0x002 #define IMASK PCB+0x008 #define P2PIN PCB+0x05A int advalue; int convdone; void far interrupt adinthndlr(void) { advalue = inpw(ADDATA); /* read the data */ convdone = 1; outpw(EOI, 0x8000); } /*-----------------------------------------------------------------------* * analogrd(int chan) * * This function reads analog input in the * * range set by configadc() * * given a channel number of 0 to 7 * * Return value : Integer { -2047 to +2048 } or { 0 to 4095 } * *-----------------------------------------------------------------------*/ unsigned int controlbyte = 0; int analogrd(int chan) { int value; if ((chan<0) || (chan >7)) return(-999); convdone = 0; outp(ADDATA, controlbyte | chan); /* write control word */ /* and start conversion */ #ifdef INTDRIVEN while (!convdone) ; convdone = 0; /* reset convdone */ value = advalue; #else /* POLLED */ while (!(inp(P2PIN) & 4)) /* wait for signal to rise */ ; value = inpw(ADDATA); /* read the data */ #endif return(value); } /*-----------------------------------------------------------------------* * configadc(int acqmod, int rng, int bip) * * This function configures the ADC for mode of acquisition, * * range, and polarity * * Send a 0 or 1 to the function variables as follows: * * acqmod = 0 ---> internally controlled acquisition * * acqmod = 1 ---> externally controlled acquisition * * RNG = 0 ---> 5V range * * RNG = 1 ---> 10V range * * BIP = 0 ---> + RNG range * * BIP = 1 ---> +/- RNG range * *-----------------------------------------------------------------------*/ void configadc(int acqmod, int rng, int bip) { controlbyte = 0x40; if (acqmod) controlbyte = controlbyte | 0x20; if (rng) controlbyte = controlbyte | 0x10; if (bip) controlbyte = controlbyte | 0x08; } void main(void) { int key,n; float adcval; #ifdef INTDRIVEN /* AD conversion-complete interrupt signal is INT3, which translates to an interrupt type of 0Fh */ _dos_setvect(0xF, adinthndlr); outp(IMASK, inp(IMASK) & 0x7F); /* unmask INT3 */ #endif configadc(INTCTRLLD, RANGE10V, BIPOLAR); /* internal controlled acq., +/- 10v range */ printf("Reading 8 channels\n\n"); printf("Ch0 Ch1 Ch2 Ch3 Ch4 Ch5 Ch6 Ch7\n"); for(;;) { for(n=0; n<8; n++) { adcval = (float)analogrd(n)*10.0/2048.0 +.005; printf("%-+6.2f ", adcval); } printf("\r"); } }