di3028.txt From EDN, July 10, 2003, "Interface a serial 12-bit ADC to a PC." EDN030403DI3208-LISTING 1 /****************************************************************************/ /**** Program to Read Data From MAX187 ****/ /**** By: D.S.Oberoi and Harinder Dhingra ****/ /***************************************************************************/ #include #include #include #define Port 0x378 /* Port where teh ADC is interfaced */ #define Write_Port Port /* Write port of ADC*/ #define Read_Port Port + 1 /* Read Port of ADC*/ #define CS_high_SCLK_low 0x80 /* CS is high and SCLK is low value*/ #define CS_low_SCLK_low 0x00 /* CS is low and SCLK is low value*/ #define CS_low_SCLK_high 0x01 /* CS is low and SCLK is high value*/ #define SCLK 12 /* No. of clock cucle required */ void screen_display(); /* Intial Screen*/ int get_adc(); /* Get value from ADC */ int DO, value, adc_val; /* Variables */ main() { char ch; screen_display(); for (;ch != 'q';) /* Endless Loop till 'q' is pressed */ { outp(Write_Port, CS_high_SCLK_low); /* Make CS High, SCLK is Low */ outp(Write_Port, CS_low_SCLK_low); /* Enable the ADC */ while ( ~(inp(Read_Port) & 0x80) == 1) /* Check for the EOC, bit is inverted */ { ; } outp(Write_Port,CS_low_SCLK_high); /* Make SCLK High */ /* Make SCLK Low, to get first bit as serial data is changed at the falling edge of th clock*/ outp(Write_Port, CS_low_SCLK_low); value = get_adc(); /* Call the ADC conversion Routine */ /* Print the Data on the screen */ gotoxy(29, 13); cprintf(" "); gotoxy(29,13); cprintf("%1.4f %d", (4.096/4096.0)*value, value); if(kbhit()) ch = getch(); /* check for 'q' key */ } /*--- End of the FOR Loop ---*/ } /*--- End of the MAIN Program ---*/ int get_adc() { int sclk; adc_val= 0; for( sclk= (SCLK-1); sclk>=0; sclk--) { outp(Write_Port, CS_low_SCLK_high); /* Make SCLK high, data bit to be read at this point */ DO = (~(inp(Read_Port)) & 0x80); /* Inverted value in true form */ if (DO == 0x80 ) /* Isolated the MSB bit */ adc_val = pow(2, sclk) + adc_val ; /* Serial shift to left to get the exact value */ outp(Write_Port, CS_low_SCLK_low); /* Make SCLK low, for next data bit on DO pin */ } return adc_val; } /*--- To display the initial Screen ---*/ void screen_display() { clrscr();textcolor(YELLOW); gotoxy(21,2); cprintf("Analog to Digital Conversion using MAX187"); gotoxy(33,11);cprintf("Analog Value"); gotoxy(30,12); cprintf("Volts Value"); gotoxy(20,22); cprintf("< Press q key to Quit the Program > "); }