/**************************************************************************** * C LANGUAGE SAMPLE 2: SAMPLE2.C * * * * This is a demonstration program to be used with the AIO8 card. * * board. The program will display channels of data acquired from the card* * using interrupts. The eight cvhannels of the AIO8 are read, as the * * program assumes that no sub-multiplexer card is attached. * * This program must be built using the large model. * * * * LAST MODIFICATION: 2/4/98 * * * ****************************************************************************/ #include #include #include #include #include #include #include "aio8drvc.h" /* These variable MUST be declared as global. They are the ones whose offsets are padded to the AIO8DRV routine. If they are not global then the driver will not find their segment. */ unsigned pntbuf[20],statcode,task; int datbuf[20],params[5]; 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 */ /**************************************************************************** * FUNCTION: call_driver -- local routine * * * * PURPOSE: Performs the call to the driver module. * * * * INPUT: None. * * * * CALLS: aio8drv - entry point to driver module. * * * * OUTPUT: Returns the error code supplied by the driver routine. * * * ****************************************************************************/ unsigned call_driver(void) { aio8drv(FP_OFF(&task),FP_OFF(params),FP_OFF(&statcode)); /* this section checks for an error code */ if (statcode > 0 && statcode != 14) { 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 * * * * PURPOSE: Performs the setup of the driver. * * * * INPUT: None. * * * * CALLS: call_driver - entry point to driver module. * * * * OUTPUT: Returns the error code supplied by the driver routine. * * * ****************************************************************************/ unsigned setup(void) { unsigned I,status; unsigned int Address; clrscr(); puts("\n Sample 2 : AIO8"); puts("\nThis sample reads the eight analog inputs from the AIO8 and displays"); puts("them in volts for you.\n"); Address=AskForBaseAddress(0x350); clrscr(); puts("\n\n\nBoard Configuration:\n"); printf(" -- Base Address is %X hex\n",Address); puts(" -- Jumper IRQ5 should be installed (required)"); puts(" -- Jumper EXT should be installed (required)"); puts(" -- Jumper pin 24 to pin 6 on the external connector (required)"); puts(" -- All remaining jumper settings are irrelevant.\n\n\n\n"); puts("Please press any key to continue."); getch(); task = 0; params[0] = Address; /* starting board address */ params[1] = 1; /* manual initialization */ params[2] = 1; /* manual gain mode, which is good for no AIM-16 */ status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ /* assign ouput range to the point address corresponding to the point address of the AIO8, 0,16,32,48,64,80,96,112. Based on 0-4095 count A/D = -5 to +5 volts. */ for (I = 0;I < 8;I++) { /* install point address in point list */ task = 5; params[0] = I * 16; /* first point in range */ params[1] = I * 16; /* last point in range */ status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ /* now set range for this point address */ task = 10; params[0] = 3; params[1] = I * 16; params[2] = -5000; /* -5000 to 5000 is 10 volt range */ params[3] = 5000; /* which +/-5V */ status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ } /* set up counter to supply interrupts */ task = 14; params[0] = 2; /* set up up counter 2 */ params[1] = 3; /* to mode 3 */ params[2] = 1000; status = call_driver(); /* call routine to call ext module */ if (status > 0) return(status); /* if status > 0 then error */ /* set the sample and hold settle time */ task = 11; params[0] = 5; params[1] = 25; 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 points in the point list using timer * * driven interrupts. * * * * INPUT: None. * * * * CALLS: call_driver - entry point to driver module. * * * * OUTPUT: Returns the error code supplied by the driver routine. * * * ****************************************************************************/ unsigned get_readings(void) { unsigned channel,I,status; double data; /* 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 */ /* 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] = 5; /* IRQ 5 */ params[2] = 8; /* number of points to gather */ params[3] = FP_OFF(datbuf); params[4] = FP_OFF(pntbuf); 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 if OK list the data to the screen */ clrscr(); printf("\n CHANNEL VALUE\n"); printf(" ------- ------\n"); for (I = 0;I < 8;I++) { channel = (pntbuf[I] & 0xff00) / 256; /* upper bits contain ch number */ data = datbuf[I] * 0.001; /* scale millivolts to volts */ printf("%9i%13.3f\n",channel,data); } 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(void) { 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 */