/**************************************************************************** * C LANGUAGE SAMPLE 2: SAMPLE2.C * * * * This is a demonstration program to be used with the AD12-8 A/D * * board. The program will display channels of data polled from an AIM-16 * * board using the A12DRVC.OBJ driver module supplied with the AD12-8, * * in interrupt mode (TASK 9). * * This program must be built using the large model. * * * * LAST MODIFICATION: July 21, 1995 * * * ****************************************************************************/ #include #include #include #include #include #include #include "a12drvc.h" unsigned AskForBaseAddress(unsigned int OldOne) { char msg[7]; int NewOne = 0, Success = 0, Dummy; int AddrInputPosX, AddrInputPosY; puts("\nPlease enter the Base Address for your card (in hex)"); printf("or press ENTER for %X.\n>", OldOne); AddrInputPosX = wherex(); AddrInputPosY = wherey(); do { gotoxy(AddrInputPosX, AddrInputPosY); clreol(); msg[0] = 5; msg[1] = 0; cgets(msg); sscanf(msg + 2, "%x", &NewOne); Success = 1; Dummy = NewOne; if (msg[1] == 0) { gotoxy(AddrInputPosX, AddrInputPosY); printf("%X", OldOne); Success = 1; Dummy = OldOne; } } while(!Success); return (Dummy); } /* end of AskForBaseAddress */ /* These variable MUST be declared as global. They are the ones whose offsets are padded to the A12DRV routine. If they are not global then the driver will not find their segment. */ unsigned pntbuf[2000],statcode,task, datbuf[2000], buffer[8000]; /* destination buffer for packed data */ int params[5]; /**************************************************************************** * FUNCTION: call_driver -- local routine * * * * PURPOSE: Performs the call to the driver package. * * * * INPUT: None. * * * * CALLS: a12drv - entry point to driver package. * * * * OUTPUT: Returns the error code supplied by the driver routine. * * * ****************************************************************************/ unsigned call_driver() { a12drv(FP_OFF(&task),FP_OFF(params),FP_OFF(&statcode)); /* this section checks for an error code */ if (statcode > 0) { printf("A status error code of %i was detected.\n",statcode); printf("Program terminated."); return(statcode); } else return(0); } /* end call_driver */ /**************************************************************************** * FUNCTION: setup -- local routine * * * * INPUT: None. * * * * CALLS: call_driver - entry point to driver package. * * * * OUTPUT: Returns the error code supplied by the driver routine. * * * ****************************************************************************/ unsigned setup() { unsigned int Address; unsigned I,status; clrscr(); puts(" SAMPLE 2.C : AD12-8"); puts("\n"); puts("This sample reads the analog inputs from an AIM-16 attached to the"); puts("AD12-8 and displays them for you."); puts("\n"); Address=AskForBaseAddress(0x350); clrscr(); puts("\n\n\nBoard Configuration:"); puts("\n"); printf(" -- BASE ADDRESS: %x hex\n",Address); puts(" -- RANGE: 5 Volt Range (required)"); puts(" -- POLARITY: Bipolar (required)"); puts(" -- IRQ: 5 -- TMR and EOC jumpered (required)"); puts(" -- AIM-16 set to Programmable Gains (required)"); puts("\n\n\n"); puts("Please press any key to continue."); getch(); params[0] = 1; /* manual setup */ params[1] = Address; ; /* starting board address */ params[2] = 5; /* IRQ5 */ params[3] = 5; /* 5V range */ params[4] = 1; /* bipolar mode */ task = 0; status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ /* now reset the task list */ task = 11; params[0] = 2; status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ /* now assign the point range for 1 AIM-16 board attached to AD12-8 channel 0 and AD12-8 channel 1 as a direct input. */ task = 5; params[0] = 0; /* point range is 0 thru 16, for a total of 17 points */ params[1] = 16; status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ /* program the counters that trigger the A/D. */ task = 14; params[0] = 1; /* set up up counter 1 */ params[1] = 3; /* to mode 3 */ params[2] = 2; /* with period 4.47 uSecs */ status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ task = 14; params[0] = 2; /* set up up counter 2 */ params[1] = 3; /* to mode 2 */ params[2] = 2237; /* with period 9.999 mSecs */ status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ /* assign ouput range to points 0 thru 16 that will convert counts to mVolts at a gain of 1. Based on 0-4095 count A/D = -5 to +5 volts. */ task = 10; params[0] = 3; params[1] = 0; params[2] = -5000; /* -5000 to 5000 is 10 volt bipolar range */ params[3] = 5000; /* which for this program is +/-5V */ status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ /* now replicate point 0 to points 1 thru 16 */ task = 10; params[0] = 4; params[1] = 0; /* replicate this point */ params[2] = 1; /* starting at this point */ params[3] = 16; /* and up to this point */ status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ /* now replicate point 0 to points 1 thru 16 */ task = 4; params[0] = 1; params[1] = 15; /* replicate this point */ params[2] = 5; /* starting at this point */ status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ return(0); } /* end setup */ /**************************************************************************** * FUNCTION: get_readings -- local routine * * * * PURPOSE: Reads the first 17 points in the point list using timer * * driven interrupts. * * * * INPUT: None. * * * * CALLS: call_driver - entry point to driver package. * * * * OUTPUT: Returns the error code supplied by the driver routine. * * * ****************************************************************************/ unsigned get_readings() { unsigned channel,gain,I,status,*temp,offpntbuf,offdatbuf; double data; int *temp1; /* now reset the task list index */ task = 11; params[0] = 1; status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ /* calculate the offset to the buffers so the driver can return the data. datbuf will contain the data read from the channels and pnt buffer will contain the channel and gain info. */ temp1 = (int *) datbuf; offdatbuf = FP_OFF(temp1); temp = pntbuf; offpntbuf = FP_OFF(temp); /* now use task 9 to do timer driven interrupt data acquisition */ /* first tell driver to start acquisition */ task = 9; params[0] = 1; /* sub task 1, interrupt scan */ params[1] = 17; /* number of points to gather */ params[2] = FP_OFF(buffer); params[3] = FP_SEG(buffer); status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ /* now wait for end of scan */ do { task = 9; params[0] = 2; /* sub task 2, wait for end of scan */ status = call_driver(); /* call routine to call ext module */ } while (params[1] != 0); if (status > 0) return(status); /* if status > 0 then error */ /* now get the read information */ task = 9; params[0] = 3; /* sub task 3 - get the data */ params[1] = offdatbuf; /* offset to data bufffer */ params[2] = offpntbuf; /* offset to the point buffer */ params[3] = 17; /* number of samples returned here */ status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ /* now if OK list the data to the screen */ printf("\n CHANNEL VALUE GAIN\n"); printf(" ------- ------ ----\n"); for (I = 0;I <= params[3] - 1;I++) { channel = (pntbuf[I] & 0xff00) / 256; /* upper bits contain ch number */ data = datbuf[I] * 0.001; /* scale millivolts to volts */ gain = (pntbuf[I] & 0x00ff); printf(" %2i %6.3f%4i\n",channel,data,gain); } return(0); } /* end get_readings */ /**************************************************************************** * FUNCTION: main -- local routine * * * * PURPOSE: Controls program flow, detects when user is ready to exit. * * * * INPUT: None. * * * * CALLS: setup - set up program and drivers. * * get_readings - read the A/D channels and display. * * * * OUTPUT: None. * * * ****************************************************************************/ void main() { unsigned status; char ch; status = setup(); /* set up program and the driver */ if (status != 0) return; /* is status > 0 then board error */ do { /* display current values for the 8 channels */ status = get_readings(); if (status != 0) return; /* if status > 0 then error */ /* check for program exit */ printf("\nPress E to exit program. Any other key to continue..."); while (!kbhit()); /* wait for key press */ ch = getch(); /* read the char */ } while (ch != 'E' && ch != 'e'); } /* end main program */