关于AD7689数据采集的问题

        大家好,我现在用TI的DSP28335通过SPI与AD7689通讯,读出的数据变化非常大,也没有规律(比如0,540,2048,3680,4,1024等等),AD7689配置寄存器是0xF104。请问哪位能指导一下,或者有没有程序参考一下,谢谢!

Parents
  • //Head files

    #include <ADuC7026.H>

    #include "functions.h"

     

    #define
    SET_CNV()                                       
    GP1DAT = (GP1DAT |
    0x00040000)           
    //P1.2->CNV             
    -- P3.40: Brown  -- A17

    #define
    CLR_CNV()                                       
    GP1DAT = (GP1DAT & 0xFFFBFFFF)

    #define
    SET_CS()                                           
    GP1DAT = (GP1DAT |
    0x00800000)           
    //

    #define
    CLR_CS()                                          
    GP1DAT = (GP1DAT &
    0xFF7FFFFF)           

    #define SET_SCK() GP1DAT = (GP1DAT | 0x00100000) //P1.4->SCK -- P3.38: White   -- A9

    #define
    CLR_SCK()                                        
    GP1DAT = (GP1DAT &
    0xFFEFFFFF)           

    #define
    MISO_BIT                                        
    (GP1DAT &
    0x00000020)                             
    //P1.5->MISO -- P3.35: Grey     -- B11

    #define
    SET_MOSI()                                     
    GP1DAT = (GP1DAT |
    0x00400000)           
    //P1.6->MOSI -- P3.34: Green

    #define
    CLR_MOSI()                                     
    GP1DAT = (GP1DAT & 0xFFBFFFFF)

     

    #define
    LED2_ON()                                      
    GP4DAT = (GP4DAT &
    0xFFFEFFFF)           
    //P4.0->LED2

    #define
    LED2_OFF()                                     
    GP4DAT = (GP4DAT | 0x00010000)

    #define
    LED3_ON()                                      
    GP4DAT = (GP4DAT &
    0xFFFDFFFF)           
    //P4.1->LED3

    #define
    LED3_OFF()                                     
    GP4DAT = (GP4DAT | 0x00020000)

    #define
    LED4_ON()                                      
    GP4DAT = (GP4DAT &
    0xFFFBFFFF)           
    //P4.2->LED4

    #define
    LED4_OFF()                                     
    GP4DAT = (GP4DAT | 0x00040000)

     

    volatile unsigned char
    Timer1_flag;         // Timer1 interrupt
    flag

    ///////////////////////////////////////////////////////////////////////////////////////////////////////

    void AD7689_gpiospiwrite_L14bitword(unsigned short
    data)           //CS low for
    reading 1 word from the first channel

    {

                 
    int i=0;

                 
    unsigned short temp=0;

                 
    temp = data;

    //Initial CNV=0, SCK=0

                 
    temp = temp << 2;

                 
    for (i=0;i<16;i++)

                 
    {

                                
    if(0x8000 == (temp & 0x8000))

                 
                                
    SET_MOSI();

                                
    else

                                               
    CLR_MOSI();

                                
    temp = temp << 1;

                                
    SET_SCK();           //rising
    edge for write in

                                
    CLR_SCK();

                 
    }

                 
    CLR_MOSI();                    
    //AD7689 SDI should be idle low

    }

     

    unsigned short AD7689_gpiospireadword_writeL14bitword(unsigned
    short data)    //CS low for reading 1 word from the first
    channel

    {

                 
    int i=0;

                 
    unsigned short temprev = 0, tempsend = 0;

    //CNV=0, SCK=0

                 
    tempsend = data;

                 
    tempsend = tempsend << 2;

                 
    for (i=0;i<14;i++)

                 
    {

                                
    temprev = temprev << 1;

                                
    if (MISO_BIT!=0)

                                               
    temprev = temprev + 1;

                                
    else

                                               
    ;

     

                                
    if(0x8000 == (tempsend & 0x8000))

                                               
    SET_MOSI();

                                
    else

                                               
    CLR_MOSI();

                                
    tempsend = tempsend << 1;

                                
    SET_SCK();

                                
    CLR_SCK();          //falling edge
    for MSB-1, ...

                                
    CLR_MOSI();       //MOSI idle low

                 
    }

                                
    for (i=14;i<16;i++)

                 
    {

                                
    temprev = temprev << 1;

                                
    if (MISO_BIT!=0)

                                               
    temprev = temprev + 1;

                                
    else

                                               
    ;

                                
    SET_SCK();

                                
    CLR_SCK();          //falling edge
    for MSB-1, ...

                 
    }

                 
    return temprev;

    }

     

    void AD7689_gpiospiread_word(unsigned char
    *data)        //CS low for reading 1 word from
    the first channel

    {

                 
    int i=0;

     

    //          
    CLR_CS();           
    //CS falling edge output first MSB

                 
    for (i=0;i<8;i++) //CNV falling for MSB

                 
    {

                                
    *data = (*data) << 1;

                                
    if (MISO_BIT!=0)

                                               
    *data = (*data)+1;

                                
    else

                                               
    ;

                                
    SET_SCK();           //

                                
    CLR_SCK();          //SCK falling
    edge for MSB-1, ...

                                
    delay1us(10);

                 
    }

                 
    data++;

                 
    for (i=0;i<8;i++)

                 
    {

                                
    *(data) = (*(data)) << 1;

                                
    if (MISO_BIT!=0)

                                               
    *(data) = (*(data))+1;

                                
    else

                                               
    ;

                                
    SET_SCK();                        
    //

                                
    CLR_SCK();          //intially low

                                
    delay1us(10);

                 
    }

    //          
    SET_CS();

                 
    data--;

    }

    ///////////////////////////////////////////////////////////////////////////////////////////

     

    void ADuC7026_Initiate(void)

    {

    /*         
    */

    }

                                

    void AD7689_Initiate(void)

    {

                                
    int i=0;

                                
    CLR_SCK();          //initially low

                                
    CLR_CNV();//intially high

                                
    //idle conv after power up

                                
    SET_CNV();

                                
    delay1us(10);      //delay 4us, tCONV > 2.2us for no
    BUSY Indicator

                                
    CLR_CNV();

                                
    //Configuration Register:

                                
    //[13] = 1: overwrite contents of register.

                                
    //[12:10] = 111: Unipolar, INx referenced to GND.

                                
    //[9:7] = 111: IN7

                                
    //[6] = 1: full BW.

                                
    //[5:3] = 110:External reference 5V, driver disabled, temperature disabled.

                                
    //[2:1] = 11 :scan from IN0 to CFG[9:7].

                                
    //[0] = 1:do not read back contents of configuration.

                                
    AD7689_gpiospiwrite_L14bitword(0x3FC7);//8 ch selected in sequencer, full bandwidth,
    external REF,

                                
    delay1us(10);

                                
    for (i=0;i<1;i++)  //delay one phase

                                
    {

                                               
    SET_CNV();

                                               
    delay1us(10);      //delay 4us, tCONV > 2.2us for
    no BUSY Indicator

                                               
    CLR_CNV();

                                               
    delay1us(10);

                                
    }

    }

     

    int main (void)

    {

    //          
    unsigned char HByte=0, LByte=0;

                 
    unsigned char combuf[4]={0};

                 
    unsigned long T1_LD=0;

                 
    unsigned long CNVNum = 0, convnum=0,convcount=0;

                 
    unsigned char
    adcbuf_2Byte[2]={0};          //1
    word

                 
    unsigned short adcrevbuf=0;

                 
    unsigned char CHNum = 8;

     

                 
    ADuC7026_Initiate();                                                  
    //ADuC7026 Initiation

                 
    AD7689_Initiate();

    /*** UART ***/

                 
    COMIEN0 =
    0x01;                                                                                      
    //Enable Receive Buffer Full Interrupt

                 
    IRQEN =
    0x00004000;                                                
                 
    // Enable UART interupt

     

                 
    while(1)

                 
    {

                                                              
    Intcount=0;

                                                              
    convcount=0x08;

                                                              
    convnum=CNVNum;

                                                              
    while (convnum)

                                                              
    {

                                                                             
    LED3_ON();

                                                                             
    LED4_ON();

                                                                             
    adcbuf_2Byte[0] = 0;

                                                                             
    adcbuf_2Byte[1] = 0;

                                                                             
    SET_CNV();

                                                                             
    delay1us(10);      //delay 4us, tCONV > 2.2us for
    no BUSY Indicator

                                                                             
    CLR_CNV();

                                                                                            
    if (convcount%CHNum==0)//IN0

                                                                                            
    {

                                                                                            
                 
    AD7689_gpiospiread_word(adcbuf_2Byte);

                                                                                            
    }

                                                                                            
    else if (convcount%CHNum==1)//IN1

                                                                                            
    {

                                                                                            
                 
    AD7689_gpiospiread_word(adcbuf_2Byte);

                                                                                            
    }

                                                                                            
    else if (convcount%CHNum==2)//IN2

                                                                                            
    {

                                                                                            
                 
    AD7689_gpiospiread_word(adcbuf_2Byte);

                                                                                            
    }

                                                                                            
    else if (convcount%CHNum==3)//IN3

                                                                                            
    {

                                                                                            
                 
    AD7689_gpiospiread_word(adcbuf_2Byte);

                                                                                            
    }

                                                                                            
    else if (convcount%CHNum==4)//IN4

                                                                                            
    {

                                                                                            
                 
    AD7689_gpiospiread_word(adcbuf_2Byte);

                                                                                            
    }

                                                                                            
    else if (convcount%CHNum==5)//IN5

                                                                                            
    {

                                                              
                                
                 
    AD7689_gpiospiread_word(adcbuf_2Byte);

                                                                                            
    }

                                                                                            
    else if (convcount%CHNum==6)//IN6

                                                                                            
    {

                                                                                            
                 
    AD7689_gpiospiread_word(adcbuf_2Byte);

                                                                                            
    }

                                                                                            
    else if (convcount%CHNum==7)//IN7

                                                                                            
    {

                                                                                            
                 
    AD7689_gpiospiread_word(adcbuf_2Byte);

                                                                                            
    }

                                                                                            
    else

                                                                                            
    {;}

                                                                                            
    putchar(adcbuf_2Byte[0]);//MSB byte     

                                                                                            
    putchar(adcbuf_2Byte[1]);

     

                                                                                            
    convnum--;

                                                                                            
    convcount++;

                                                              
    }//while

                                               
       LED3_OFF();

                                               
       if (convcount==CNVNum)

                                                              
    LED4_OFF();                                    
     
                             

                                               
    }//else if (0x11 == combuf[0])

     

                 
    }

                 
    return 0;

    }

  • 您好,研究AD7689的数据手册好久了,我这里发现了几种测试现象如下所示:

    1-使用内部VREF 2.5输作为基准源输出,VREFIN VREF都接了电容,就是有时重新上电没有电压-现在我把VREFIN和VREF短接在一起,测量出的电压是4.9V(外部供电5V),  这样问题基本解决,但是很奇怪为什么选择的是2.5V,测量的输出是4.9V呢

    2-使用您上边的程序,虽然测量有数据输出(不是之前的0XFFFF),但是总是感觉通道错了一位,我的的程序就在您的基础上加了打印的语句,并没有影响您的初始化和采样逻辑顺序,输出的结果如下,(我先打印了8个通道的结果,最后的DA=?代表外边实际加的电压)-----现在怀疑程序的延时是不是对结果有很明显的影响啊,如您文章中加的延时我都加的足够长了。

    init ok
    CH0=:2.50 CH1=:1.46 CH2=:1.31 CH3=:1.25 CH4=:0.27 CH5=:1.24 CH6=:0.34 CH7=:0.55 DA=0.06
    CH0=:0.74 CH1=:0.81 CH2=:1.24 CH3=:1.15 CH4=:1.25 CH5=:0.27 CH6=:1.24 CH7=:0.34 DA=0.06
    CH0=:0.51 CH1=:0.45 CH2=:0.60 CH3=:1.25 CH4=:1.12 CH5=:1.25 CH6=:0.27 CH7=:1.24 DA=0.12
    CH0=:0.34 CH1=:0.23 CH2=:0.47 CH3=:0.62 CH4=:1.24 CH5=:1.11 CH6=:1.25 CH7=:0.27 DA=0.18
    CH0=:1.24 CH1=:0.34 CH2=:0.48 CH3=:0.66 CH4=:0.71 CH5=:1.24 CH6=:1.11 CH7=:1.25 DA=0.24
    CH0=:0.27 CH1=:1.24 CH2=:0.34 CH3=:0.49 CH4=:0.66 CH5=:0.71 CH6=:1.24 CH7=:1.11 DA=0.31
    CH0=:1.25 CH1=:0.27 CH2=:1.24 CH3=:0.35 CH4=:0.49 CH5=:0.66 CH6=:0.71 CH7=:1.24 DA=0.37
    CH0=:1.11 CH1=:1.25 CH2=:0.27 CH3=:1.24 CH4=:0.41 CH5=:0.55 CH6=:0.68 CH7=:0.74 DA=0.43
    CH0=:1.24 CH1=:0.67 CH2=:1.25 CH3=:0.27 CH4=:1.24 CH5=:0.47 CH6=:0.57 CH7=:0.71 DA=0.49
    CH0=:0.77 CH1=:1.25 CH2=:1.11 CH3=:1.25 CH4=:0.27 CH5=:1.24 CH6=:0.53 CH7=:0.62 DA=0.55
    CH0=:0.74 CH1=:0.41 CH2=:1.24 CH3=:1.11 CH4=:1.25 CH5=:0.27 CH6=:1.24 CH7=:0.60 DA=0.61
    CH0=:0.68 CH1=:0.43 CH2=:0.56 CH3=:1.24 CH4=:1.11 CH5=:1.25 CH6=:0.27 CH7=:1.24 DA=0.67
    CH0=:0.66 CH1=:0.36 CH2=:0.57 CH3=:0.67 CH4=:1.24 CH5=:1.11 CH6=:1.25 CH7=:0.27 DA=0.73
    CH0=:1.24 CH1=:0.78 CH2=:0.77 CH3=:0.83 CH4=:0.84 CH5=:1.24 CH6=:1.11 CH7=:1.25 DA=0.79
    CH0=:0.27 CH1=:1.24 CH2=:0.84 CH3=:0.82 CH4=:0.88 CH5=:0.87 CH6=:1.24 CH7=:1.11 DA=0.85
    CH0=:1.25 CH1=:0.27 CH2=:1.24 CH3=:0.91 CH4=:0.88 CH5=:0.92 CH6=:0.90 CH7=:1.24 DA=0.92
    CH0=:1.11 CH1=:1.25 CH2=:0.27 CH3=:1.24 CH4=:0.97 CH5=:0.89 CH6=:0.91 CH7=:0.90 DA=0.98
    CH0=:1.24 CH1=:0.68 CH2=:1.25 CH3=:0.27 CH4=:1.24 CH5=:1.03 CH6=:0.95 CH7=:0.97 DA=1.04
    CH0=:0.92 CH1=:1.25 CH2=:1.11 CH3=:1.25 CH4=:0.27 CH5=:1.24 CH6=:1.09 CH7=:1.00 DA=1.10
    CH0=:0.99 CH1=:0.54 CH2=:1.24 CH3=:1.11 CH4=:1.25 CH5=:0.27 CH6=:1.24 CH7=:1.16 DA=1.16
    CH0=:1.03 CH1=:0.61 CH2=:0.70 CH3=:1.24 CH4=:1.11 CH5=:1.25 CH6=:0.27 CH7=:1.24 DA=1.22
    CH0=:1.22 CH1=:0.65 CH2=:0.75 CH3=:0.79 CH4=:1.24 CH5=:1.11 CH6=:1.25 CH7=:0.27 DA=1.28
    CH0=:1.24 CH1=:1.34 CH2=:1.13 CH3=:1.06 CH4=:1.00 CH5=:1.24 CH6=:1.11 CH7=:1.25 DA=1.34
    CH0=:0.27 CH1=:1.24 CH2=:1.41 CH3=:1.19 CH4=:1.13 CH5=:1.03 CH6=:1.24 CH7=:1.11 DA=1.40
    CH0=:1.25 CH1=:0.27 CH2=:1.24 CH3=:1.47 CH4=:1.22 CH5=:1.16 CH6=:1.06 CH7=:1.24 DA=1.46
    CH0=:1.11 CH1=:1.25 CH2=:0.27 CH3=:1.24 CH4=:1.53 CH5=:1.28 CH6=:1.15 CH7=:1.06 DA=1.53
    CH0=:1.24 CH1=:0.68 CH2=:1.25 CH3=:0.27 CH4=:1.24 CH5=:1.60 CH6=:1.30 CH7=:1.18 DA=1.59
    CH0=:1.09 CH1=:1.25 CH2=:1.11 CH3=:1.25 CH4=:0.27 CH5=:1.24 CH6=:1.66 CH7=:1.36 DA=1.65
    CH0=:1.22 CH1=:0.68 CH2=:1.24 CH3=:1.11 CH4=:1.25 CH5=:0.27 CH6=:1.24 CH7=:1.72 DA=1.71
    CH0=:1.42 CH1=:0.82 CH2=:0.84 CH3=:1.24 CH4=:1.11 CH5=:1.25 CH6=:0.27 CH7=:1.24 DA=1.77
    CH0=:1.78 CH1=:0.96 CH2=:0.97 CH3=:0.92 CH4=:1.24 CH5=:1.11 CH6=:1.25 CH7=:0.27 DA=1.83

    硬件电路图如下所示

    主程序的代码如下所示

    uint8_t i,j=0;
    uint16_t value;
    printf("init ok\r\n");
    AD7689_Initiate();
    for(;;)
    {
    osSemaphoreWait(tickHandle,osWaitForever);
    da7311Out(1,DA_CH1);//16*200=3200
    for(i=0;i<8;i++)
    {
    AD_VAL[i] = AD7689_read(i);
    printf("CH%d=:%3.2f ",i,(float)AD_VAL[i]*2.5/65536);
    }
    if(DA_CH1 == 4096) DA_CH1=0;

    printf("DA=%3.2f\r\n",(float)DA_CH1*2.5/4096);
    set_value.Real_Voltage=AD_VAL[2]*2.5/65536;
    set_value.Output_Voltage=(float)DA_CH1*2.5/4096;

    }

    其中AD7689_read()

    uint16_t AD7689_read(uint8_t AD7689_INx)
    {
    unsigned short AD7689_Data=0;
    SET_CNV();
    delay1us(100); //delay 4us, tCONV > 2.2us for no BUSY Indicator
    CLR_CNV();
    AD7689_gpiospiread_word(&AD7689_Data);
    osDelay(20);
    return AD7689_Data*2;//此处*2感觉数据能对上
    }

    希望能帮我查下问题,搞得真头大!裸机跑每次上电采样值和通道固定输出都不一样

Reply Children
No Data