📄 adt600.h
字号:
/*
SBS CO.,LTD. ShenZhen,GuangDong,P.R.C.
This file contains procedure and functions used by the sample programs
provided with your ADT600 The procedures are well documented and should
be helpful in learning how to program your ADT600
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <asm/io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/times.h>
#include <signal.h>
#define ENABLED 1
#define DISABLED 0
#define BIPOLAR 1 /* A/D volage polarity 1=+/- */
#define UNIPOLAR 0 /* A/D 0=+ */
#define INPUT 1
#define OUTPUT 0
#define TRUE 1
#define FALSE 0
#define HIGH 1
#define LOW 0
#define START_CONVERSION 0
#define READ_DATA_MSB 0
#define READ_DATA_LSB 1
#define CLEAR_INT 2
#define STATUS_BYTE 2
#define PPI_0 4
#define PPI_1 5
#define PPI_2 6
#define PPI_CTRL 7
#define TIMER_A 8
#define TIMER_B 9
#define TIMER_C 10
#define TIMER_CTRL 11
#define CHANNEL_SLCT 12
#define IRQ_SLCT 12
unsigned char Channel_IRQ;
unsigned BaseAddress;
float VoltageRange,
DACSlope,
ConversionFactor,
Baseline ;
int DACOffset;
/**************************
InitializeBoardSettings
The InitializeBoardSettings procedure is used to set the Base address
variable and calculate the conversion factor for converting between digital
values and volts. Since the base address variable is not set until this
procedure is called, make certain that you call this procedure before
any others in this file.
*******************/
void InitializeBoardSettings(unsigned BA, float Range, char Polarity)
{
BaseAddress = BA;
Channel_IRQ = 0;
VoltageRange = Range;
ConversionFactor = VoltageRange / 4096.0;
if (Polarity == BIPOLAR)
Baseline = 0;
else
Baseline = 5.0;
}
/***********
The Function DigitalToSBS converts a digitized value to a SBS value.
In these sample programs the conversion factor and baseline
correspond to converting between digitized values and volts.
***********/
float DigitalToSBS(int DigitalValue)
{
return(DigitalValue * ConversionFactor + Baseline);
}
/*******************
ResetBoard
The ResetBoard procedure is used to reset the ADT600. The UPD71055 PPI is
configured so that ports 0,1 and 2 are input, a dummy A-D conversion is
performed and then the clear board command is sent.
The channel bits of the Channel Select register are set for channel 0
The external trigger is disabled, the IRQ source is set to Timer 2 out.
*******************/
void ResetBoard(void)
{
unsigned char B;
unsigned char status;
/*
status=inb(BaseAddress+PPI_2);
printf("before resetboard,status=%x",status);
outb_p(0x9B,BaseAddress + PPI_CTRL);
status=inb(BaseAddress+PPI_2);
printf("after resetboard,status=%x\n",status);
*/
outb_p(0x00,BaseAddress + CHANNEL_SLCT); /* Not select channel,IRQ disabled */
Channel_IRQ = 0x00;
outb_p(0,BaseAddress + START_CONVERSION); /* Start a Dummy conversion */
while ( (inb_p(BaseAddress + STATUS_BYTE) & 1) == 0)
{
} /* Wait 'til conversion done */
B = inb_p(BaseAddress + READ_DATA_LSB);
B = inb_p(BaseAddress + READ_DATA_MSB);
sleep(1); /* delay until board is cleared */
}
/*******************
SetChannel
The SetChannel procedure is used to set the channel bits, in the CHANNEL
SELECT register (BA + 12).
Note how this procedure sets only the channel select bits;
it does not change the other bits in this register.
This is important because if you unintentionally clear the other bits it
can cause unexpected behavior of the ADT600.
*******************/
void SetChannel(unsigned char ChannelNumber)
{
unsigned char B;
B = Channel_IRQ; /* read current byte */
B = B & 0x08;
B = B | ( ChannelNumber & 0x07 ); /* set channel bits */
if(ChannelNumber <= 7)
B = B | 0x10;
else
B = B | 0x20;
outb_p(B,BaseAddress + CHANNEL_SLCT); /* write new byte */
Channel_IRQ = B;
usleep(10);
}
/*******************
SetIRQStatus
The SetIRQStatus procedure is used to set or clear the IRQ Enable bit
on the ADT600. A value of 1 passed to this procedure enables interrupts
a value of 0 disables interrupts.
*******************/
void SetIRQStatus(char IRQStatus)
{
unsigned char B;
B = Channel_IRQ; /* read current byte */
B = B & 0xF7; /* clear IRQ bit */
B = B | IRQStatus * 8; /* set IRQ select bit */
outb_p(B,BaseAddress + IRQ_SLCT); /* write new byte */
Channel_IRQ = B; /* store current channel and IRQ select byte */
}
/*******************
StartConversion
The StartConversion procedure is used to start conversions.
*******************/
void StartConversion(void)
{
outb_p(0,BaseAddress + START_CONVERSION);
}
/*******************
ConversionDone
The ConversionDone function returns TRUE if a conversion is complete, FALSE
if a conversion is in progress.
*******************/
char ConversionDone(void)
{
unsigned char Status;
Status = inb_p(BaseAddress + STATUS_BYTE); /* read board status */
if ( (Status & 1) == 1)
return(TRUE); /* if B0 is set return TRUE */
else
return(FALSE); /* if B0 is not set return FALSE */
}
/*******************
ReadData
The ReadData function retrieves two bytes from the converter and combines
them into an integer value.
*******************/
int ReadData(void)
{
int MSB, LSB;
MSB = inb_p(BaseAddress + READ_DATA_MSB) * 16;
LSB = inb_p(BaseAddress + READ_DATA_LSB) / 16;
return(MSB + LSB - 2048);
}
/*******************
ClockMode
The ClockMode procedure is used to set the mode of a designated counter
on the UPD71054 programmable interval timer (PIT).
*******************/
void ClockMode(unsigned char Clock, unsigned char Mode)
{
unsigned char StatusByte;
StatusByte = (Clock * 64) + (Mode * 2) + 48;
outb_p(StatusByte,BaseAddress + TIMER_CTRL);
}
/*******************
ClockDivisor
The ClockDivisor procedure is used to set the divisor of a designated
counter on the UPD71054 programmable interval timer (PIT). This procedure
assumes that the counter has already been set to receive the least
significant byte (LSB) of the divisor followed by the most significant
byte (MSB).
*******************/
void ClockDivisor(unsigned char Clock, unsigned int Divisor)
{
unsigned char MSB, LSB;
unsigned int PortID;
PortID = BaseAddress + TIMER_A + Clock;
LSB = Divisor % 256;
MSB = Divisor / 256;
outb_p(LSB,PortID );
outb_p(MSB,PortID);
}
/***********
SetUserClock
The SetUserClock procedure is used to set the programmable interval
timer (PIT) on the ADT600 such that the output of counter 2 goes high
at the specified rate. The maximum attainable rate this procedure, as
written, is 500,000 Hz although you can easily change this by adjusting
the divisors accordingly.
***********/
void SetUserClock(float Rate)
{
ClockMode(0, 2);
ClockDivisor(0, 80);
ClockMode(1, 2);
ClockDivisor(1, ((50<<10)/ Rate));
ClockMode(2, 2);
ClockDivisor(2,2);
}
/*******************
ClockDone
*******************/
char ClockDone(unsigned char Timer)
{
unsigned int CounterValue;
unsigned char LSB, MSB;
outb_p(Timer*64,BaseAddress+TIMER_CTRL);
LSB = inb_p(BaseAddress + TIMER_A + Timer);
MSB = inb_p(BaseAddress + TIMER_A + Timer);
CounterValue = (MSB * 256) + LSB;
if (CounterValue > 1)
return(FALSE);
else
return(TRUE);
}
/***********
Read_PIT_Status
************/
char Read_PIT_Status(unsigned char Timer)
{
unsigned char status;
switch(Timer){
case 0:{ outb_p(0xe2,BaseAddress+TIMER_CTRL);
break;
}
case 1:{ outb_p(0xe4,BaseAddress+TIMER_CTRL);
break;
}
default:{ outb_p(0xe8,BaseAddress+TIMER_CTRL);
break;
}
}
status= inb_p(BaseAddress + TIMER_A + Timer);
if(status & 0x80)
return(HIGH);
else
return(LOW);
}
/***********
Read DigitalIO
The ReadDigitalIO function returns the value of the specified digital
input port. Each digital input line is represented by a bit of the
return value. Digital in 0 is bit 0, digital in 1 is bit 1, and so on.
***********/
unsigned char ReadDigitalIO(unsigned char InputPort)
{
return(inb_p(BaseAddress + PPI_0 + InputPort));
}
/***********
WriteDigitalIO
The WriteDigitalIO function sets the value of the digital output port to
equal the value passed as parameter v. Each digital output line is
represented by a bit of v. Digital out 0 is bit 0, digital out 1 is bit 1,
and so on.
***********/
void WriteDigitalIO(unsigned char OutputPort, unsigned char v)
{
outb_p(v,BaseAddress + PPI_0 + OutputPort);
}
/*****************
ConfigureIOPorts
The ConfigureIOPorts procedure is used to configure the ports 0 and 2 on
the UPD71055 PPI for either input or output.
A value of 1 means input, a value of 0 is for output.
It is advisable to use the INPUT and OUTPUT constants defined in this file.
*****************/
void ConfigureIOPorts(unsigned char Port0, unsigned char Port1,unsigned char Port2)
{
unsigned char ControlByte;
ControlByte = 128 + (Port0 * 16) + (Port1 * 2)+(Port2 * 8)+ Port2;
outb_p(ControlByte,BaseAddress+PPI_CTRL);
}
int set_bit(unsigned char bit,unsigned char port)
{
unsigned char val;
unsigned addr;
if ((bit>7)||(port>2)||(port==0)) return -1;
val=(bit<<1)|0x01;
addr=BaseAddress+PPI_CTRL;
outb(val,addr);
}
int clear_bit(unsigned char bit,unsigned char port)
{
unsigned char val;
unsigned addr;
if ((bit>7)||(port>2)||(port==0)) return -1;
val=(bit<<1)&0xfe;
addr=BaseAddress+PPI_CTRL;
outb(val,addr);
}
int test_bit(unsigned char bit,unsigned addr)
{
return (addr&(1<<bit));
}
void my_delay()
{
int i;
for (i=0;i<16;i++) {}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -