#include #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(BASE + (DACnum ? 0x0E : 0x08), count); //outport(BASE + 0x08, 0x8000); return double(count)/4096.0L*((DACnum?dacArange:dacBrange)?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 } void EEPROM_Write(unsigned int addr,unsigned int data) { outportb(BASE+0x0a,0x81);//Start Bit outportb(BASE+0x0a,0x01);//Opcode Bit 0 (01=write) outportb(BASE+0x0a,0x81);//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 outportb(BASE+0x0a,sbitd(data,15));//d15 outportb(BASE+0x0a,sbitd(data,14));//d14 outportb(BASE+0x0a,sbitd(data,13));//d13 outportb(BASE+0x0a,sbitd(data,12));//d12 outportb(BASE+0x0a,sbitd(data,11));//d11 outportb(BASE+0x0a,sbitd(data,10));//d10 outportb(BASE+0x0a,sbitd(data,9));//d9 outportb(BASE+0x0a,sbitd(data,8));//d8 outportb(BASE+0x0a,sbitd(data,7));//d7 outportb(BASE+0x0a,sbitd(data,6));//d6 outportb(BASE+0x0a,sbitd(data,5));//d5 outportb(BASE+0x0a,sbitd(data,4));//d4 outportb(BASE+0x0a,sbitd(data,3));//d3 outportb(BASE+0x0a,sbitd(data,2));//d2 outportb(BASE+0x0a,sbitd(data,1));//d1 outportb(BASE+0x0a,sbitd(data,0));//d0 outportb(BASE+0x0a,0x00);//end trans delay(20); } 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 // delay(10); // 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 CALWrite(unsigned zAM,unsigned zAB,unsigned zDAM,unsigned zDBM) { EEPROM_Write((adrange+0),zAB); EEPROM_Write((adrange+8),zAM); EEPROM_Write((dacArange+0x10),zDAM); EEPROM_Write((dacBrange+0x12),zDBM); } void CAL(void) { unsigned char zDAM, zDBM, zAM, zAB; zAB=EEPROM_Read((adrange+0))&0xff; //byte 0-7 in EEPROM holds "B" for ADC zAM=EEPROM_Read((adrange+8))&0xff; //byte 8-f in EEPROM holds "M" for ADC zDAM=EEPROM_Read((dacArange+0x10))&0xff; //byte x10,x11 in EEPROM holds "M" for DAC0 zDBM=EEPROM_Read((dacBrange+0x12))&0xff; //byte x12,x13 in EEPROM holds "M" for DAC1 CAL_DAC(0,zDAM);//write the calibration value from EEPROM to CAL Pots CAL_DAC(1,zDBM);// "" CAL_ADC(zAM,zAB);// "" } 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; // CAL(); } #define GAIN 0 #define CHANNEL 0 #define STARTCONVERSION (outportb(BASE+0,0)) #define CHECKFOREOC (!(inportb(BASE+8) & 0x80)) #define WAITFOREOC for(int timer=30000;!CHECKFOREOC && timer;timer--) #define WAITFORDATA for(int timer=30000;!CHECKFOREOC && timer;timer--) #define READADDATA inport(BASE+0) //#define READADDATA ReadADData() #define CLEARFIFO (outportb(BASE+0x01, 0)) #define CLEARUNUSEDSTATES (outportb(BASE+0x03, 0x00), outportb(BASE + 0x1D, 0x10), outportb(BASE+0x1A, 0x11)) /* unsigned short ReadADData(void) { unsigned short Result; Result = inportb(BASE + 0x00); //WAITFORDATA; Result += inportb(BASE + 0x00) * 256; return Result; } */ #define BAV 1024 double ADReading(int Ch) { unsigned data; unsigned long sumdata=0L; outportb(BASE + 0x02, Ch * 0x11); sumdata=0L; for (int i=0;i", 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 */ #define LastStep 4 void main(void) { unsigned int key, y, confirm; unsigned char CalVal[4], oCalVal[4], CurCalVal; int done = FALSE; key=1; textmode(C80); textattr(0x07); clrscr(); BASE = AskForBaseAddress(BASE); clrscr(); init(); CLEARFIFO; CLEARUNUSEDSTATES; EEPROM_Enable(); oCalVal[0]=CalVal[0]=EEPROM_Read(adrange+0)&0xff; //byte 0-7 in EEPROM holds "B" for ADC oCalVal[1]=CalVal[1]=EEPROM_Read(adrange+8)&0xff; //byte 8-f in EEPROM holds "M" for ADC oCalVal[2]=CalVal[2]=EEPROM_Read(dacArange+0x10)&0xff; //byte x10,x11 in EEPROM holds "M" for DAC0 oCalVal[3]=CalVal[3]=EEPROM_Read(dacBrange+0x12)&0xff; //byte x12,x13 in EEPROM holds "M" for DAC1 CAL_ADC(CalVal[1], CalVal[0]); CAL_DAC(0, CalVal[2]); CAL_DAC(1, CalVal[3]); outportb(BASE + 0x18, 0x01); //Put DACs in automatic mode(default, just in case) outportb(BASE+0x1d,GAIN); //configure gain setting outportb(BASE+0x2,CHANNEL); //configure channel while(!done) { if (key) { clrscr(); textattr(0x0F); cputs("104-AIO16-16 Calibration Sample\r\n"); textattr(0x07); cputs("This program will calibrate the card for the configured ranges:\r\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" ); //puts("Use ESC to exit calibration program, arrow keys to go to a different step."); DrawMenuLine(0, "A/D Offset ", TRUE); DrawMenuLine(1, "A/D Slope ", TRUE); DrawMenuLine(2, "DAC 0 Slope", TRUE); DrawMenuLine(3, "DAC 1 Slope", TRUE); DrawMenuLine(4, "Write Calib", StepsComplete == 0xF); if ( MidCalib ) { textattr(0x0A); gotoxy(20, 6); cputs("ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿"); gotoxy(20, 7); cputs("³ ³"); gotoxy(20, 8); cputs("³ ³"); gotoxy(20, 9); cputs("³ ³"); gotoxy(20, 10); cputs("³ ³"); gotoxy(20, 11); cputs("³ ³"); gotoxy(20, 12); cputs("³ ³"); gotoxy(20, 13); cputs("³ ³"); gotoxy(20, 14); cputs("³ ³"); gotoxy(20, 15); cputs("³ ³"); gotoxy(20, 16); cputs("³ ³"); gotoxy(20, 17); cputs("ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ"); gotoxy(14, 8 + step); cputs("ÄÄÄÄÄÄ´"); switch(step) { case 0: textattr(0x0F); gotoxy(22, 7); cputs("Calibrating A/D Offset"); textattr(0x07); gotoxy(24, 9); if ( adrange & 0x02 ) if ( adrange & 0x04 ) cputs("Put -4.5 volts on A/D input channel zero."); else cputs("Put -9 volts on A/D input channel zero."); else if ( adrange & 0x04 ) cputs("Put 0.5 volts on A/D input channel zero."); else cputs("Put 0.5 volts on A/D input channel zero."); gotoxy(22, 10); if ( adrange & 0x01 ) cputs("(Pin 1 of connector P1)"); else cputs("(Pins 1 (high) and 2 (low) of connector P1)"); gotoxy(24, 12); cputs("Adjust the calibration value with the arrow"); gotoxy(22, 13); cputs("keys until the voltage below is accurate."); gotoxy(22, 16); cprintf("Voltage read: Cal Value: %02X", (unsigned int)CurCalVal); gotoxy(1, 22); cputs("Press Escape to exit this step, arrows to change the value, Enter to accept."); break; case 1: textattr(0x0F); gotoxy(22, 7); cputs("Calibrating A/D Slope"); textattr(0x07); gotoxy(24, 9); if ( adrange & 0x02 ) if ( adrange & 0x04 ) cputs("Put +4.5 volts on A/D input channel zero."); else cputs("Put +9 volts on A/D input channel zero."); else if ( adrange & 0x04 ) cputs("Put 9.5 volts on A/D input channel zero."); else cputs("Put 9.5 volts on A/D input channel zero."); gotoxy(22, 10); if ( adrange & 0x01 ) cputs("(Pin 1 of connector P1)"); else cputs("(Pins 1 (high) and 2 (low) of connector P1)"); gotoxy(24, 12); cputs("Adjust the calibration value with the arrow"); gotoxy(22, 13); cputs("keys until the voltage below is accurate."); gotoxy(22, 16); cprintf("Voltage read: Cal Value: %02X", (unsigned int)CurCalVal); gotoxy(1, 22); cputs("Press Escape to exit this step, arrows to change the value, Enter to accept."); break; case 2: textattr(0x0F); gotoxy(22, 7); cputs("Calibrating DAC 0 Slope"); textattr(0x07); gotoxy(24, 9); if ( dacArange ) cputs("Outputting 4.75 volts on DAC 0."); else cputs("Outputting 9.5 volts on DAC 0."); gotoxy(24, 11); cputs("Put a meter on pin 25 of connector P1."); gotoxy(24, 13); cputs("Adjust the calibration value with the arrow"); gotoxy(22, 14); cputs("keys until the voltage is accurate."); gotoxy(54, 16); cprintf("Cal Value: %02X", (unsigned int)CurCalVal); gotoxy(1, 22); cputs("Press Escape to exit this step, arrows to change the value, Enter to accept."); break; case 3: textattr(0x0F); gotoxy(22, 7); cputs("Calibrating DAC 1 Slope"); textattr(0x07); gotoxy(24, 9); if ( dacArange ) cputs("Outputting 4.75 volts on DAC 1."); else cputs("Outputting 9.5 volts on DAC 1."); gotoxy(24, 11); cputs("Put a meter on pin 26 of connector P1."); gotoxy(24, 13); cputs("Adjust the calibration value with the arrow"); gotoxy(22, 14); cputs("keys until the voltage is accurate."); gotoxy(54, 16); cprintf("Cal Value: %02X", (unsigned int)CurCalVal); gotoxy(1, 22); cputs("Press Escape to exit this step, arrows to change the value, Enter to accept."); break; case 4: textattr(0x0F); gotoxy(22, 7); cputs("Writing Calibration To EEPROM"); textattr(0x07); gotoxy(24, 9); cputs("Press Enter to write these calibration"); gotoxy(22, 10); cputs("values to the EEPROM."); gotoxy(22, 13); cputs(" A/D A/D DAC 0 DAC 1"); gotoxy(22, 14); cputs(" Offset Slope Slope Slope"); gotoxy(22, 16); cprintf(" %02X %02X %02X %02X", (unsigned short)CalVal[0], (unsigned short)CalVal[1], (unsigned short)CalVal[2], (unsigned short)CalVal[3]); gotoxy(1, 22); cputs("Press Escape to exit this step, Enter to accept these calibration values."); //break; } } else { textattr(0x07); gotoxy(1, 22); cputs("Press Escape to exit, arrows to select a step, Enter to calibrate that step."); } } if ( MidCalib ) { switch(step) { case 0: case 1: gotoxy(36, 16); cprintf("%+.4lf", ADReading(0)); break; /* double A0, A1; A0 = ADReading(0); A1 = ADReading(1); gotoxy(36, 16); cprintf("%+.4lf", A0); gotoxy(36, 17); cprintf("%+.4lf", A1); gotoxy(36, 18); cprintf("%+.4lf", A0 - A1); break; */ } } if (!done) { if ( !kbhit() ) key = 0; else switch(key = toupper(getch())) { case 0: if ( MidCalib ) //arrow adjustment of cal values { if ( step != LastStep ) //arrow keys are ignored in confirm step { switch(key = getch()) { // Up Left case 'H': case 'K': ++CurCalVal; break; // PgUp case 'I': CurCalVal += 0x10; break; // Down Right case 'P': case 'M': --CurCalVal; break; // PgDn case 'Q': CurCalVal -= 0x10; break; default: key = 0; } if ( key ) switch(step) { case 0: CAL_ADC(CalVal[1], CurCalVal); break; case 1: CAL_ADC(CurCalVal, CalVal[0]); break; case 2: CAL_DAC(0, CurCalVal); break; case 3: CAL_DAC(1, CurCalVal); break; } } } else switch(key = getch()) //arrowing around the menu { // Up Left PgUp case 'H': case 'K': case 'I': --step; if ( step < 0 ) step = LastStep - (StepsComplete == 0xF ? 0 : 1); break; // Down Right PgDn case 'P': case 'M': case 'Q': ++step; if ( step > LastStep - (StepsComplete == 0xF ? 0 : 1) ) step = 0; break; // Home case 'G': step = 0; break; // End case 'O': step = LastStep - (StepsComplete == 0xF ? 0 : 1); break; } break; case 13: if ( MidCalib ) { if ( step == LastStep ) //Write cal values { CALWrite(CalVal[1], CalVal[0], CalVal[2], CalVal[3]); done = TRUE; } else //Store cal value { CalVal[step] = CurCalVal; StepsComplete |= (1 << step); } MidCalib = FALSE; } else //Begin adjusting cal value { if ( step < LastStep ) CurCalVal = CalVal[step]; if ( step == 2 ) DAC(0, dacArange ? 4.75 : 9.5); else if ( step == 3 ) DAC(1, dacBrange ? 4.75 : 9.5); MidCalib = TRUE; } break; case 27: if ( MidCalib ) MidCalib = FALSE; else done = TRUE; break; } } } EEPROM_Disable(); textattr(0x07); clrscr(); puts("Done."); } /**/