AnsweredAssumed Answered

AD7714 self-calibration

Question asked by Cjp3323 on May 28, 2013
Latest reply on Jun 12, 2013 by ChrisD.Rama

Hi,

 

   I'm using the AD7714 to read voltages from two different channels. I read one, then the other, then back to the first one, etc. etc. This only works if I do a self-calibration before each read. If I don't, one of the channels (the channel which was calibrated before the other) will return zero's. In fact, there will be no data on the SPI line.

 

For example, when I run this code:

Cal_Curr_Chan();

Cal_Bat_Chan();

Ic = Read_Current();

V_bat = Read_Bat_Voltage();

 

 

 

The voltage will be read perfectly and the current will return 0. When I flip the order of the calibrations, the current will be read perfectly and the voltage will be 0.

 

The only way I've gotten this to work is to run this code:

Cal_Curr_Chan();

Ic = Read_Current();

Cal_Bat_Chan();

V_bat = Read_Bat_Voltage();

 

 

and I still have to delay in these read functions for it to work consistently. Has anyone ever seen this before and if so, how did you fix it?

My SPI settings are as so:

 

2Mhz SCLK

SCLK is idle LOW

DIN is idle LOW

and

POL pin is grounded

 

The function definitions for the ones stated above are:

 

float Read_Current()

{

    unsigned char byte;

    float voltage, voltage_word = 0, word, i;

 

 

    CS_ADC_LOW;

    byte = SPI_Transfer(0x5D); //command to read data from data reg

    __delay_ms(30); //give DRDY a chance to go high again

    while(DRDY_ADC_PORT); // wait for data to be valid in the adc reg

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

    {

        word = (float)(SPI_Transfer(0));

        voltage_word = word*powf(2,(2-i)*8) + voltage_word;

    }

    CS_ADC_HIGH;

 

    voltage = ((2.50/powf(2,24))*voltage_word)/20.00; //20 is the gain of the amplifier

    return(voltage/0.1); //.05 is the value of the resistor across the terminals of the amp

}

 

 

float Read_Bat_Voltage()

{

    unsigned char byte;

    float voltage = 0, word, i;

 

 

    CS_ADC_LOW;

    byte = SPI_Transfer(0x5C); //command to read data from data reg

    __delay_ms(30); //give DRDY a chance to go high again

    while(DRDY_ADC_PORT); // wait for data to be valid in the adc reg

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

    {

        word = (float)(SPI_Transfer(0));

        voltage = word*powf(2,(2-i)*8) + voltage;

    }

    CS_ADC_HIGH;

    //return the voltage on the voltage divider plus the voltage drop across

    //the 0.05 ohm resistor

    return(((2.50/powf(2,24))*voltage)*16.00 + Ic*0.1);

}

 

void Cal_Curr_Chan()

{

    unsigned char byte;

 

 

    CS_ADC_LOW;

    //Calibration for the AIN3/AIN4 channel

    byte = SPI_Transfer(0x15); //next write to mode reg

    byte = SPI_Transfer(0x20);

    //wait for calibration to complete (DRDY line goes low)

    while(DRDY_ADC_PORT);

    CS_ADC_HIGH;

}

 

 

void Cal_Bat_Chan()

{

    unsigned char byte;

 

 

    CS_ADC_LOW;

    //Calibration for the AIN1/AIN2 channel

    byte = SPI_Transfer(0x14); //next write to mode reg

    byte = SPI_Transfer(0x20);

    //wait for calibration to complete (DRDY line goes low)

    while(DRDY_ADC_PORT);

    CS_ADC_HIGH;

}

 

Before my main loop, I configure all the channels by using this function:

void Config_ADC()

{

    unsigned char byte;

 

 

    CS_ADC_LOW;

    //Configure the ADC channels

    byte = SPI_Transfer(0x25); //next write to filter high reg

    byte = SPI_Transfer(0xC0);

 

 

    byte = SPI_Transfer(0x35); //next write to filter low reg

    byte = SPI_Transfer(0xC0);

    CS_ADC_HIGH;

}

 

Also, I notice in a lot of these posts it is said that DIN must idle high. I don't believe I can do this on this microcontroller unless I make some changes on the PCB. On page 29 of the AD7714 datasheet, it doesn't seem that DIN is preferred high nor low. I also can't find this note that DIN must be high anywhere else on the datasheet. If you can point out why this pin has to idle high or where in the datasheet it recommends this configuration, I'd very much appreciate it.

 

Thanks,

Caleb Pellerin

Raven R&D

Outcomes