搜索
bottom↓
回复: 13

AD7710采集到的电压值比实际电压值大0.034怎么回事

[复制链接]

出0入0汤圆

发表于 2012-4-3 07:28:09 | 显示全部楼层 |阅读模式
本帖最后由 faw 于 2012-4-3 08:55 编辑

AD7710采集到的电压值比实际电压值大0.034怎么回事,使用AVRmega16单片机与AD7710进行数据采集,24位的AD芯片,我怎么感觉连MV级的稳定性都没有呢!
哪位大哥用过请指教。
/*AD7710头文件*/
/*主控芯片为MEGA16单片机*/

/*PC口用于与AD7710通信*/
/*AD7710工作在外部时钟模式,MODE=0*/
/*接口配置
SCLK        -->PC0
SDATA       -->PC1
A0          -->PC2
DRDY        -->PC3
TFS         -->PC5
RFS         -->PC4
*/

/*接口定义*/

#define  SCLK   PC0
#define  SDATA  PC1
#define  A0     PC2
#define  DRDY   PC3
#define  TFS    PC5
#define  RFS    PC4
//读引脚设置                  
#define  SDATA_PIN  PINC1
#define  DRDY_PIN   PINC3
#define  RFS_PIN    PINC4

#define  SCLK_ON    PORTC|=(1<<PC0)
#define  SCLK_OFF   PORTC&=~(1<<PC0)

#define  SDATA_ON   PORTC|=(1<<PC1)
#define  SDATA_OFF  PORTC&=~(1<<PC1)
#define  A0_ON      PORTC|=(1<<PC2)
#define  A0_OFF     PORTC&=~(1<<PC2)

#define  DRDY_ON    PORTC|=(1<<PC3)
#define  DRDY_OFF   PORTC&=~(1<<PC3)

#define  TFS_ON     PORTC|=(1<<PC5)
#define  TFS_OFF    PORTC&=~(1<<PC5)

#define  RFS_ON    PORTC|=(1<<PC4)
#define  RFS_OFF   PORTC&=~(1<<PC4)

/*输入输出设置*/
#define  SCLK_DDR_ON    DDRC|=(1<<PC0)
#define  SCLK_DDR_OFF   DDRC&=~(1<<PC0)

#define  SDATA_DDR_ON   DDRC|=(1<<PC1)
#define  SDATA_DDR_OFF  DDRC&=~(1<<PC1)
#define  A0_DDR_ON      DDRC|=(1<<PC2)
#define  A0_DDR_OFF     DDRC&=~(1<<PC2)

#define  DRDY_DDR_ON    DDRC|=(1<<PC3)
#define  DRDY_DDR_OFF   DDRC&=~(1<<PC3)

#define  TFS_DDR_ON     DDRC|=(1<<PC5)
#define  TFS_DDR_OFF    DDRC&=~(1<<PC5)

#define  RFS_DDR_ON     DDRC|=(1<<PC4)
#define  RFS_DDR_OFF    DDRC&=~(1<<PC4)
/*向AD7710控制寄存器发送24bit数据*/
void send24Bit(unsigned char *Comm)
{
unsigned char i,j,temp;
RFS_DDR_ON;
RFS_ON;//发送数据,不接收数据
A0_DDR_ON ;
A0_OFF;//进入控制寄存器

TFS_DDR_ON;
TFS_ON ;

SCLK_DDR_ON ;
SCLK_OFF ;

SDATA_DDR_ON;

TFS_OFF ;

for(i=0;i<3;i++)
{
temp=*(Comm+i);
        for(j=0;j<8;j++)
        {
                if(temp&0x80)//判断时只判断0和非0
                {
                        SDATA_ON;
                }
                else
                {
                        SDATA_OFF;
                }
                        SCLK_ON;
                        NOP();
                        NOP();       
                        SCLK_OFF;
                temp<<=1;
                }

}


TFS_ON ;
A0_ON;
}




/**********************************************************************

读AD7710控制寄存器,放在*CommReg里

**********************************************************************/
void readCommReg(unsigned char *CommReg)
{
        unsigned char i,j,temp;
        TFS_DDR_ON;
        TFS_ON ;
       
        A0_DDR_ON ;
    A0_OFF;//进入控制寄存器
       
        SCLK_DDR_ON ;
    SCLK_OFF ;
       
        RFS_DDR_ON;
        RFS_ON ;
       
        DRDY_DDR_OFF;
       
        SDATA_DDR_OFF;
        RFS_OFF;
       
        for(i=0;i<3;i++)
        {
                temp=0;
                NOP();
                for(j=0;j<8;j++)
                {
                        temp<<=1;
                        if((PINC&(1<<SDATA_PIN))==(1<<SDATA_PIN))
                        temp|=0x01;       
                        SCLK_ON;
                        NOP();       
                                NOP();       
                       
                        SCLK_OFF;
                }
                *(CommReg+i)=temp;
               
        }
        A0_ON;
        RFS_ON ;

}

/*向AD7710校准寄存器发送24bit数据*/
void send24Bit_corr(unsigned char *corr)
{
unsigned char i,j,temp;
RFS_DDR_ON;
RFS_ON;//发送数据,不接收数据
A0_DDR_ON ;
A0_ON;//进入校准寄存器

TFS_DDR_ON;
TFS_ON ;

SCLK_DDR_ON ;
SCLK_OFF ;

SDATA_DDR_ON;

TFS_OFF ;

for(i=0;i<3;i++)
{
temp=*(corr+i);
        for(j=0;j<8;j++)
        {
                if(temp&0x80)//判断时只判断0和非0
                {
                        SDATA_ON;
                }
                else
                {
                        SDATA_OFF;
                }
                        SCLK_ON;
                        NOP();               
                        SCLK_OFF;
                temp<<=1;
        }

}


TFS_ON ;
A0_OFF;
}




/**********************************************************************

读AD7710校准寄存器,放在*CorrReg里

**********************************************************************/
void read_corr_reg(unsigned char *CorrReg)
{
        unsigned char i,j,temp;
        TFS_DDR_ON;
        TFS_ON ;
       
        A0_DDR_ON ;
    A0_ON;//进入校准寄存器
       
        SCLK_DDR_ON ;
    SCLK_OFF ;
       
        RFS_DDR_ON;
        RFS_ON ;
       
        DRDY_DDR_OFF;
       
        SDATA_DDR_OFF;
        RFS_OFF;
       
        for(i=0;i<3;i++)
        {
                temp=0;
                NOP();
                for(j=0;j<8;j++)
                {
                        temp<<=1;
                        if((PINC&(1<<SDATA_PIN))==(1<<SDATA_PIN))
                        temp|=0x01;       
                        SCLK_ON;
                        NOP();               
                        SCLK_OFF;
                }
                *(CorrReg+i)=temp;
               
        }
        A0_OFF;
        RFS_ON ;

}



/**********************************************************************

读AD7710数据寄存器,放在*CorrReg里

**********************************************************************/
void read_data_reg(unsigned char *dataReg)
{
        unsigned char i,j,temp;
        TFS_DDR_ON;
        TFS_ON ;
       
        A0_DDR_ON ;
    A0_ON;//进入数据寄存器
       
        SCLK_DDR_ON ;
    SCLK_OFF ;
       
        RFS_DDR_ON;
        RFS_ON ;
       
        DRDY_DDR_OFF;
       
        SDATA_DDR_OFF;
       
while((PINC&(1<<DRDY_PIN))==(1<<DRDY_PIN));
       
        RFS_OFF;
       
        for(i=0;i<3;i++)
        {
                temp=0;
                NOP();
                for(j=0;j<8;j++)
                {
                        temp<<=1;
                        if((PINC&(1<<SDATA_PIN))==(1<<SDATA_PIN))
                        temp|=0x01;       
                        SCLK_ON;
                        NOP();               
                        SCLK_OFF;
                }
                *(dataReg+i)=temp;
               
        }
        A0_OFF;
        RFS_ON ;

}




#include<iom16v.h>
#include<macros.h>
#include<delay.h>
#include"AD7710.h"
#include"lcd12864.h"
#include"usart.h"
unsigned char flag=0;
void main()
{
unsigned char init,k;
unsigned char readdata[3];

//CLI();
//TCNT0=0x00;
//TCCR0=0x02;//普通模式,内部时钟8分频
//TIMSK=0x01;//打开T0中断

Lcd_INT();
uart_init();
SEI();
init=init_ad7710();

if(init==0x00)
{
LCD_Write_string(0,0,"7710 INIT FAULT");
LCD_Write_string(1,4,"ko");//初始化不成功显示KO
}
else
{
LCD_Write_string(0,0,"AD7710初始化成功");
LCD_Write_string(2,4,"ok");//初始化成功显示OK
}

k=10;

while(flag)
{

read_data_reg(readdata);
while(k)
{
k--;
putchar(readdata[0]);
putchar(readdata[1]);
putchar(readdata[2]);
}
}

conver16_10(readdata);



}


conver16_10()
{
unsigned char i=5;
unsigned int data10[6],data16[6];
unsigned int sum=0,advalue,admv[6];




data10[0]=(data16[0]>>4)*16*16*16*16*16;
//data16[0]=(*data_16+0);
data10[1]=(data16[0]&0x0f)*16*16*16*16;

data10[2]=(data16[1]>>4)*16*16*16;
//data16[1]=(*data_16+1);
data10[3]=(data16[1]&0x0f)*16*16;

data10[4]=(data16[2]>>4)*16;
//data16[2]=(*data_16+2);
data10[5]=(data16[2]&0x0f)*1;
//2.1436./852216
for(i=0;i<6;i++)
{
sum=sum+data10;
}
sum=2.14368852216;
advalue=(sum*2.5)/16777216;
advalue=2.14368852216;
advalue=advalue*10000;
//advalue=2.14368852216;


advalue=21345.899;
admv[0]=(advalue/10000);
admv[1]=((advalue%10000)/1000);


lcd_write2(1,2,(advalue/10000));
lcd_write2(1,3,(advalue%10000)/1000);




}







lcd1()
{
LCD_Write_string(0,1,"发动机循环水");
LCD_Write_string(1,0,"温度");
LCD_Write_string(1,4,"压力");
LCD_Write_string(2,0,"水池液位");
LCD_Write_string(2,6,"m");
LCD_Write_string(3,0,"系统状态:");
}
lcd2()
{
LCD_Write_string(0,1,"测功机循环水");
LCD_Write_string(1,0,"温度");
LCD_Write_string(1,4,"压力");
LCD_Write_string(2,0,"水池液位");
LCD_Write_string(3,0,"系统状态:");
}

lcd3()
{
LCD_Write_string(0,1,"冷冻水");
LCD_Write_string(1,0,"温度");
LCD_Write_string(1,4,"压力");
LCD_Write_string(2,0,"水池液位");
LCD_Write_string(3,0,"系统状态:");
}

init_ad7710()
{
unsigned char i,j,result;
unsigned char CtrlReg[3];
unsigned char readtemp[3];
CtrlReg[0]=0x20;
CtrlReg[1]=0x93;
CtrlReg[2]=0x0D;
send24Bit(CtrlReg);
        delay_nus(32);               
readCommReg(readtemp);
i=0x00;
        while(i<5)
        {
                result=0xff;
                for(j=0;j<3;j++)
                {
                 
                  if(readtemp[j]!=CtrlReg[j])
                        {
                                result=0x00;
                                putstr("error");// 若不相等在串口上输出ERROR
                        }                       
                }
                if(result)
                {   putstr("ok");// 若相等在串口上输出ok
                        return(result);
                }
                i++;
                send24Bit(CtrlReg);
                delay_nus(32);               
                readCommReg(readtemp);
               
        }
        return(result);
}
/*

#pragma  interrupt_handler timer0:10  //定时器T0的入口地址
  void timer0 (void)
  {
  CLI();
  
// LCD_Write_string(3,0,"系统状态:");
  flag=~flag;
  SEI();
  
         }
         
         */

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2012-4-3 08:11:39 | 显示全部楼层
虽然我没有用过AD7710,但你这样问估计没人可以帮你。至少把电路图发出来啊

出0入0汤圆

 楼主| 发表于 2012-4-3 08:56:15 | 显示全部楼层
maiyingzhao 发表于 2012-4-3 08:11
虽然我没有用过AD7710,但你这样问估计没人可以帮你。至少把电路图发出来啊 ...

已经更新了

出0入0汤圆

发表于 2012-4-3 09:15:27 | 显示全部楼层
确定layout符合规范吗

出0入0汤圆

发表于 2012-4-3 09:59:19 | 显示全部楼层
是固定偏差吗?检查一下基准,另外,也有可能是INL的问题

出0入0汤圆

 楼主| 发表于 2012-4-3 10:05:51 | 显示全部楼层
leifeng 发表于 2012-4-3 09:59
是固定偏差吗?检查一下基准,另外,也有可能是INL的问题

是固定的偏差,INL是什么意思?

出0入0汤圆

 楼主| 发表于 2012-4-3 10:10:17 | 显示全部楼层
monlika 发表于 2012-4-3 09:15
确定layout符合规范吗

电路板自己搭的

出0入0汤圆

发表于 2012-4-3 11:05:31 | 显示全部楼层
积分非线性表示了ADC器件在所有的数值点上对应的模拟值和真实值之间误差最大的那一点的误差值,也就是输出数值偏离线性最大的距离。单位是LSB。例如,一个12bit的ADC,INL值为1LSB,那么,对应基准4.095V,测某电压得到的转换结果是1.000V,那么,真实电压值可能分布在0.999V到1.001V之间。
>你的问题可以通过自校准来解决,详见datasheet.

出0入0汤圆

 楼主| 发表于 2012-4-3 14:56:32 | 显示全部楼层
leifeng 发表于 2012-4-3 11:05
积分非线性表示了ADC器件在所有的数值点上对应的模拟值和真实值之间误差最大的那一点的误差值,也就是输出 ...

之间测试的电压值使用电位器搭建的,模拟电压输入,我用万用表测试一下,发现变化极大,在几十MV波动,后来改变方法用AD7710自己的refOUT2.5V输出进行模拟输入,发现采集到的电压值和实际的电压值相差0.002V,也就是2MV,我想24位的AD,2MV也是不能接受的!
请指教.....

出0入0汤圆

发表于 2012-4-3 15:43:16 | 显示全部楼层
输入有电容吗?

出0入0汤圆

 楼主| 发表于 2012-4-3 16:38:26 | 显示全部楼层
leifeng 发表于 2012-4-3 15:43
输入有电容吗?

没有电容,就只一根线从REFOUT2.5V直接接到了,in1+,IN1-接GND

出0入0汤圆

 楼主| 发表于 2012-4-4 06:20:16 | 显示全部楼层
leifeng 发表于 2012-4-3 11:05
积分非线性表示了ADC器件在所有的数值点上对应的模拟值和真实值之间误差最大的那一点的误差值,也就是输出 ...

请问一下系统校准需要人为将输入端短接吗?手册说的也不详细!

出0入0汤圆

发表于 2013-11-18 18:11:41 | 显示全部楼层
你的AD7710的有效位数能达到多少位啊

出0入85汤圆

发表于 2013-11-18 18:12:41 | 显示全部楼层
地没有处理好吧
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 18:15

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表