打印

有谁用过AD7896? 12位串行AD转换IC。

[复制链接]
2999|17
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xzhenggen|  楼主 | 2007-1-16 10:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我按照时序电路写了一个子程序测试为什么测不准?请各位大侠出来指点一下.
#include "reg51.h"
#include "absacc.h"
#include "math.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned  int

sbit SCLK=P1^1;
sbit WDI=P1^2;
sbit SDATA=P1^0;

void delay(uchar n)
{
    uchar i;
    for(i=0;i<n;i++)
    {
        _nop_();
    }
}


uint read7896(void)
{
    char i;
    uint result;
    uchar hbyte, lbyte;

    WDI=0;
    delay(3);
    SCLK=0;
    
    WDI=1;
    delay(3);
    WDI=0;
    for(i=0;i<15;i++)
    {
        _nop_();
    }
    SCLK=1;
    SCLK=0;
    
    hbyte=0;
    for(i=0;i<4;i++)
    {
        SDATA=1;
        SCLK=1;
        if(SDATA) hbyte=0x01;
        SCLK=0;
        if(i!=3) hbyte<<=1;
    }
    lbyte=0;
    for(i=0;i<8;i++)
    {
        SDATA=1;
        SCLK=1;
        if(SDATA) lbyte=0x01;
        SCLK=0;
        if(i!=7) lbyte<<=1;
        
    }
    _nop_();
    _nop_();
    
    WDI=1;
    result=0;
    result=hbyte;
    result<<=8;
        result|=lbyte;
    return (result);
}


void main(void)
{
    uint ad;
        while(1){
    ad=read7896();
         }    
    
    
}
 
 我总觉得我这个子程序有问题,但就是不知错在哪里?有哪位高手出来指点一下,在此多谢了。!!

相关下载

相关帖子

沙发
shiyang800| | 2007-1-16 12:49 | 只看该作者

串行 AD 不需要初始化?!

使用特权

评论回复
板凳
xzhenggen|  楼主 | 2007-1-16 12:57 | 只看该作者

串行 AD (AD7896) 的DATASHEET里面没有说怎样初始化

使用特权

评论回复
地板
xzhenggen|  楼主 | 2007-1-16 13:59 | 只看该作者

重新修改,还是有问题,不知为何?

#include "reg51.h"
#include "absacc.h"
#include "math.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned  int
#define N 128
sbit SCLK=P1^1;
sbit WDI=P1^2;
sbit SDATA=P1^0;
uint xdata Array[N];
void delay(uchar n)
{
    uchar i;
    for(i=0;i<n;i++)
    {
        _nop_();
    }
}

uint read7896(void)
{
    char i;
    uint result;
    uchar hbyte, lbyte;

    WDI=0;
    delay(1);
    SCLK=0;
    
    WDI=1;
    delay(1);
    WDI=0;
    for(i=0;i<15;i++)
    {
        _nop_();
    }
    //SCLK=1;
    //SCLK=0;
    //while(AD_BUSY);
    hbyte=0;
    for(i=0;i<8;i++)
    {
        SDATA=1;
        SCLK=1;
        if(SDATA) hbyte=0x01;
        SCLK=0;
        if(i!=7) hbyte<<=1;
    }
    lbyte=0;
    for(i=0;i<8;i++)
    {
        SDATA=1;
        SCLK=1;
        if(SDATA) lbyte=0x01;
        SCLK=0;
        if(i!=7) lbyte<<=1;
        
    }
    //_nop_();
    //_nop_();
    
    //WDI=1;
    result=0;
    result=hbyte;
    result<<=8;
        result|=lbyte;
    return (result);
}


void main(void)
{
    uint ad;
        while(1){
    ad=read7896();
         }    
    
    
}



相关链接:https://bbs.21ic.com/upfiles/img/20071/2007116135946452.jpg

使用特权

评论回复
5
xzhenggen|  楼主 | 2007-1-16 14:23 | 只看该作者

请圈圈高手出来指点一下。

使用特权

评论回复
6
computer00| | 2007-1-16 15:30 | 只看该作者

没用过这个芯片,不过你这个读数据的程序好象不大对头...

    hbyte=0;
    for(i=0;i<8;i++)
    {
        SDATA=1;
        SCLK=1;
        if(SDATA) hbyte=0x01;
        SCLK=0;
        if(i!=7) hbyte<<=1;
    }
    lbyte=0;
    for(i=0;i<8;i++)
    {
        SDATA=1;
        SCLK=1;
        if(SDATA) lbyte=0x01;
        SCLK=0;
        if(i!=7) lbyte<<=1;
        
    }

改成这样试试:

    SDATA=1;
    for(i=0;i<8;i++)
    {
        hbyte<<=1;
        SCLK=1;
        if(SDATA) hbyte++;
        SCLK=0;
    }

    for(i=0;i<8;i++)
    {
        lbyte<<=1;
        SCLK=1;
        if(SDATA) lbyte++;
        SCLK=0;        
    }

使用特权

评论回复
7
xzhenggen|  楼主 | 2007-1-16 16:36 | 只看该作者

串行读数据不是首先置时钟信号为高电平吗?

对于上升沿驱动的芯片,串行读数据不是首先置时钟信号为高电平吗?
从数据输出口读取数据时,不是应先将时钟信号从低电平跳变到高电平,以使1位数据输出到其输出引脚,从读取该数据。
读串行数据时不是先置时钟信号为高电平的吗?
然后再读一位串行数据;再置时钟信号为低电平,以使下一位数据发生变化。

使用特权

评论回复
8
xzhenggen|  楼主 | 2007-1-16 16:47 | 只看该作者

我到底该用这个DATASHEET的那个时序读数?

使用特权

评论回复
9
xzhenggen|  楼主 | 2007-1-16 16:51 | 只看该作者

第二个

使用特权

评论回复
10
xzhenggen|  楼主 | 2007-1-16 16:52 | 只看该作者

第三个

使用特权

评论回复
11
computer00| | 2007-1-16 17:04 | 只看该作者

前面两个图,要看你所选择的模式了

有高速采样模式和自动睡眠模式.


而读数据,则都是按照下面的图来读.


从这个图来看,数据是在前一个时钟的下降沿发出的,经过T4时间后,数据稳定,这以后可以去读数据.

而在下一个时钟的下降沿到来后,经过T5时间后,数据消失.


按照我上面写的读数据程序,还需要将hbyte的最高位清0,因为从这个图来看,读最高位时,数据还是不确定的。

使用特权

评论回复
12
xzhenggen|  楼主 | 2007-1-16 17:08 | 只看该作者

读串行数据时不是先置时钟信号为高电平的吗?

使用特权

评论回复
13
xzhenggen|  楼主 | 2007-1-16 17:10 | 只看该作者

我那我上面的子程序该如何修改?!

请圈圈再帮我看一看,多谢!

使用特权

评论回复
14
xzhenggen|  楼主 | 2007-1-17 09:24 | 只看该作者

按圈圈的方式,修改如下,不知是不是这样做??


#include "reg51.h"
#include "absacc.h"
#include "math.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned  int

sbit SCLK=P1^1;
sbit WDI=P1^2;
sbit SDATA=P1^0;
//AD_BUSY 没有用上。
void delay(uchar n)
{
    uchar i;
    for(i=0;i<n;i++)
    {
        _nop_();
    }
}

uint read7896(void)
{
    char i;
    int j;
    uint result;
    //uchar hbyte, lbyte;
        result<<=4;/*精确12位,所以左移6位*/
    WDI=1;
    delay(3);
    SCLK=0;
    
    WDI=0;
    delay(3);
    WDI=1;
    for(i=0;i<15;i++)
    {
        _nop_();
    }
    
    
    SDATA=1;

     
    for(j=0;j<16;j++)
    {
        result<<=1;
        SCLK=1;
        _nop_();
        if(SDATA)result++;
        SCLK=0;
     }

    return (result);
}


void main(void)
{
    uint ad;
        while(1){
    ad=read7896();
         }    
    
    
}


使用特权

评论回复
15
xzhenggen|  楼主 | 2007-1-17 10:40 | 只看该作者

晕死我了,圈圈说的,我怎么就弄不了的呢?!

有哪一位高手出来 指点一下。该如何修改子程序啊!!!。。。




数据是在前一个时钟的下降沿发出的,经过T4时间后,数据稳定,这以后可以去读数据.
而在下一个时钟的下降沿到来后,经过T5时间后,数据消失.

使用特权

评论回复
16
computer00| | 2007-1-17 12:10 | 只看该作者

试试这样行不. 或者去网上搜索一下,看有没有现成的例子

uint read7896(void)
{
    char i;
    int j;
    uint result;
    //uchar hbyte, lbyte;
     //   result<<=4;/*精确12位,所以左移6位*/

    SCLK=0;
    WDI=1;
    delay(30);
    WDI=0;
    delay(30);
    
    SDATA=1;
     
    for(j=0;j<16;j++)
    {
        result<<=1;
        SCLK=1;
        _nop_();
        if(SDATA)result++;
        SCLK=0;
     }
    return (result&0x0FFF);
}

使用特权

评论回复
17
xzhenggen|  楼主 | 2007-1-17 12:44 | 只看该作者

多谢圈圈帮忙!我试一下。

使用特权

评论回复
18
tracyking| | 2011-7-16 22:32 | 只看该作者
uint result;  //result为采样值;
        convst=1;   //唤醒AD7896;
        sclk=0;    //时钟线设为0;
        delayus(7);          //等待模拟信号输入稳定;
        convst=0;     //启动ADC;
        deyayus(10);  //等待AD转换结束;
        if(busy==0)          //busy为0则表示转换结束;
        {
                for(k=0;k<16;k++)
                {
                        sclk=1;
                        delayus(2);
                        sclk=0;
                        delayus(2);
                        result=(result<<1)|sda;
                        delayus(2);
                       
                }               
        }
不知道这样行不行?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

55

主题

529

帖子

1

粉丝