📄 ana_io.c
字号:
/*ana_io.c*/
/*12bit, 8 channel ADC and 8 bit 8 channel DAC interface
Uses MAX186 and MAX521
Dhananjay V. Gadre*/
#include<stdio.h>
#include<dos.h>
#include<time.h>
#include <conio.h>
#include <process.h>
/* D5 is SDA = data; D6 is SCL=clock */
#define H_H 0xff
#define H_L 0xdf
#define L_H 0xbf
#define L_L 0x9f
#define TRUE 1
#define FALSE 0
/*ADC control bytes for the 8 channels*/
unsigned char adc_con_byte[8];
/* Global variable has address of DATA port of LPT1 */
unsigned int dport_lpt1; /* data port address*/
unsigned char dport_value, cport_value; /*data and control port status*/
/*Check if LPT1 is present*/
int chk_lpt(void);
/* This generates the SLAVE address for the MAX-521 */
void set_up(void);
/*MAX521 start sequence*/
void st_seq(void);
/*MAX521 end sequence*/
void end_seq(void);
/* sets DAC address & the corresponding value */
void out_to_dac(unsigned int dac_number, unsigned int dac_value);
/*check if ADC is connected*/
int chk_adc(void);
/*start ADC conversion and get the result*/
int read_adc(int channel_number);
void st_seq(void)
{
unsigned int tempa;
tempa=inportb(dport_lpt1) & 0x9f;
tempa=tempa | (0x60 & H_H);
/* Generate start sequence for MAX-521*/
outportb(dport_lpt1, tempa);
tempa= tempa & 0x9f;
tempa= tempa | (H_L & 0x60);
outportb(dport_lpt1, tempa);
tempa=tempa & L_L;
outportb(dport_lpt1, tempa);
}
void end_seq(void)
{
unsigned char tempb;
tempb=inportb(dport_lpt1) & 0x9f;
tempb=tempb | (0x60 & H_L);
/* generate stop sequence */
outportb(dport_lpt1, tempb);
tempb=tempb | (0x60 & H_H);
outportb(dport_lpt1, tempb);
}
int chk_lpt(void)
{
/*Get LPT1 port addresses */
dport_lpt1 = peek(0x40,0x08);
if(dport_lpt1 == 0) return FALSE;
return TRUE;
}
int chk_adc(void)
{
unsigned char temp1;
outportb(dport_lpt1+2, 0x01);
temp1=inportb(dport_lpt1);
temp1=temp1 & 0x7e;
outportb(dport_lpt1, temp1);
temp1=inportb(dport_lpt1+2);
temp1=temp1 & 0xfe;
outportb(dport_lpt1+2, temp1);
delay(10);
temp1=inportb(dport_lpt1+1);
temp1=temp1 & 0x80;
if(temp1 ) return FALSE;
temp1=inportb(dport_lpt1+2);
temp1=temp1 | 0x01;
outportb(dport_lpt1+2, temp1);
delay(10);
temp1=inportb(dport_lpt1+1);
temp1=temp1 & 0x80;
if(!temp1) return FALSE;
adc_con_byte[0]=0x8f;
adc_con_byte[1]=0xcf;
adc_con_byte[2]=0x9f;
adc_con_byte[3]=0xdf;
adc_con_byte[4]=0xaf;
adc_con_byte[5]=0xef;
adc_con_byte[6]=0xbf;
adc_con_byte[7]=0xff;
return TRUE;
}
/*start ADC conversion and get the result*/
int read_adc(int channel_number)
{
int adc_val, temp_val;
unsigned char temp1, temp2, temp3, data[20];
long loop;
outportb(dport_lpt1+2, 0x01);
temp1=adc_con_byte[channel_number];
for(temp2=0; temp2<8; temp2++)
{
temp3= (temp1 << temp2) & 0x80;
temp3=temp3 & 0x81;
dport_value=inportb(dport_lpt1);
dport_value=dport_value & 0x7e;
dport_value=dport_value | temp3;
outportb(dport_lpt1, dport_value);
dport_value=dport_value | 1;
outportb(dport_lpt1, dport_value);
outportb(dport_lpt1, dport_value);
/* this is to make the clk 50% duty cycle*/
/* Duty cycle as measured with a 66 MHz 486 is 48% */
dport_value=dport_value & 0xfe;
outportb(dport_lpt1, dport_value);
}
dport_value=dport_value & 0x7f;
outportb(dport_lpt1, dport_value);
for(temp2=0; temp2<16; temp2++)
{
dport_value = dport_value & 0x7e;
dport_value=dport_value | 0x01;
outportb(dport_lpt1, dport_value);
data[temp2]=( inportb(dport_lpt1+1) & 0x80);
dport_value=dport_value & 0xfe;
outportb(dport_lpt1, dport_value);
outportb(dport_lpt1, dport_value);
}
adc_val=0;
for(temp2=0; temp2<16; temp2++)
{
temp_val=( (unsigned int) data[temp2] & 0x00ff) << 8;
adc_val= adc_val | ( (temp_val ^ 0x8000) >> temp2);
}
adc_val=adc_val>> 3;
return adc_val;
}
void set_up(void)
{
unsigned char temp, sda_val=0x50, tempx;
/*sda_val is set for AD1=AD0=0*/
unsigned int lp_count;
/* Read DATA port */
temp=inportb(dport_lpt1);
/* Send Slave address byte */
for (lp_count=0; lp_count<8; lp_count++)
{
/* Send SDA */
temp=temp & L_L;
tempx=sda_val & 0x80;
tempx = (tempx >> 2) & 0x20;
temp = tempx | temp;
outportb(dport_lpt1, temp);
/* setup SCL */
temp = temp | 0x40 ;
outportb(dport_lpt1, temp);
/* reset SCL */
temp = temp & L_H;
outportb(dport_lpt1, temp);
/* get new value for SDA */
sda_val = sda_val <<1;
}
/* Send ack */
temp = temp & 0x9f;
outportb(dport_lpt1, temp);
temp = temp | 0x40;
outportb(dport_lpt1, temp);
temp = temp & 0x9f;
outportb(dport_lpt1, temp);
}
void out_to_dac(unsigned int dac_number, unsigned int dac_value)
{
unsigned char dac_address, tempy;
unsigned int counter, value, temp1;
temp1=inportb(dport_lpt1);
dac_address = 0x07 & ( (char) dac_number) ;
value = (char) dac_value;
/* Send command byte to MAX-521 */
/* Set DAC address into MAX-521 */
for(counter=0; counter<8; counter++)
{
temp1 = temp1 & L_L;
tempy=dac_address & 0x80;
tempy = (tempy >> 2) & 0x20;
temp1 = tempy | temp1;
outportb(dport_lpt1, temp1);
temp1 = temp1 | 0x40;
outportb(dport_lpt1, temp1);
temp1 = temp1 & L_H;
outportb(dport_lpt1, temp1);
dac_address = dac_address << 1;
}
/* Send ack */
temp1 = temp1 & 0x9f;
outportb(dport_lpt1, temp1);
temp1 = temp1 | 0x40;
outportb(dport_lpt1, temp1);
temp1 = temp1 & 0x9f;
outportb(dport_lpt1, temp1);
/* Send value to the selected DAC */
for(counter=0; counter<8; counter++)
{
temp1 = temp1 & L_L;
tempy = value & 0x80;
tempy = (tempy >> 2) & 0x20;
temp1 = tempy | temp1;
outportb(dport_lpt1, temp1);
temp1 = temp1 | 0x40;
outportb(dport_lpt1, temp1);
temp1 = temp1 & L_H;
outportb(dport_lpt1, temp1);
value = value << 1;
}
/* Send ack */
temp1 = temp1 & 0x9f;
outportb(dport_lpt1, temp1);
temp1 = temp1 | 0x40;
outportb(dport_lpt1, temp1);
temp1 = temp1 & 0x9f;
outportb(dport_lpt1, temp1);
}
void main(void)
{
clrscr();
printf("\nMulti-channel Analog I/O for the PC");
printf("\n8 Channel 12-bit ADC");
printf("\n8 Channel 8-bit DACs");
printf("\nDhananjay V. Gadre, 1996.\n\n");
if( chk_lpt() == FALSE)
{printf("\nNo Parallel Port. Aborting..."); exit(1);}
outportb(dport_lpt1, 0xff);
if( chk_adc() == FALSE)
{printf("\nNo ADC Connected. Aborting..."); exit(1);}
/*Convert voltage on ADC channel*/
printf("\nADC Channel 2 Value = %d mV", read_adc(2) );
printf("\n\nProgramming the 8 DACs..");
/*Program the DACs*/
/* Generate start sequence for MAX-521*/
st_seq();
/*setup address*/
set_up();
/*output to the DACs*/
out_to_dac(0, 0);
out_to_dac(1, 0x20);
out_to_dac(2, 0x40);
out_to_dac(3, 0x60);
out_to_dac(4, 0x80);
out_to_dac(5, 0xa0);
out_to_dac(6, 0xc0);
out_to_dac(7, 0xe0);
/* generate stop sequence */
end_seq();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -