📄 rtidrv.c
字号:
/*****************************************************************************
***FILE: RTI_DRV.C (Analog Devices - RTI-815 DACA board) ***
******************************************************************************
**** ****
**** Digital IO routines for the RTI DACA board ****
**** Also, note the the dig_in routine casts the incoming data as ****
**** an integer (2 bytes in C) and dig_out writes it to the port ****
**** as an unsigned int... definitely 2 different types. However, ****
**** this is not a problem (i.e. both need not be the same) unless ****
**** math operations are performed. Then, the binary number at the ****
**** port is interpreted and calcs done accordingly. The data at ****
**** the port is binary and is just carried into the routines using ****
**** some casting. ****
**** ****
**** In dig_out, the data is inverted in the argument. This is ****
**** because the output byte is presented as straight binary ****
**** inverted and, in order to be read correctly, must be inverted. ****
**** Note that reading the output port yields the inverted value ****
**** while reading the input port (typically done) yields the true ****
**** value. ****
**** ****
**** ****
**** In adc(), the returned number from the 12 bit a-to-d converter is ****
**** a signed integer (2's complement) between -2048 and 2047 ****
**** ****
**** In dac(), a singed integer between -2048 and 2047 is output to the****
**** 12 bit d-to-a converter. ****
**** ****
**** Routines contained: ****
**** ****
**** void dig_init () ; ****
**** int dig_in () ; ****
**** void dig_out (int) ; ****
**** int adc(int); ****
**** void dac(int,int); ****
**** float volt_in(int channel) ****
**** void volt_out(int channel,float f_out) ****
*****************************************************************************/
/*************************************
*** Include files ***
*************************************/
/*Import */
#include "windows.h"
#include "rtapi.h"
#include "stdio.h"
/*Export */
#include "rtidrv.h" /* register mapping, etc. BOARD SPECIFIC */
/*Entry Routines*/
/********************************************************************
**** init_rti -- Enables access to IO region used by the RTI-815
**** Call this function before any other function defined in this file
**********************************************************************/
VOID _stdcall init_rti(void)
{
RtEnablePortIo(RTIBASE,0xE);
}
/*****************************************************************************
**** dig_init -- initialize digital IO device ****
*****************************************************************************/
void _stdcall dig_init ()
{
/**
*** sets output to zero (not required, just a precaution)
**/
RtWritePortUchar (BIN_OUTPUT, 0x0000) ;
}
/*****************************************************************************
**** dig_in -- reads digital input ****
*****************************************************************************/
int _stdcall dig_in ()
{
/**
*** reads existing data value
**/
return ( (int) RtReadPortUchar (BIN_INPUT) );
}
/*****************************************************************************
**** dig_out -- writes digital output ****
*****************************************************************************/
void _stdcall dig_out(int value)
{
/**
*** writes low byte of given data value (2 bytes)
**/
RtWritePortUchar (BIN_OUTPUT, (UCHAR) ~value);
}
/*****************************************************************************
**** analog_to_digital -- READ analog channel and convert input
******************************************************************************
***
*** check to make sure that _Busy and _Done flags are both low and
*** then start conversion, wait for completion (Done bit goes high),
*** read and return value.
***
*** ARGUMENTS: ADC input channel (0,1,2,3)
*** RETURN VALUE: 2 byte word (12 signif bits) - value of input reading
***
*****************************************************************************/
int _stdcall adc(int channel) {
union adcin
{
char a[2];
short int b;
}ad;
if ((channel<0) || (channel>15)) {
printf("Error in function 'adc', only channels 0-15 allowed\n");
ad.b = 0;
} else {
RtWritePortUchar(MUX_GAIN,(UCHAR) channel);
RtWritePortUchar(CONVERT, 0x00);
while ((RtReadPortUchar(STATUS) & ADC_DONE) == 0); /*wait for the a-to-d conversion done */
ad.a[0] = RtReadPortUchar(ADC_LOW);
ad.a[1] = RtReadPortUchar(ADC_HIGH);
RtWritePortUchar(FLAGS_CLEAR, 0x00);
} /* endif */
return (int) ad.b;
}
/*****************************************************************************
**** digital_to_analog -- WRITE output value to analog port
******************************************************************************
***
*** receives output channel number (0 or 1) and the value to be sent.
*** value bytes must be output in order low then high because it
*** is loaded into the converter when the high byte is written
*** to -- this is done by the C function to write a word (2 bytes) or
*** can be done in two byte writes (outp).
***
***
*** ARGUMENTS: DAC output channel (0 or 1)
*** output value (2 bytes, but only lower 12-bits are good)
*** RETURN VALUE: zero (bogus)
***
*****************************************************************************/
void _stdcall dac(int channel,int raw_out) {
union setdac
{
char a[2];
short int b;
}sd;
sd.b = (short int) raw_out;
if (sd.b > 2047)
sd.b = 2047;
if (sd.b < -2048)
sd.b = -2048;
if (channel == 0) {
/* output DAC (Low byte then High nibble of 12 bit output) */
RtWritePortUchar(DAC0_LOW,sd.a[0]); RtWritePortUchar(DAC0_HIGH,sd.a[1]);
} else if (channel == 1) {
/* output DAC (Low byte then High nibble of 12 bit output) */
RtWritePortUchar(DAC1_LOW,sd.a[0]); RtWritePortUchar(DAC1_HIGH,sd.a[1]);
} else {
printf("Error in function 'dac', channel can only equal 0 or 1\n");
} /* endif */
}
float _stdcall volt_in(int channel) {
if(channel<2)
return (float) (adc(channel) * (10.0F/2048.0F)); /* convert to volts */
else
return (float) (adc(channel) * (5.0F/2048.0F)); /* convert to volts */
}
void _stdcall volt_out(int channel,float f_out) {
/* limit output */
if (f_out > 9.99F)
f_out = 9.99F;
if (f_out < -9.99F)
f_out = -9.99F;
dac(channel,(int) (204.8F*f_out + 0.5F)); /* convert voltage value to 12 bit DAC units */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -