/* DOS program to read the voltage level on one of the A/D inputs. Syntax: ANIN CHANNEL Optional LPT port number - defaults to LPT1 CHANNEL Analog input channel number (0 - 13) Note: Channels 11-13 are internal test channels. */ #include #include #include #define LPT1 0x00400008 /* BIOS printer address entries */ #define LPT2 0x0040000a #define LPT3 0x0040000c #define LPT4 0x0040000e #define INIT 0x04 /* Printer port "INIT" signal */ #define ERROR 0x08 /* Printer port "ERROR" signal */ #define SELECT 0x08 /* Chip select signal to A/D converter */ #define CLOCK 0x02 /* Clock signal to A/D converter */ #define ADDR 0x01 /* Address signal to A/D converter */ #define EOC 0x40 /* End-Of-Conversion mask */ #define DOUT 0x10 /* Data output mask */ /*--------------------- Prototype Declarations --------------------------*/ void send_addr(unsigned int port,unsigned int channel); int get_data(unsigned int port); /*--------------------- Program starts here -----------------------------*/ int main(int argc, char *argv[]) { unsigned int port, /* Parallel port address */ channel; /* A/D channel to read */ unsigned int far *bios_printer_addr; float data; /* A/D data read from channel */ char status; /* Status of control port */ int lpt_number; /* LPT port number */ switch(argc) { case 1: printf("Read & display the voltage level on the specified analog input.\n\n"); printf("ANIN CHANNEL\n\n"); printf(" Optional LPT port number - defaults to LPT1.\n"); printf("CHANNEL Analog input channel number (0 - 13).\n\n"); printf("Note: Channels 11-13 are internal test channels.\n\n"); printf("On exit, ERRORLEVEL = 1 if parameter error.\n\n"); printf(" ERRORLEVEL = 2 if time out on End-Of-Conversion.\n"); exit(0); case 2: if (argv[1][0]=='/') { puts("Missing channel number"); exit(1); } port=*(bios_printer_addr=LPT1); if (port==NULL) { puts("LPT1 does not exist"); exit(1); } sscanf(argv[1],"%d",&channel); break; case3: case 3: if (argv[1][0]=='/') lpt_number=atoi(argv[1]+1); switch(lpt_number) { case 1 : port=*(bios_printer_addr=LPT1); if (port==NULL) { puts("LPT1 does not exist"); exit(1); } sscanf(argv[2],"%d",&channel); break; case 2 : port=*(bios_printer_addr=LPT2); if (port==NULL) { puts("LPT2 does not exist"); exit(1); } sscanf(argv[2],"%d",&channel); break; case 3 : port=*(bios_printer_addr=LPT3); if (port==NULL) { puts("LPT3 does not exist"); exit(1); } sscanf(argv[2],"%d",&channel); break; case 4 : port=*(bios_printer_addr=LPT4); if (port==NULL) { puts("LPT4 does not exist"); exit(1); } sscanf(argv[2],"%d",&channel); break; default: puts("Invalid printer port"); exit(1); } } if ((channel>13) || (channel<0)) { puts("Invalid channel number"); exit(1); } status=inportb(port+2); /* Save control port status */ outportb(port+2,status&~SELECT); /* "CS" high */ delay(1); outportb(port,~CLOCK); /* "CLK" low */ delay(1); send_addr(port,channel); /* Select A/D converter, Clock in 4-bit address, Issue 6 more clocks cycles Deselect A/D converter */ while (!(inportb(port+1)&EOC)); /* Wait for EOC high */ data=(float)get_data(port)/1024*5; /* Read data from A/D converter and convert into decimal */ printf("Analog channel %d = %4.3fV\n",channel,data); outportb(port+2,status); /* Restore control port status */ return 0; } /*------------------------------------------------------------------------*/ /* Send channel address to A/D converter chip Also send remaining 6 clock cycles */ void send_addr(unsigned int port, unsigned int channel) { int x; char status; status=inportb(port+2); /* Save control port status */ outportb(port+2,status|SELECT); /* Select A/D chip ("CS" low) */ for (x=0; x<11; x++) /* Clock in address + 6 more clocks */ { delay(1); if (channel&0x0008) /* Is address bit high? */ { outportb(port,ADDR); /* Yes, set "ADDR" pin high */ outportb(port,ADDR|CLOCK); /* "CLK" high */ delay(1); outportb(port,ADDR); /* "CLK" low */ } else { outportb(port,CLOCK&ADDR); /* No, set "ADDR" pin low */ outportb(port,CLOCK); /* "CLK" high */ delay(1); outportb(port,CLOCK&ADDR); /* "CLK" low */ } channel=channel<<1; /* Shift in next address bit */ } outportb(port+2,status&~SELECT); /* "CS" high */ delay(1); } /*------------------------------------------------------------------------*/ /* Get serial data from A/D converter chip and return it */ int get_data(unsigned int port) { int data=0, /* Holds data read */ x; char status; status=inportb(port+2); /* Save control port status */ outportb(port+2,status|SELECT); /* Select A/D chip ("CS" low */ for (x=0; x<10; x++) /* Clock out 10 data bits */ { delay(1); data=data<<1; /* Shift bits along */ if (inportb(port+1)&DOUT) /* Is data bit high? */ data=data|0x0001; /* Yes, "data" bit = 1 */ else data=data&0xfffe; /* No, "data" bit = 0 */ outportb(port,CLOCK); /* "CLK" high */ delay(1); outportb(port,~CLOCK); /* "CLK" low */ } outportb(port+2,status&~SELECT); /* "CS" high */ return(data); }