电赛总结(二)——AD芯片总结之AD7705

 

1、特性参数

(1)16位无丢失代码性AD转化器

(2)只需要3.3V供电(即只需要单片机即可供电)

(3)双通道差分输入

(4)基准电压为2.5V时,在单极性信号下,输入范围是0到2.5V,在双极性输入下,输入范围是-1.25到+1.25

(5)低功耗CMOS芯片,功耗一般为20uW

(6)可编程,可编程增益,以及降噪参数等。

 

2、引脚排列

image

 

3、引脚功能说明

管脚名称 功能
SCLK

串行时钟,施密特逻辑输入。将一个外部的串行时钟加于这一输入端口,以访问AD7705/7706 的串行数据。和单片机传输数据时的控制时钟

MCLKIN

为转换器提供主时钟信号。能以晶体/谐振器或外部时钟的形式提供。晶体/谐振器可以接在MCLKIN 和MCLKOUT 二引脚之间。此外,MCLKIN 也可用CMOS 兼容的时钟驱动, 而MCLKOUT 不连接。时钟频率的范围为500kHz~5MHz

MCLKOUT

当主时钟为晶体/谐振器时,晶体/谐振器被接在MCLKIN 和MCLKOUT 之间。如果在MCLKIN 引脚处接上一个外部时钟,MCLKOUT 将提供一个反相时钟信号。这个时钟可以用来为外部电路提供时钟源,且可以驱动一个CMOS 负载。如果用户不需要,MCLKOUT 可以通过时钟寄存器中的CLKDIS位关掉。这样,器件不会在MCLKOUT 脚上驱动电容负载而消耗不必要的功率

CS’

片选,低电平有效的逻辑输入,选择AD7705/7706。将该引脚接为低电平,AD7705/7706 能以三线接口模式运行(以SCLK、DIN 和DOUT 与器件接口)。在串行总线上带有多个器件的系统中,可由CS’对这些器件作出选择,或在与AD7705/7706 通信时,CS’可用作帧同步信号

RESET

复位输入。低电平有效的输入,将器件的控制逻辑、接口逻辑、校准系数、数字滤波器和模拟调制器复位至上电状态

AIN2(+) 差分模拟输入通道2 的正输入端。
AIN1(+) 差分模拟输入通道1 的正输入端;
REFIN(+) 基准输入端,基准输入是差分的,并规定REFIN(+)必须大于REFIN(-)。REFIN(+)可以取VDD 和GND 之间的任何值
REFIN(-) 基准输入端,REFIN(-)可以取VDD 和GND 之间的任何值,且满足REFIN(+)大于REFIN(-)
DRDY’

逻辑输出。这个输出端上的逻辑低电平表示可从AD7705/7706 的数据寄存器获取新的输出字。完成对一个完全的输出字的读操作后,DRDY’引脚立即回到高电平。如果在两次输出更新之间,不发生数据读出,DRDY’将在下一次输出更新前500×tCLKIN 时间返回高电平。当DRDY’处于高电平时,不能进行读操作,以免数据寄存器中的数据正在被更新时进行读操作。当数据被更新后,
DRDY’又将返回低电平。DRDY’也用来指示何时AD7705/7706 已经完成片内的校准序列.

DOUT 串行数据输出端
DIN 串行数据输入端
VDD 电源电压,+3.3V
GND 内部电路的地电位基准点

 

4、片内寄存器

(1)概述

      AD7705/7706 片内包括8 个寄存器,这些寄存器通过器件的串行口访问。第一个是通信寄存器,它管理通道选择,决定下一个操作是读操作还是写操作,以及下一次读或写哪一个寄存器。所有与器件的通信必须从写入通信寄存器开始。上电或复位后,器件等待在通信寄存器上进行一次写操作。这一写到通信寄存器的数据决定下一次操作是读还是写,同时决定这次读操作或写操作在哪个寄存器上发生。所以,写任何其它寄存器首先要写通信寄存器,然后才能写选定的寄存器。

 

(2)通信寄存器

      通信寄存器是一个8 位寄存器,既可以读出数据也可以把数据写进去。所有与器件的通信必须从写该寄存器开始。写上去的数据决定下一次读操作或写操作在哪个寄存器上发生。一旦在选定的寄存器上完成了下一次读操作或写操作,接口返回到通信寄存器接收一次写操作的状态。

image

名称

功能

DRDY’

对于写操作,必须有一个“0”被写到这位,以便通信寄存器上的写操作能够准确完成。如果“1”被写到这位,后续各位将不能写入该寄存器。

RS2-RS0

寄存器选择位。这3 个位选择下次读/写操作在8 个片内寄存器中的哪一个上发生

image
R/W

读/写选择。这个位选择下次操作是对选定的寄存器读还是写。“0”表示下次操作是写,“1”表示下次操作是读。


STBY

等待模式。此位上写“1”,则处于等待或掉电模式。在这种模式下,器件消耗的电源电流仅为10μA。在等待模式时,器件将保持它的校准系数和控制字信息。写“0”,器件处于正常工作模式。

CHI-CH0 通道选择
image

 

(3)设置寄存器

image

名称 功能
MD1 MD0 image
G2-G0 增益选择位
image
image
B/U 单极性/双极性工作。“0”表示选择双极性操作,“1”表示选择单极性工作。
BUF

缓冲器控制。“0”表示片内缓冲器短路,缓冲器短路后,电源电流降低。此位处于高电平时,缓冲器与模拟输入串联,输入端允许处理高阻抗源。

FSYNC

滤波器同步。该位处于高电平时,数字滤波器的节点、滤波器控制逻辑和校准控制逻辑处于复位状态下,同时,模拟调制器也被控制在复位状态下。当处于低电平时,调制器和滤波器开始处理数据,并在3×(1/输出更新速率)时间内(也就是滤器的稳定时间)产生一个有效字。FSYNC 不影响数字接口,也不使DRDY’输出复位(如果它是低电平)。

 

(4)时钟寄存器

image

名称 功能
ZERO 必须在这些位上写零,以确保AD7705/7706 正确操作。
CLKDIS

主时钟禁止位。逻辑“ 1” 表示阻止主时钟在MCLKOUT 引脚上输出。禁止时,MCLKOUT 输出引脚处于低电平。

CLKDIV

CLKDIV 时钟分频器位。CLKDIV 置为逻辑1 时,MCLKIN 引脚处的时钟频率在被AD7705/7706,使用前进行2 分频。“1”是二分频,“0”没有分频。

CLK

时钟位。CLK 位应根据AD7705/7706 的工作频率而设置。如果转换器的主时钟频率为2.4576MHz(CLKDIV=0)或为4.9152MHz(CLKDIV=1),CLK 应置“0”。如果器件的主时钟频率为1MHz(CLKDIV=0)或2MHz (CLKDIV=1),则该位应置“1”。该位为给定的工作频率设置适当的标度电流,并且也(与FS1 和FS0 一起)选择器件的输出更新率。

FS1,FS2

滤波器选择位,它与CLK 一起决定器件的输出更新率。表12 显示了滤波器的第一陷波和-3dB 频率。

image

image

 

(5)数据寄存器

      数据寄存器是一个16 位只读寄存器,它包含了来自AD7705/7706 最新的转换结果。如果通信寄存器将器件设置成对该寄存器写操作,则必定会实际上发生一次写操作以使器件返回到准备对通信寄存器的写操作,但是向器件写入的16 位数字将被AD7705/7706 忽略。

 

(6)测试寄存器

      测试寄存器用于测试器件时。建议用户不要改变测试寄存器的任何位的默认值(上电或复位时自动置入全0),否则当器件处于测试模式时,不能正确运行。

 

(7)零标度校准寄存器、满标度校准寄存器一般不进行设置

 

5、芯片外围电路图

image

 

6、STM32F103ZE驱动程序

     使用SPI模式驱动的AD7705

#ifndef __SPI_H
#define __SPI_H


#include "stm32f10x.h"
#include "pbdata.h"

//×ԱຯÊý
#include "timer.h"
#include "gpio.h"
#include "baseFunc.h"

/*    ???? SPI1_REMAP = 0 
    SPI1_NSS         PA4      CS        
    SPI1_SCK      PA5     CLK    
    SPI1_MISO      PA6      DOUT    
    SPI1_MOSI      PA7      DIN        
                PA8    DRDY            */ 
                
#define LCD_CS Pin4
#define CLK Pin5
#define DOUT Pin6
#define Din  Pin7
#define DRDY Pin8

#define CS_ADC_LOW()    GPIO_ResetBits(GPIOA,GPIO_Pin_4)    /*??*/
#define CS_ADC_HIGH()   GPIO_SetBits(GPIOA,GPIO_Pin_4)

void SPIx_Init(void);

u8 SPIx_ReadWriteByte(u8 TxData);



#endif

 

#include "spi.h"



/*    ???? SPI1_REMAP = 0 
    SPI1_NSS         PA4      CS        
    SPI1_SCK      PA5     CLK    
    SPI1_MISO      PA6      DOUT    
    SPI1_MOSI      PA7      DIN        
                PA8    DRDY            */ 

int temp;

SPI_InitTypeDef  SPI_InitStructure;

void SPIx_Init(void)
{

    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1|RCC_APB2Periph_AFIO, ENABLE );    
  
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;// AdDrdy
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;//PC8
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);        
     GPIO_SetBits(GPIOA,GPIO_Pin_8);
    
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);        
     GPIO_SetBits(GPIOA,GPIO_Pin_4);    


    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    SPI_Cmd(SPI1, DISABLE); 
    SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; 
    SPI_InitStructure.SPI_Mode = SPI_Mode_Master;    
    SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;        
    SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;        
    SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;    
    SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;        
     SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256;        
    SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;    
    SPI_InitStructure.SPI_CRCPolynomial = 7;    
    SPI_Init(SPI1, &SPI_InitStructure);  
  
    SPI_Cmd(SPI1, ENABLE); 
    
    CS_ADC_LOW();    
    temp=SPIx_ReadWriteByte(0xff); 
    CS_ADC_HIGH();
}   


u8 SPIx_ReadWriteByte(u8 TxData)
{        
    u8 retry=0;                 
 
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET)
    {
        retry++;
        if(retry>200)return 0;
    }              
 
    SPI_I2S_SendData(SPI1, TxData); 
    retry=0;
 
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET) 
    {
        retry++;
        if(retry>200)return 0;
    }                                  
 
    return SPI_I2S_ReceiveData(SPI1);                         
}

 

#ifndef __ADC7705_H
#define __ADC7705_H


#include "stm32f10x.h"

//×ԱຯÊý
#include "timer.h"
#include "gpio.h"
#include "baseFunc.h"
#include "spi.h"
#include "LCD3.2.h"

void Init_AD7705(u8 chnanel) ;

u16 GetData7705_CH1(void) ;

u16 GetData7705_CH2(void) ;

void ADC_7705_single(void);

void ADC_7705_double(void);

void AD7705_WriteByte(u8 Dst_Addr);

#endif

 

#include "adc7705.h"
#include "usart1.h"

int tag=1;

/********AD7705?????***********/

void AD7705_WriteByte(u8 Dst_Addr)   
{   
       CS_ADC_LOW(); 
      delay_us(20);
      SPIx_ReadWriteByte(Dst_Addr);
       delay_us(100);
      CS_ADC_HIGH();
}

void Init_AD7705(u8 chnanel) 
{
    u8 i;
    
    for(i=0;i<150;i++)
    {
        AD7705_WriteByte(0xff);
      }  
      delay_ms(1);
        
    switch(chnanel)
    {
        case 1: 
            AD7705_WriteByte(0x20); 
          delay_ms(1);
            AD7705_WriteByte(0x03); 
            delay_ms(1);
          AD7705_WriteByte(0x10); 
            delay_ms(1);
        if(tag==1)
        {
            AD7705_WriteByte(0x4C);  //µ¥¼«ÐÔ 
        }
        else
        {
             AD7705_WriteByte(0x48); 
        }         
          break;
        case 2: 
            AD7705_WriteByte(0x21); 
          delay_ms(1);
            AD7705_WriteByte(0x03); 
            delay_ms(1);
          AD7705_WriteByte(0x11);
      delay_ms(1);        
         if(tag==1)
        {
            AD7705_WriteByte(0x4C);  //µ¥¼«ÐÔ 
        }
        else
        {
             AD7705_WriteByte(0x48); 
        }    
          break;
        default:    
            break;
    } 
}

/* ?AD7705???? ????channel */ 
u16 GetData7705_CH1(void) 
{
    u16 temp1 = 0;
      u16 DataL = 0;
    u16 DataH = 0;
    
    
      Init_AD7705(1);            //?????1
      delay_ms(1);
      AD7705_WriteByte(0x38);   //??CH1??????  
    
      while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1);  //??????AdDrdy=0  
      
      CS_ADC_LOW();  
      delay_us(20);
      DataH = SPIx_ReadWriteByte(0xff);
      DataL = SPIx_ReadWriteByte(0xff); 
      delay_us(200);
    CS_ADC_HIGH();   
      DataH = DataH << 8; 
    temp1  =  DataH | DataL; 

    return temp1; 
}

 
u16 GetData7705_CH2(void) 
{
    u16 temp2 = 0;
      u16 DataL = 0;
    u16 DataH = 0;
       Init_AD7705(2);        //?????2
      delay_ms(1);
      AD7705_WriteByte(0x39);   //??CH2??????  
    while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_8)==1);  //??????AdDrdy=0  
      
      CS_ADC_LOW(); //????  
      delay_us(20);
      DataH = SPIx_ReadWriteByte(0xff);
      DataL = SPIx_ReadWriteByte(0xff); 
      delay_us(100);
    CS_ADC_HIGH();   //????     
      DataH = DataH << 8; 
    temp2  =  DataH | DataL; 

    return temp2; 
}




void ADC_7705_single(void)
{          
    u8 num1[]={"0000.0mV"};
    u8 num2[]={"0000.0mV"};

    u16 RCH1_16bit,RCH2_16bit;
  u32 l_ncm1,l_ncm2;
    
  tag=1;    
    RCH1_16bit = GetData7705_CH1();
    l_ncm1    = (u32)(RCH1_16bit*(25000.0/65535)); 
     RCH2_16bit = GetData7705_CH2();
    l_ncm2    = (u32)(RCH2_16bit*(25000.0/65535)); 
    
    num1[0]    = l_ncm1/10000+'0';
    num1[1]    = (l_ncm1%10000)/1000+'0';
    num1[2]    = (l_ncm1%1000)/100+'0';
    num1[3]    = (l_ncm1%100)/10+'0';
    num1[5]    = l_ncm1%10+'0';

    
    num2[0]    = l_ncm2/10000+'0';
    num2[1]    = (l_ncm2%10000)/1000+'0';
    num2[2]    = (l_ncm2%1000)/100+'0';
    num2[3]    = (l_ncm2%100)/10+'0';
    num2[5]    = l_ncm2%10+'0';

    
     LCD_PutString(0,0,num1,Blue,White);
     LCD_PutString(0,20,num2,Blue,White);

}

void ADC_7705_double(void)
{          
    u8 num1[]={"+0000.0MV"};
    u8 num2[]={"+0000.0MV"};

    u16 RCH1_16bit,RCH2_16bit;
  u32 l_ncm1,l_ncm2,NUM1[20],NUM2[20],temp,temp2;
    int i,j,x,y;
    int fuhao1=0;
    int fuhao2=0;
    
  tag=0;    
    for(i=0;i<10;i++)
    {
        RCH1_16bit = GetData7705_CH1();
      RCH2_16bit = GetData7705_CH2();
    if(RCH1_16bit>=0x8000)
      {
            fuhao1++;
        l_ncm1    = (u32)((RCH1_16bit-0x8000)*(25000.0/65535*2));
      }
      else
      {
            fuhao1--;
        l_ncm1    = (u32)((0x8000-RCH1_16bit)*(25000.0/65535*2)); 
      }
         if(RCH2_16bit>=0x8000)
      {
            fuhao2++;
        l_ncm2    = (u32)((RCH2_16bit-0x8000)*(25000.0/65535*2));
      }
      else
      {
            fuhao2--;
        l_ncm2    = (u32)((0x8000-RCH2_16bit)*(25000.0/65535*2)); 
      }    
        NUM1[i]=l_ncm1;
        NUM2[i]=l_ncm2;
    }
    
    for(i=0;i<9;i++)
    {
        x=i;
        for(j=i+1;j<10;j++)
        {
            if(NUM1[x]>NUM1[j])
            {
                x=j;
            }
                if(NUM2[y]>NUM2[j])
            {
                y=j;
            }
        }
        temp=NUM1[x];
        NUM1[x]=NUM1[i];
        NUM1[i]=temp;
        temp2=NUM2[y];
        NUM2[y]=NUM2[i];
        NUM2[i]=temp2;
    }
    
    
    for(i=3,l_ncm1=NUM1[2];i<9;i++)
    {
        l_ncm1=(l_ncm1+NUM1[i])/2;
    }
    
    for(i=3,l_ncm2=NUM2[2];i<9;i++)
    {
        l_ncm2=(l_ncm2+NUM2[i])/2;
    }
    
    if(fuhao1>=0)
    {
        num1[0]    = '+';
        num1[1]    =  l_ncm1/10000+'0';
      num1[2]    = (l_ncm1%10000)/1000+'0';
      num1[3]    = (l_ncm1%1000)/100+'0';
      num1[4]    = (l_ncm1%100)/10+'0';
       num1[6]    =  l_ncm1%10+'0';
    }
    else
    {
    
        num1[0]    = '-';
        num1[1]    =  l_ncm1/10000+'0';
      num1[2]    = (l_ncm1%10000)/1000+'0';
      num1[3]    = (l_ncm1%1000)/100+'0';
      num1[4]    = (l_ncm1%100)/10+'0';
       num1[6]    =  l_ncm1%10+'0';
    }
    
 
    
    if(fuhao2>=0)
    {
    
        num2[0] = '+';
    num2[1]    =  l_ncm2/10000+'0';
      num2[2]    = (l_ncm2%10000)/1000+'0';
      num2[3]    = (l_ncm2%1000)/100+'0';
      num2[4]    = (l_ncm2%100)/10+'0';
      num2[6]    =  l_ncm2%10+'0';    
    }
    else
    {    
        num2[0] = '-';
    num2[1]    = l_ncm2/10000+'0';
      num2[2]    = (l_ncm2%10000)/1000+'0';
      num2[3]    = (l_ncm2%1000)/100+'0';
      num2[4]    = (l_ncm2%100)/10+'0';
      num2[6]    =  l_ncm2%10+'0';            
    }
    
//     printf("%s   \n",num1);
//     printf("%s   \n",num2);
    
     Show_RGB(0,72,0,8,White);
     Show_RGB(LCDRight-80,LCDRight,0,8,White);
     LCD_PutString(0,0,num1,Blue,White);
     LCD_PutString(LCDRight-80,0,num2,Blue,White);
    
    

}
posted @ 2015-08-18 21:53  Blue Mountain  阅读(6698)  评论(0编辑  收藏  举报