專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

AD7705程序

作者:佚名   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2013年08月04日   【字體:

AD7705應(yīng)用注意要點(diǎn):
   (1) DRDY邏輯不要搞反,高電平時(shí)等待轉(zhuǎn)換狀態(tài),低電平為可以讀取轉(zhuǎn)換數(shù)據(jù)
   (2) 系統(tǒng)校準(zhǔn)時(shí)輸入信號(hào)要大于所選量程的4/5,否則校準(zhǔn)不到32767。
   (3) 校準(zhǔn)時(shí)要等待一定的時(shí)間,讀取數(shù)據(jù)也一樣,不能超過轉(zhuǎn)換速率。
   (4) 一般的應(yīng)用只要內(nèi)部校準(zhǔn),這個(gè)很簡(jiǎn)單,只要初始化就可以。如果測(cè)量范圍不是芯片的范圍,可以通過系統(tǒng)校準(zhǔn)來實(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,無極性,增益為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再訪問
//參數(shù):無
//返回:無
//變量:無
//備注:無
//----------------------------------------------------------------------------
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ù):無
//返回:讀到的一字節(jié)數(shù)據(jù)
//變量:無
//備注:無
//------------------------------------------------------------------------------------------
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ù):無
//返回:讀到的一字節(jié)數(shù)據(jù)
//變量:無
//備注:無
//------------------------------------------------------------------------------------------
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ù):無
//返回:讀到的一字節(jié)數(shù)據(jù)
//變量:無
//備注: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ù)
//返回:無
//變量:無
//備注:無
//------------------------------------------------------------------------------------------
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ù)
//返回:無
//變量:無
//備注:無
//------------------------------------------------------------------------------------------
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;         
}

//---------------------------------------------------------------------------------------
//校準(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();
                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è)置,無分頻,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();
}

關(guān)閉窗口

相關(guān)文章