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);
}
}
|