AD7705為完整16位低成本、Σ-Δ型ADC。采用SP IQ SPI兼容的三線串行接口,能夠方便地與各種微控制器和DSP連接,也比并行接口方式大大節(jié)省了CPU的 I O口。本文主要以ad7705應(yīng)用經(jīng)驗(yàn)及應(yīng)用所需注意的事項(xiàng)為中心而展開(kāi)的討論。
ad7705應(yīng)用經(jīng)驗(yàn)總結(jié)
1.時(shí)序注意要點(diǎn):數(shù)字接口迷失的時(shí)候可以通過(guò)ADIN輸入持續(xù)32個(gè)脈沖周期(DCLK)以上的高電平將復(fù)位AD7705的數(shù)字接口,復(fù)位之后要等待500us以上才能訪問(wèn)AD7705芯片,這種復(fù)位方式不會(huì)影響AD7705內(nèi)部的任何寄存器,所有的寄存器將保持復(fù)位之前的內(nèi)容,但所有的寄存器在數(shù)字接口迷失的狀態(tài)下內(nèi)容是不確定的,因此強(qiáng)烈建議在復(fù)位之后重新設(shè)置AD7705內(nèi)部所有的寄存器,防止錯(cuò)誤。而芯片管腳RESET的復(fù)位將使片內(nèi)所有的寄存器恢復(fù)到上電的默認(rèn)值。時(shí)鐘輸入信號(hào)DCLK是一種施密特出發(fā)信號(hào),能夠適應(yīng)光耦合器的慢速邊沿,其他數(shù)字輸入信號(hào)的上升和下降時(shí)間不應(yīng)超過(guò)1us。
2.AD7705時(shí)鐘大于2M時(shí),時(shí)鐘設(shè)置寄存器的CLK位應(yīng)置1,小于2M時(shí)應(yīng)置0。DCLK的脈沖寬度要滿足最小的脈寬要求。在時(shí)鐘DCLK下降之后的低電平期間讀取數(shù)據(jù)ADOUT。在時(shí)鐘DCLK的低電平期間設(shè)置要寫入數(shù)據(jù)ADIN,然后在DCLK的上升沿寫入到7705。寫入數(shù)據(jù)以及讀取數(shù)據(jù)的時(shí)鐘DCLK的數(shù)目要與(被寫入或被讀取的寄存器)的位數(shù)長(zhǎng)度一致,多于或少于(寄存器位長(zhǎng)度)的時(shí)鐘DCLK數(shù)目都將導(dǎo)致操作錯(cuò)誤。在兩次寫操作之間,ADIN應(yīng)最好保持在高電平:因?yàn)槿魏危ㄗx或?qū)懀┎僮鞫急仨殢膶?a href="http://ttokpm.com/v/tag/1301/" target="_blank">通信寄存器開(kāi)始,而且寫入通信寄存器的8個(gè)位中的第1位必須為0,后續(xù)的位才能被寫入到通信寄存器。所以當(dāng)ADIN為0的時(shí)候,萬(wàn)一時(shí)鐘DCLK受到干擾導(dǎo)致0寫入通信寄存器,AD7705會(huì)誤認(rèn)為是寫通信寄存器的操作開(kāi)始而等待后續(xù)的7位位串,發(fā)生這種干擾之后會(huì)導(dǎo)致AD7705的數(shù)字接口迷失,從而導(dǎo)致內(nèi)部寄存器的內(nèi)容也許會(huì)變得未知狀態(tài)。此外,時(shí)鐘信號(hào)DCLK在兩次操作AD7705之間要保持高電平。即:在不訪問(wèn)AD7705的空閑時(shí)刻,或者兩次操作之間的空閑時(shí)刻,ADIN、DCLK都最好保持高電平為最可靠。
3.DRDY信號(hào)為數(shù)據(jù)AD轉(zhuǎn)換完成的指示信號(hào),低電平期間表示AD轉(zhuǎn)換完成,可以讀取數(shù)據(jù)寄存器的內(nèi)容,高電平期間表示AD轉(zhuǎn)換正在進(jìn)行,這時(shí)不能訪問(wèn)數(shù)據(jù)寄存器。對(duì)于系統(tǒng)校準(zhǔn)和內(nèi)部校準(zhǔn)也一樣,低電平期間表示校準(zhǔn)完成,可以讀取校準(zhǔn)寄存器的內(nèi)容,高電平期間表示校準(zhǔn)正在進(jìn)行,這時(shí)不能訪問(wèn)校準(zhǔn)寄存器。違反這些規(guī)定的操作,結(jié)果時(shí)未知的。此外程序中千萬(wàn)不能把DRDY的邏輯搞反,否則結(jié)果不可預(yù)料。
4.不管是校準(zhǔn)還是數(shù)據(jù)AD轉(zhuǎn)換,數(shù)字濾波器同步位FSYNC都要置為0,這樣AD7705的校準(zhǔn)或者數(shù)據(jù)AD轉(zhuǎn)換工作才能進(jìn)行,否則校準(zhǔn)和AD轉(zhuǎn)換不會(huì)進(jìn)行,DRDY信號(hào)也不會(huì)變低。當(dāng)FSYNC=0時(shí),在校準(zhǔn)或AD轉(zhuǎn)換結(jié)束后DRDY信號(hào)將變低,此時(shí)可以讀取校準(zhǔn)系數(shù)或者數(shù)據(jù)寄存器。
5.采用非緩沖模式時(shí),AD7705模擬輸入前端的電阻電容的變化對(duì)AD轉(zhuǎn)換精度影響很大。若系統(tǒng)工作時(shí)的信號(hào)源、溫度環(huán)境、器件參數(shù)變化很大,導(dǎo)致AD7705模擬輸入前端電路的參數(shù)跟系統(tǒng)校準(zhǔn)時(shí)的參數(shù)不一致,誤差會(huì)非常大。緩沖模式能解決這種問(wèn)題,當(dāng)使能緩沖模式時(shí),AD7705會(huì)在模擬輸入端和AD轉(zhuǎn)換器之間接入一個(gè)緩沖器Buffer,這樣AD7705就能適應(yīng)模擬輸入前端信號(hào)源的大阻抗、器件參數(shù)(電阻電容)的變化、溫度環(huán)境的變化等各種與系統(tǒng)校準(zhǔn)時(shí)的不一致情況(即器件工作條件的變化)。所以,AD7705的校準(zhǔn)和正常工作最好都要在緩沖模式下進(jìn)行。
6.電壓輸入范圍:對(duì)于非緩沖模式,模擬輸入信號(hào)范圍是GND-30mV至VDD+30mV之間。對(duì)于緩沖模式,模擬輸入信號(hào)范圍是GND+50mV至VDD-1.5V之間。
7.非緩沖模式、單極性、增益為GAIN:此時(shí)AD7705的反相輸入端VIN-的范圍是GND-30mV至VDD+30mV-VREF/GAIN之間,其中VREF為AD7705的參考電壓。正相輸入端VIN+的范圍是V-至V-+VREF/GAIN。如右圖,即V+和V-都必須大于GND小于VDD,同時(shí)還要考慮單極性的輸入范圍,即V-還必須小于VDD+30mV-VREF/GAIN,才不至于模擬輸入為V+max=V-+VREF/GAIN時(shí)大于VDD+30mV。
8.非緩沖、雙極性、增益為GAIN:此時(shí)V+和V-都必須大于GAN小于VDD,V-還必須小于VDD+30V-VREF/GAIN,這樣輸入V+max=V-+VREF/GAIN不至于大于VDD+30mV。V-還必須大于GND-30mV +VREF/GAIN,才不至于輸入V+min=V――VREF/GAIN時(shí)小于GND-30mV。正相輸入端VIN+的正信號(hào)輸入范圍是V-至V-+VREF/GAIN,正相輸入端VIN+的負(fù)信號(hào)輸入范圍是V-至V--REF/GAIN。
9.緩沖模式、單極性、增益為GAIN:此時(shí)AD7705的反相輸入端VIN-的范圍是【GND+50mV】至【VDD-1.5V-VREF/GAIN】之間,其中VREF為AD7705的參考電壓。正相輸入端VIN+的范圍是【V-】至【V-+VREF/GAIN】。如右圖,即V+和V-都必須大于GND+50mV小于VDD-1.5V,同時(shí)還要考慮單極性的輸入范圍,即V-還必須小于VDD-1.5V-VREF/GAIN,才不至于輸入V+max=【V-+VREF/GAIN】時(shí)大于VDD-1.5V。
10.緩沖模式、雙極性、增益為GAIN:此時(shí)AD7705的反相輸入端VIN-的范圍是【GND+50mV+VREF/GAIN】至【VDD-1.5V-VREF/GAIN】之間,這樣才不至于輸入VIN+max=【V-+VREF/GAIN】時(shí)導(dǎo)致VIN+大于VDD-1.5V、輸入VIN+min=【V――VREF/GAIN】時(shí)導(dǎo)致VIN+小于GND+50mV。其中VREF為AD7705的參考電壓。正相輸入端VIN+的正信號(hào)輸入范圍是【V-】至【V-+VREF/GAIN】,正相輸入端VIN+的負(fù)信號(hào)輸入范圍是【V-】至【V--REF/GAIN】。
AD7705應(yīng)用注意要點(diǎn)和程序
(1) DRDY邏輯不要搞反,高電平時(shí)等待轉(zhuǎn)換狀態(tài),低電平為可以讀取轉(zhuǎn)換數(shù)據(jù)
?。?) 系統(tǒng)校準(zhǔn)時(shí)輸入信號(hào)要大于所選量程的4/5,否則校準(zhǔn)不到32767。
?。?)校準(zhǔn)時(shí)要等待一定的時(shí)間,讀取數(shù)據(jù)也一樣,不能超過(guò)轉(zhuǎn)換速率。
?。?) 一般的應(yīng)用只要內(nèi)部校準(zhǔn),這個(gè)很簡(jiǎn)單,只要初始化就可以。如果測(cè)量范圍不是芯片的范圍,可以通過(guò)系統(tǒng)校準(zhǔn)來(lái)實(shí)現(xiàn),滿量程校準(zhǔn)電壓要大于量程的4/5
#include 《util/delay.h》
#include 《avr/eeprom.h》
#include “ad7705.h”
#include “main.h”
#include “crc16.h”
#include “Usart.h”
/針對(duì)四個(gè)量程的設(shè)置寄存器的設(shè)置內(nèi)容
//(1)對(duì)于單極性V級(jí)別輸入0-5V、0-20mA、0-10V這三個(gè)量程,輸入范圍為0-2V,無(wú)極性,增益為1,緩沖模式--0-2V
//(2)對(duì)于雙極性V級(jí)別輸入+-2.5V、+-5V這兩個(gè)量程,輸入范圍為+-1V,雙極性,增益為2,緩沖模式--+-2V
//(3)對(duì)于雙精度mV級(jí)別輸入+-500mV,增益為4,雙極性,緩沖模式--+-2V
//(4)對(duì)雙精度mV級(jí)別+-50mV,增益為32,雙極性,緩沖模式--+-1.6V
//------MD1(0) MD0(0) G2(0) G1(0) G0(0) B/U(0) BUF(0) FSYNC(0)
--------------------------//
const unsigned char text_of_setup[4]={0X04,0X08,0X10,0X28}; //非緩沖模式,數(shù)字濾波同步
//const unsigned char text_of_setup[4]={0X06,0X0A,0X12,0X2A}; //緩沖模式,數(shù)字濾波同步
extern volatile unsigned char command[7]; //校準(zhǔn)命令全局?jǐn)?shù)組
extern volatile unsigned char scale; //記錄系統(tǒng)量程
extern volatile unsigned char NO_CALI_TYPE; //未校準(zhǔn)類型
extern volatile unsigned long int ZS,GS; //當(dāng)前量程的校準(zhǔn)系數(shù)
extern volatile unsigned char time_count; //超時(shí)標(biāo)志
//----------------------------------------------------------------------------
//函數(shù):reset_AD7705
//功能:AD7705串行接口失步后將其復(fù)位。復(fù)位后要延時(shí)500us再訪問(wèn)
//參數(shù):無(wú)
//返回:無(wú)
//變量:無(wú)
//備注:無(wú)
//----------------------------------------------------------------------------
void reset_AD7705(void)
{
unsigned char i;
AD_DIN1;
for( i=0; i《36; i++ )
{
AD_CLK0;
asm(“nop”);
asm(“nop”);
asm(“nop”);
AD_CLK1;
asm(“nop”);
asm(“nop”);
asm(“nop”);
}
_delay_ms(1);
}
//------------------------------------------------------------------------------------------
//函數(shù):read_AD7705_byte
//功能:從AD7705讀一個(gè)字節(jié)的數(shù)據(jù)
//參數(shù):無(wú)
//返回:讀到的一字節(jié)數(shù)據(jù)
//變量:無(wú)
//備注:無(wú)
//------------------------------------------------------------------------------------------
unsigned char read_AD7705_byte(void)
{
unsigned char data = 0;
unsigned char i = 0;
for( i=0; i《8; i++ )
{
data 《《= 1;
AD_CLK0;
asm(“nop”);
asm(“nop”);
asm(“nop”);
if(AD_DOUT)
{
data++;
}
AD_CLK1;
asm(“nop”);
asm(“nop”);
asm(“nop”);
}
return data;
}
//------------------------------------------------------------------------------------------
//函數(shù):read_AD7705_word
//功能:從AD7705讀一個(gè)字的數(shù)據(jù),共16bit
//參數(shù):無(wú)
//返回:讀到的一字節(jié)數(shù)據(jù)
//變量:無(wú)
//備注:無(wú)
//------------------------------------------------------------------------------------------
unsigned int read_AD7705_word(void)
{
unsigned int data = 0;
unsigned char i = 0;
for( i=0; i《16; i++ )
{
data 《《= 1;
AD_CLK0;
asm(“nop”);
asm(“nop”);
asm(“nop”);
if(AD_DOUT)
{
data++;
}
AD_CLK1;
asm(“nop”);
asm(“nop”);
asm(“nop”);
}
return data;
}
//------------------------------------------------------------------------------------------
//函數(shù):read_AD7705_dword
//功能:從AD7705讀一個(gè)24的數(shù)據(jù)
//參數(shù):無(wú)
//返回:讀到的一字節(jié)數(shù)據(jù)
//變量:無(wú)
//備注:AD7705是一個(gè)24位AD,選定刷新頻率在16.7HZ下,有效位是19位,暫時(shí)讀出全部24位數(shù)據(jù)
//------------------------------------------------------------------------------------------
unsigned long int read_AD7705_dword(void)
{
unsigned long data = 0;
unsigned char i = 0;
for( i=0; i《24; i++ )
{
data 《《= 1;
AD_CLK0;
asm(“nop”);
asm(“nop”);
asm(“nop”);
if(AD_DOUT)
{
data++;
}
AD_CLK1;
asm(“nop”);
asm(“nop”);
asm(“nop”);
}
return data;
}
//------------------------------------------------------------------------------------------
//函數(shù):write_AD7705_byte
//功能:往AD7705寫8位數(shù)據(jù)
//參數(shù):IN - uint8_t data,要寫入AD7705的數(shù)據(jù)
//返回:無(wú)
//變量:無(wú)
//備注:無(wú)
//------------------------------------------------------------------------------------------
void write_AD7705_byte(unsigned char data)
{
for(unsigned char i=0; i《8; i++)
{
AD_CLK0;
if(data&0x80)
AD_DIN1;
else
AD_DIN0;
asm(“nop”);
asm(“nop”);
asm(“nop”);
AD_CLK1;
asm(“nop”);
asm(“nop”);
asm(“nop”);
data 《《= 1;
}
AD_DIN1;
}
//------------------------------------------------------------------------------------------
//函數(shù):write_AD7705_dword
//功能:往AD7705寫24位數(shù)據(jù),因?yàn)锳D7705是24位的器件
//參數(shù):IN - int32_t data,要寫入AD7705的數(shù)據(jù)
//返回:無(wú)
//變量:無(wú)
//備注:無(wú)
//------------------------------------------------------------------------------------------
void write_AD7705_dword(unsigned long int data)
{
for(unsigned char i = 0; i《24; i++)
{
AD_CLK0;
if(data&0x800000)
AD_DIN1;
else
AD_DIN0;
asm(“nop”);
asm(“nop”);
asm(“nop”);
AD_CLK1;
asm(“nop”);
asm(“nop”);
asm(“nop”);
data 《《= 1;
}
AD_DIN1;
}
//--------------------------------------------------------------------------
//-------------------------讀取AD7705轉(zhuǎn)換數(shù)據(jù)函數(shù)--------------------------
//入口參數(shù):指向main()主函數(shù)定義的ad_data變量的常量指針
//--------------------------------------------------------------------------
void ReadData7705(unsigned int *const pdata)
{
unsigned int data=0, fiter[5]={0};
unsigned long int temp=0;
unsigned char i=0, sort_flag=1;
AD_CS0;
_delay_us(5);
start_AD7705();
for( i=0; i《5; i++ )
{
start_timer0();
_delay_ms(2);
while( AD_DRDY )
{
if( time_count 》= time_read_data )
{
stop_timer0();
AD_CS1;
return;
}
}
stop_timer0();
write_AD7705_byte( RD_DATA_REG );
fiter[i] = read_AD7705_word();
}
AD_CS1;
sort_flag = 1;
while( sort_flag )
{
sort_flag = 0;
for( i=0; i《4; i++ )
{
if( fiter[i] 》 fiter[i+1] )
{
data = fiter[i];
fiter[i] = fiter[i+1];
fiter[i+1] = data;
sort_flag = 1;
}
}
}
temp = ( (unsigned long int)fiter[1] + (unsigned long int)fiter[2]
+ (unsigned long int)fiter[3] )/3;
data = (unsigned int)temp;
if( (data《0xfff0) && (data&0x000f)》0x0008 )
{
data 》》= 4;
data++;
}
else
{
data 》》= 4;
}
if( 1 != scale )
{
data -= 0x0800;
}
*pdata = data & 0x0fff;
}
//---------------------------------------------------------------------------------------
gina 發(fā)表于 2008-9-22 10:35
//校準(zhǔn)命令格式
//STX Data Long Command Code Parameter CheckSum ETX
//0x55 數(shù)據(jù)長(zhǎng)度(2) 量程指示 00H/01H CRC16(2) 0x0D
void AD7705_calibration(void)
{
unsigned char readtimes =0;
unsigned char cali_scale =0;
unsigned long int temp =0;
unsigned char coefficient[8] ={0}; //test[8]={0};
//16位校驗(yàn)和的臨時(shí)變量
unsigned int crcvalue =0;
AD_CS1;
cali_scale = command[2]; //獲取上位機(jī)發(fā)送的要校準(zhǔn)的量程類型
eeprom_busy_wait();
eeprom_read_block( &coefficient[0], (void*)(ADDR_EEPROM_1+(cali_scale-1)*10), 8 );
crcvalue = checksum( &coefficient[0], 6 );
if( (coefficient[7]*256+coefficient[6]) != crcvalue )
{
readtimes++;
}
if( 1 == readtimes )
{
eeprom_busy_wait();
&nnbsp; eeprom_read_block( &coefficient[0], (void*)(ADDR_EEPROM_2+(cali_scale-1)*10), 8 );
crcvalue = checksum( &coefficient[0], 6 ); //
if( (coefficient[7]*256+coefficient[6]) != crcvalue )
{
readtimes++;
}
}
if( 2 == readtimes )
{
eeprom_busy_wait();
eeprom_read_block( &coefficient[0], (void*)(ADDR_EEPROM_3+(cali_scale-1)*10), 8 );
}
ADDR409_MASK;
AD_CS0;
_delay_us(5);
reset_AD7705();
write_AD7705_byte( WR_CLOCK_REG );
write_AD7705_byte( CLOCK_REG_SET );
if( ZERO_CALIBRATION == command[3] ) //校準(zhǔn)命令為零校準(zhǔn)
{
write_AD7705_byte( WR_SETUP_REG );
write_AD7705_byte( text_of_setup[cali_scale-1] | SYS_ZERO_CALI);
//等待校準(zhǔn)完成
start_timer0();
while( time_count 《 time_sys_cali );
stop_timer0();
while( AD_DRDY );
//讀OFFSET寄存器
write_AD7705_byte( RD_OFFSET_REG );
temp = read_AD7705_dword();
if( cali_scale == scale)
{
ZS = temp; NO_CALI_TYPE = NO_FULL_CALIBRATION;
}
coefficient[0] = (unsigned char)( temp%256 );
coefficient[1] = (unsigned char)( (temp/256)%256 );
coefficient[2] = (unsigned char)( (temp/65536)%256 );
}
else if( FULL_CALIBRATION == command[3] )
{
temp = (unsigned long int)(coefficient[0]) + (unsigned long int)(coefficient[1])*256
+ (unsigned long int)(coefficient[2])*65536;
write_AD7705_byte( WR_OFFSET_REG );
write_AD7705_dword( temp );
write_AD7705_byte( WR_SETUP_REG );
write_AD7705_byte( text_of_setup[cali_scale-1] | SYS_FULL_CALI );
//等待校準(zhǔn)完成
start_timer0();
while( time_count 《 time_sys_cali );
stop_timer0();
while( AD_DRDY );//
//讀FULL寄存器
write_AD7705_byte( RD_FULL_REG );
temp = read_AD7705_dword();
if( cali_scale == scale )
{
GS = temp;
NO_CALI_TYPE = ALREADY_CALIBRATION;
}
coefficient[3] = (unsigned char)( temp%256 );
coefficient[4] = (unsigned char)( (temp/256)%256 );
coefficient[5] = (unsigned char)( (temp/65536)%256 );
}
else
{
AD_CS1;
_delay_us(5);
return;
}
AD_CS1;
_delay_us(5);
crcvalue = checksum(&coefficient[0],6);
coefficient[6] = (unsigned char)(crcvalue%256);//
coefficient[7] = (unsigned char)(crcvalue/256);
eeprom_busy_wait();
eeprom_write_block( &coefficient[0], (void*)(ADDR_EEPROM_1+(cali_scale-1)*10), 8 );
eeprom_busy_wait();
eeprom_write_block( &coefficient[0], (void*)(ADDR_EEPROM_2+(cali_scale-1)*10), 8 );
eeprom_busy_wait();
eeprom_write_block( &coefficient[0], (void*)(ADDR_EEPROM_3+(cali_scale-1)*10), 8 );
Txout( &coefficient[0] );//輸出校準(zhǔn)數(shù)據(jù)給上位機(jī)
return;
}
//
void start_AD7705(void)
{
reset_AD7705();
//寫OFFSET寄存器
write_AD7705_byte( WR_OFFSET_REG );
write_AD7705_dword( ZS );
//寫滿量程校準(zhǔn)寄存器
write_AD7705_byte( WR_FULL_REG );
write_AD7705_dword( GS );
//CLOCK寄存器設(shè)置,無(wú)分頻,50HZ輸出更新速率
write_AD7705_byte( WR_CLOCK_REG );
write_AD7705_byte( CLOCK_REG_SET );
//寫設(shè)置寄存器
write_AD7705_byte( WR_SETUP_REG );
write_AD7705_byte( text_of_setup[scale-1] );
start_timer0();
while( time_count 《 time_read_data );
stop_timer0();
}
評(píng)論
查看更多