#include #include #include #include #include #define TRUE 1 #define FALSE 0 unsigned int BASE=0x300; unsigned char jumpers; unsigned char adrange; unsigned char dacBrange; unsigned char dacArange; //sbitd takes data and bit, then returns 0x81 or 0x01 based on data[bit] unsigned char sbitd(unsigned int data,unsigned char bit) { return (data & (1< 0xFFF ) count = 0xFFF; else if (count < 0 ) count = 0; outport(DACAddr, count); //Load counts into input register //outport(BASE + 0x08, 0x8000); //Load input register into DAC return double(count)/4096.0L*((DACnum?dacBrange:dacArange)?5.0L:10.0L); //actual V } void EEPROM_Enable(void) { outportb(BASE+0x0a,0x81);//start bit outportb(BASE+0x0a,0x01);//Opcode bit 0 (00 = enable/disable) outportb(BASE+0x0a,0x01);//Opcode bit 1 "" outportb(BASE+0x0a,0x81);//a5 (must be 1 to enable) outportb(BASE+0x0a,0x81);//a4 (must be 1 to enable) outportb(BASE+0x0a,0x01);//a3 (don't care because enable/disable) outportb(BASE+0x0a,0x01);//a2 (don't care because enable/disable) outportb(BASE+0x0a,0x01);//a1 (don't care because enable/disable) outportb(BASE+0x0a,0x01);//a0 (don't care because enable/disable) outportb(BASE+0x0a,0x00);//end trans } void EEPROM_Disable(void) { outportb(BASE+0x0a,0x81);//start bit outportb(BASE+0x0a,0x01);//Opcode bit 0 (00 = enable/disable) outportb(BASE+0x0a,0x01);//Opcode bit 1 "" outportb(BASE+0x0a,0x01);//a5 (must be 0 to disable) outportb(BASE+0x0a,0x01);//a4 (must be 0 to disable) outportb(BASE+0x0a,0x01);//a3 (don't care because enable/disable) outportb(BASE+0x0a,0x01);//a2 (don't care because enable/disable) outportb(BASE+0x0a,0x01);//a1 (don't care because enable/disable) outportb(BASE+0x0a,0x01);//a0 (don't care because enable/disable) outportb(BASE+0x0a,0x00);//end trans } unsigned int EEPROM_Read(unsigned int addr) { unsigned int data=0; outportb(BASE+0x0a,0x81);//Start Bit outportb(BASE+0x0a,0x81);//Opcode Bit 0 (10=Read) outportb(BASE+0x0a,0x01);//Opcode Bit 1 "" outportb(BASE+0x0a,sbitd(addr,5));//a5 (address to write to) outportb(BASE+0x0a,sbitd(addr,4));//a4 outportb(BASE+0x0a,sbitd(addr,3));//a3 outportb(BASE+0x0a,sbitd(addr,2));//a2 outportb(BASE+0x0a,sbitd(addr,1));//a1 outportb(BASE+0x0a,sbitd(addr,0));//a0 inportb(BASE+0x0a);//dummy bit data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d15 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d14 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d13 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d12 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d11 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d10 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d9 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d8 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d7 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d6 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d5 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d4 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d3 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d2 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d1 data=(data<<1) | ((inportb(BASE+0x0a) & 0x80)?1:0);//d0 outportb(BASE+0x0a,0x00);//end com return data; } void CAL_ADC(unsigned char M,unsigned char B) { //write cal to A/D, offset first, then slope outportb(BASE+0x0b,0x01);//a1 pot 00 is offset outportb(BASE+0x0b,0x01);//a0 "" outportb(BASE+0x0b,sbitd(B,7));//data bit 7 of offset outportb(BASE+0x0b,sbitd(B,6));//data bit 6 of offset outportb(BASE+0x0b,sbitd(B,5));//data bit 5 of offset outportb(BASE+0x0b,sbitd(B,4));//data bit 4 of offset outportb(BASE+0x0b,sbitd(B,3));//data bit 3 of offset outportb(BASE+0x0b,sbitd(B,2));//data bit 2 of offset outportb(BASE+0x0b,sbitd(B,1));//data bit 1 of offset outportb(BASE+0x0b,sbitd(B,0));//data bit 0 of offset outportb(BASE+0x0b,0x00);//end trans //write slope now outportb(BASE+0x0b,0x01);//a1 pot 01 is slope of A/D outportb(BASE+0x0b,0x81);//a0 pot 01 is slope of A/D outportb(BASE+0x0b,sbitd(M,7));//data bit 7 of slope outportb(BASE+0x0b,sbitd(M,6));//data bit 6 of slope outportb(BASE+0x0b,sbitd(M,5));//data bit 5 of slope outportb(BASE+0x0b,sbitd(M,4));//data bit 4 of slope outportb(BASE+0x0b,sbitd(M,3));//data bit 3 of slope outportb(BASE+0x0b,sbitd(M,2));//data bit 2 of slope outportb(BASE+0x0b,sbitd(M,1));//data bit 1 of slope outportb(BASE+0x0b,sbitd(M,0));//data bit 0 of slope outportb(BASE+0x0b,0x00);//end trans } void CAL_DAC(unsigned char DACNum,unsigned char M) { outportb(BASE+0x0b,0x81);//a1 pot 10 is slope of DAC0 outportb(BASE+0x0b,sbitd(DACNum,0));//a0 pot 11 is slope of DAC1 outportb(BASE+0x0b,sbitd(M,7));//data bit 7 of slope outportb(BASE+0x0b,sbitd(M,6));//data bit 6 of slope outportb(BASE+0x0b,sbitd(M,5));//data bit 5 of slope outportb(BASE+0x0b,sbitd(M,4));//data bit 4 of slope outportb(BASE+0x0b,sbitd(M,3));//data bit 3 of slope outportb(BASE+0x0b,sbitd(M,2));//data bit 2 of slope outportb(BASE+0x0b,sbitd(M,1));//data bit 1 of slope outportb(BASE+0x0b,sbitd(M,0));//data bit 0 of slope outportb(BASE+0x0b,0x00);//end trans } void CAL(void) { unsigned char DAM, DBM, AM, AB; AB=EEPROM_Read(adrange+0); //byte 0-7 in EEPROM holds "B" for ADC AM=EEPROM_Read(adrange+8); //byte 8-f in EEPROM holds "M" for ADC DAM=EEPROM_Read(dacArange+0x10); //byte x10,x11 in EEPROM holds "M" for DAC0 DBM=EEPROM_Read(dacBrange+0x12); //byte x12,x13 in EEPROM holds "M" for DAC1 CAL_DAC(0,DAM);//write the calibration value from EEPROM to CAL Pots CAL_DAC(1,DBM);// "" CAL_ADC(AM,AB);// "" } void init(void) { jumpers=inportb(BASE+0x08);//jumper configuration readback adrange=jumpers & 0x07;//d2,d1,d0 are 5/10, uni/bip, 16/8 dacBrange=(jumpers>>3) & 0x01;//d4,d3 are 5/10 for daca,b dacArange=(jumpers>>4) & 0x01; outportb(BASE + 0x1B, 0x01); //Select counters 1 & 2 for A/D start // CAL(); clrscr(); puts("104-AIO1616W Sample\n"); cprintf("A/D: %s %s\r\n" "DAC A: %s\r\n" "DAC B: %s", (adrange&0x02)? ((adrange&0x04)?"ñ5V":"ñ10V") : ((adrange&0x04)?"0-10V":"0-10V(Low Res)") //0-10V(Low Res) is , //in theory 0-20V, (adrange&0x01)?"16ch":"8ch", //but the amps cap dacArange?"0-5V":"0-10V", //at 10V dacBrange?"0-5V":"0-10V" ); } unsigned AskForBaseAddress(unsigned int OldOne) { char msg[8]; int NewOne = 0, Success = 0, Dummy; int AddrInputPosX, AddrInputPosY; puts("Please enter the Base Address (100-FFFF) 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); if (NewOne >= 0x100) { Success = 1; Dummy = NewOne; } else if (msg[1] == 0) { gotoxy(AddrInputPosX, AddrInputPosY); printf("%X", OldOne); Success = 1; Dummy = OldOne; } } while(!Success); return (Dummy); } /* end of AskForBaseAddress */ void DacSample(void) { char key=0; double percent=0; char done=0; puts("This sample will write to DAC 0 and DAC 1."); puts("Press 1-0 keys for 10% to 100% DAC value, use \"~\" for 0%"); puts("Press ESC to exit sample"); outportb(BASE + 0x18, 0x01); do{ key=getch(); if (key==27) done=1; if (isdigit(key)) percent=(key-'0')/10.0L; if ((key=='`') || (key=='~')) percent=0.0; if (key=='0') percent=1.0L; //if (key == ' ') { outport(BASE + 0x08, 0x8000); continue; } gotoxy(1,20); printf("Writing to DAC 0: %3.2lf\n",DAC(0,percent*(dacArange?4.9988L:9.9976L))); printf("Writing to DAC 1: %3.2lf\n",DAC(1,(1.0L-percent)*(dacBrange?4.9988L:9.9976L))); }while (!done); puts("Done."); } void ADSample(void) #define CLEARUNUSEDSTATES (outportb(BASE+0x03, 0x00), outportb(BASE + 0x1D, 0x10), outportb(BASE+0x1A, 0x22)) #define STARTCONVERSION (outportb(BASE+0,0)) #define CHECKFOREOC (!(inportb(BASE+8) & 0x80)) #define WAITFOREOC for(int timer=10000;!CHECKFOREOC && timer;timer--) #define WAITFORDATA for(int timer=10000;!CHECKFOREOC && timer;timer--) #define READADDATA (inport(BASE+0)) { int done=0; unsigned data,CHANNEL; float ADMul, FData; unsigned int ADSpan, ADOffset; clrscr(); puts("Free Run A/D, Gain Code 0, polling FIFO\n"); puts("Press ESC to exit."); ADSpan = (adrange&0x04)?10.0:20.0; ADOffset = (adrange&0x02) ? (ADSpan / 2) : 0; ADMul = (float)ADSpan / (float)0x10000; CHANNEL = (adrange & 0x01) ? 0xF0 : 0x70; CLEARUNUSEDSTATES; inportb(BASE+0x07); //reset gains outportb(BASE+0x02, CHANNEL); //configure channels outportb(BASE+0x01, 0); //clear FIFO CHANNEL = 0; do{ STARTCONVERSION; WAITFORDATA; gotoxy(1,CHANNEL+9); data=READADDATA; FData = data * ADMul - ADOffset; printf("Current AD channel %1X Reading:%04X = %f ",CHANNEL,data,FData); CHANNEL = (CHANNEL + 1) % ((adrange & 0x01) ? 16 : 8); if (timer<=0) cputs("<--AD TIMEOUT\n\r"); if (kbhit()) if (getch()==27) done=TRUE; }while (!done); } void main(void) { char done=FALSE; clrscr(); BASE = AskForBaseAddress(BASE); do{ init(); puts("\n\nSelect which sample to run:\n 1. DAC Sample\n 2. A/D Sample\n 0. Exit Program\n"); switch(toupper(getch())) { case '1':case 'D':DacSample();break; case '2':case 'A':ADSample();break; case '0':case '3':case 'X':case 27:done=TRUE;break; }//end switch }while (!done); puts("\nDone."); }