1. 引脚及其功能 DAC0832是双列直插式8位D/A转换器。能完成数字量输入到模拟量(电流)输出的转换。图1-1和图1-2分别为DAC0832的引脚图和内部结构图。其主要参数如下:分辨率为8位,转换时间为1μs,满量程误差为±1LSB,参考电压为(+10?/span>-10)V,供电电源为(+5~+15)V,逻辑电平输入与TTL兼容。从图1-1中可见,在DAC0832中有两级锁存器,第一级锁存器称为输入寄存器,它的允许锁存信号为ILE,第二级锁存器称为DAC寄存器,它的锁存信号也称为通道控制信号 /XFER。 图1-1中,当ILE为高电平,片选信号 /CS 和写信号 /WR1为低电平时,输入寄存器控制信号为1,这种情况下,输入寄存器的输出随输入而变化。此后,当 /WR1由低电平变高时,控制信号成为低电平,此时,数据被锁存到输入寄存器中,这样输入寄存器的输出端不再随外部数据DB的变化而变化。 对第二级锁存来说,传送控制信号 /XFER 和写信号 /WR2同时为低电平时,二级锁存控制信号为高电平,8位的DAC寄存器的输出随输入而变化,此后,当 /WR2由低电平变高时,控制信号变为低电平,于是将输入寄存器的信息锁存到DAC寄存器中。 图1-1中其余各引脚的功能定义如下: (1)、DI7~DI0 :8位的数据输入端,DI7为最高位。 (2)、IOUT1 :模拟电流输出端1,当DAC寄存器中数据全为1时,输出电流最大,当DAC寄存器中数据全为0时,输出电流为0。 (3)、IOUT2 :模拟电流输出端2, IOUT2与IOUT1的和为一个常数,即IOUT1+IOUT2=常数。 (4)、RFB :反馈电阻引出端,DAC0832内部已经有反馈电阻,所以 RFB端可以直接接到外部运算放大器的输出端,这样相当于将一个反馈电阻接在运算放大器的输出端和输入端之间。 (5)、VREF :参考电压输入端,此端可接一个正电压,也可接一个负电压,它决定0至255的数字量转化出来的模拟量电压值的幅度,VREF范围为(+10~-10)V。VREF端与D/A内部T形电阻网络相连。 (6)、Vcc :芯片供电电压,范围为(+5~ 15)V。 (7)、AGND :模拟量地,即模拟电路接地端。 (8)、DGND :数字量地。
下面是单片机驱动程序:
#include <reg51.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit CS = P1^0;
sbit CLK = P1^1;
sbit DI = P1^2;
sbit DO = P1^2;
uchar code Tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void Display(uint dat) //显示的数值为毫伏
{
uchar ge,shi,bai,qian;
qian = dat/1000%10;
bai = dat/100%10;
shi = dat/10%10;
ge = dat%10;
P2 = 0xfe;
P0 = Tab[qian]|0x80; //最高位加小数点
delay(1);
P2 = 0xfd;
P0 = Tab[bai];
delay(1);
P2 = 0xfb;
P0 = Tab[shi];
delay(1);
P2 = 0xf7;
P0 = Tab[ge];
delay(1);
}
uchar ADC0832(bit mode,bit channel) //AD转换,返回结果
{
uchar i,dat,ndat;
CS = 0;//拉低CS端
_nop_();
_nop_();
DI = 1; //第1个下降沿为高到
CLK = 1;//拉高CLK端
_nop_();
_nop_();
CLK = 0;//拉低CLK端,形成下降沿1
_nop_();
_nop_();
DI = mode; //低电平为差分模式,电平为单通道模式
CLK = 1;//拉高CLK端
_nop_();
_nop_();
CLK = 0;//拉低CLK端,形成下降沿2
_nop_();
_nop_();
DI = channel;//低电平为CH0,高缙轿狢H1
CLK = 1;//拉高CLK端
_nop_();
_nop_();
CLK = 0;//拉低CLK端,形成下降沿3
DI = 1;//控制命令结束(经试验必需)
dat = 0;
//下面开始读取转换后的数据,从最高位开始依次输出(D7~D0)
for(i = 0;i < 8;i++)
{
dat <<= 1;
CLK=1;//拉高时钟端
_nop_();
_nop_();
CLK=0;//拉低时钟端形成一次时钟脉冲
_nop_();
_nop_();
dat |= DO;
}
ndat = 0; //记录D0
if(DO == 1)
ndat |= 0x80;
//下面开始继续读取反序的数据(从D1到D7)
for(i = 0;i < 7;i++)
{
ndat >>= 1;
CLK = 1;//拉高时钟端
_nop_();
_nop_();
CLK=0;//拉低时钟端形成一次时钟脉冲
_nop_();
_nop_();
if(DO==1)
ndat |= 0x80;
}
CS=1;//拉高CS端,结束转换
CLK=0;//拉低CLK端
DI=1;//拉高数据端,回到初始状态
if(dat==ndat)
return(dat);
else
return 0;
}
void main()
{
uint adc;
while(1)
{
adc = ADC0832(0,0); //差分模式,CH0-CH1
adc = adc*19.607843; //转换为实际电压便于显示
Display(adc);
}
}
|