circuits
schematics
diagrams
FreeCircuits.net
18-bit ADC uses PC's serial port
By internum
Figure 1. You can use a PC’s serial port to communicate with an 18-bit A/D converter.
A PC usually requires a plug-in ADC card to process analog signals. However, with the circuitry in Figure 1, a PC can communicate with an 18-bit ADC through its serial port. The port provides both positive and negative power supplies as well as control signals. IC1 is an 18-bit MAX132 ADC with a serial interface. It requires three input control signals, , DIN, and SCLK, and emits serial data, DOUT, and EOC (end-of-conversion) signals. An RS-232 port has three output lines: Pin 3 (TX), Pin 4 (DTR), and Pin 7 (RTS). TX generates the clock signal for the MAX132 and provides the negative power supply. DTR transmits serial data. RTS provides the CS signal and the positive power supply. Both the positive and the negative supplies use large capacitors for energy storage. When TX generates a clock signal or DTR sends a CS logic-low signal, the capacitors provide power to the MAX132. The MAX132 integrates everything except a reference that comes from a 1.2V LM385 voltage-reference diode, D1. The input-voltage range of the MAX132 is -512 to +512 mV. Listing 1 is a C program that displays the analog-to-digital-conversion result on-screen.
Listing 1
#include <stdio.h> #include <dos.h> #include <time.h> #include <conio.h> #include <bios.h> #include <conio.h> #define COM1 0 #define MCR 4 /* control register */ #define MSR 6 /* status register */ int i, j, base_add1=0x3f8, base_add2=0x2f8, out_data=0x03, in_data[4]; float data; void send_clk(void) { delay(1); outportb(base_add1, 0x00); delay(3); } void read_port(void) { int control[4], out_control; data=0; for (i=0; i<4; i++) in_data[i]=0; control[0]=0x82; control[1]=0x04; control[2]=0x00; control[3]=0x00; out_data|=0x02; outportb(base_add1+MCR, out_data); /* CS high */ delay(10); out_data&=0x01; outportb(base_add1+MCR, out_data); /* CS low */ delay(10); out_control=control[0]; for (i=0; i<8; i++) { if (out_control>=0x80) out_data|=0x01; else out_data&=0x02; outportb(base_add1+MCR, out_data); send_clk(); /* clock out */ out_control&=0x7f; out_control=out_control*2; } out_data|=0x02; outportb(base_add1+MCR, out_data); /* CS high */ delay(10); do{ }while((inportb(base_add1+MSR)&0x40)==0); /* waiting for EOC=high */ for (j=1; j<4; j++) { out_control=control[j]; in_data[j]=0; out_data&=0x01; outportb(base_add1+MCR, out_data); /* CS low */ delay(10); for (i=0; i<8; i++) { if (out_control>=0x80) out_data|=0x01; else out_data&=0x02; outportb(base_add1+MCR, out_data); in_data[j]=in_data[j]*2+(inportb(base_add1+MSR)&0x80)/0x80; send_clk(); /* clock out */ out_control&=0x7f; out_control=out_control*2; } out_data|=0x02; outportb(base_add1+MCR, out_data); /* CE high */ delay(10); } if ((in_data[1]&0x08)==0) data=(float)(in_data[1]&0x07)+(float)(in_data[2])*2048+(float)(in_data[3])*8; else /* reading is negative */ { in_data[1]=in_data[1]&0x07; in_data[1]=(8-in_data[1])&0x07; in_data[2]=(256-in_data[2])&0xff; in_data[3]=(256-in_data[3])&0xff; data=-((float)(in_data[1])+(float)(in_data[2])*2048+(float)(in_data[3])*8); } } void dis_data(void) { float show_data; show_data=0.000002*data; gotoxy(1,1); printf("%.5f ", show_data); gotoxy(1,1); } void init(void) { bioscom(0, 255, COM1); /* set up COM1 */ out_data=0x02; outportb(base_add1+MCR, out_data); /* CS=high, DIN=low */ delay(100); } void main(void) { clrscr(); init(); gotoxy(60,24); printf("Hit any key to quit"); do{ read_port(); dis_data(); delay(500); } while(!kbhit()); }
882 19 September 2009