Post Go back to editing

ADC problem about ADUC7061

I post this problem in chinese version, but the china engineer can't give correct answer. So i want to post it here to found an more senior engineer. 

As you know, ADC1~ADC5 are single function port. but ADC6~ADC9 are mutil-function prots.

The SPI/I2C and analog can be changed.

I write code to sample analog signle from ADC4 and ADC8, ADC 4 is connected to ADC8 together.

But when i read, value from ADC4 is correct, but data from ADC8 is not correct.

When the voltage is 0.67V around. the value from ADC4 is 0x004xxxxx, but value from ADC8 is about 0x000005xx.

When i change the voltage, value from ADC8 will not change, or chage slightly. for example, 0x5ff, 0x5fe.

When i change another device(CPU chip), the value will be 0x606, 0x607.

I  deduce:

there are some bug in device. and the codes to initiate ADC1 need special sequence.

the Datasheed does not tell me what is sequence, the special sequence, so i get wrong result.

I can't find example code how to use adc6~adc9,  will anyone give correct resolution?

thanks.

I post my code here:

int main()
{
volatile signed long s;
signed char N = -1;
char Err = 0;
float fN = 0;

PLLKEY1 = 0xaa;
PLLCON = 0x00;
PLLKEY2 = 0x55;

POWKEY1 = 0x1;
POWCON0 = 0x38; // Set core to max CPU speed of 10.24Mhz
POWKEY2 = 0xF4;

POWKEY3 = 0x76;
POWCON1 = 0x024;
POWKEY4 = 0xB1;

DACCON = 0x0013;
DACDAT = 0x04ff0000;


while(1)
{

ADCCFG = 0x84;
ADCFLT = 0x8083;

GP0CON0 = 0x00000000; //p0.0~p0.4 gpio
GP0PAR = 0x0f; //01110
GP0DAT = 0x10100000;

GP0KEY1 = 0x7;
GP0CON1 = 0x1; // adc
GP0KEY2 = 0x13;

ADC0CON = 0;
ADC1CON = 0x878c;;

s = ADCSTA;
s = ADC0DAT;
s = ADC1DAT;
//////////
ADCMDE = 0x83;
////
ADC1CON = 0x8004 | 0x0480;//ch 8
//ADC1CON = 0x800c | 0x0300;//ch 4

s = ADC1DAT;
s = ADCSTA;
ADCMDE = 0x82;
do
{
s = ADCSTA;
if (s & 0x2000) //adc1cerr
{
Err |= 1; //over range
}
} while(!(s & 0x2));

s = ADC1DAT;
ADCMDE = 0x83;

//3. exit adc
ADCMDE = 0x83; //idle
ADCFLT = 0x80ff;
ADC1CON = 0x78c; //internally shorted

GP0CON0 = 0x00001011; //back to spi
GP0PAR = 0x04;
GP0DAT = 0x10100000;

GP0KEY1 = 0x7;
GP0CON1 = 0x0; // exit adc
GP0KEY2 = 0x13;
}
}

  • Hi,

    You mentioned that CH4 is working while CH8 is not but looking at the configuration below, there is another difference. You bypass both buffer when reading from CH4. Can you try to bypass the buffer when using CH8 as well? This is just to check if we have an issue with the buffer. 

    ADC1CON = 0x8004 | 0x0480;//ch 8
    //ADC1CON = 0x800c | 0x0300;//ch 4

    Also, I think the lines below can be skipped.

    GP0CON0 = 0x00000000; //p0.0~p0.4 gpio
    GP0PAR = 0x0f; //01110
    GP0DAT = 0x10100000;

     

    regards,

    Mark

  • I have tried all 4 different configuuatoin modes of buffer. 

    I have read a topic 2011, an old topic.

    It seems a bug in aduc7061. Perhaps, it will work in aduc7060, but it will not work in 7016.

    In the topic, It said that several code should be add in startup.asm file before _ld _main.

    I am not sure if it is true.

    It seems there is bug for 32 pin package, but perhaps, it is ok in 48 pin package( ie 7060).

    I can't find useful example to usd ADC8 in aduc7061 from ADI .

  • ADC1CON = 0x8004 | 0x0480;//ch 8

    ADC1CON = 0x800C | 0x0480;//ch 8

    and other two mode are tried also.

    This code can't be removed.

    I don't know the reason, but if i removed, the system will not work correctly.

    GP0CON0 = 0x00000000; //p0.0~p0.4 gpio
    GP0PAR = 0x0f; //01110
    GP0DAT = 0x10100000;

    And someone, ADI engineer, said, the leakage of CH8 is 25nA at most. In fact, the leakage is very large.

    So i can't belive the datesheet sometimes.

    Perhaps, it is ok in aduc7060, but not correct in aduc7061.

    these strange apperances support me to belive that perhaps there is configure bug in duc7061. Perhaps adi will write some configure paremeters or code in factory before  downline.

  • if i change GP0PAR = 0x0f; //01110 for different value, pull-up or not, the ADC value is diffent.

    logically, if I set the pin as analog input, the configure of digital GPIO will not  affact ananlog function.

    But in facts, it  will affect each other.

    So, the device appears not as gerenal CPU of TI, ST, NXP. etc.

  • Hi, please give me until the end of next week to test this in the lab.

    regards,

    Mark

  • Several weeks i can't get correct ADC samples from channel8, signal from DAC. so  i guess there is something wrong on analogue mux.

    But now, i found that the true is that when port 0 used as analugue, the dac will not work correctly.

    If you use debug, the code will work correctly, and the DAC output will be ok, but when it  runs freely, the output is not correct..

  • I have checked it for several weeks,

    In facts, the ADC is correct. the reason to make wrong data of ADC is that the DAC will not work when P0 is configured as analogue input. the DAC will not ouput linear voltage.

    Finally, when USE jlink, device works correctly after programming, but will not work correctly after reset again by power off and on.

    when use ULINK, device work incorrectly after programming, but it will work in debug mode, run or step by step. if the devcei is resetted again by poweroff/on, the devcei will not work correctly again.

  • I have checked it for several weeks,

    In facts, the ADC is correct. the reason to make wrong data of ADC is that the DAC will not work when P0 is configured as analogue input. the DAC will not ouput linear voltage.

    Finally, when USE jlink, device works correctly after programming, but will not work correctly after reset again by power off and on.

    when use ULINK, device work incorrectly after programming, but it will work in debug mode, run or step by step. if the devcei is resetted again by poweroff/on, the devcei will not work correctly again.

  • Hi,
    I have gone through the code and added some comments to it. I will suggest to disable the SPI/I2C blocks when converting from ADC. Also please take note of the device selection on your compiler, use ADuC7061 instead of ADuC7060. What compiler are you using?

    int main()
    {
    volatile signed long s;
    signed char N = -1;
    char Err = 0;
    float fN = 0;

    PLLKEY1 = 0xaa;
    PLLCON = 0x00;
    PLLKEY2 = 0x55;

    POWKEY1 = 0x1;
    POWCON0 = 0x38; // Set core to max CPU speed of 10.24Mhz
    POWKEY2 = 0xF4;

    POWKEY3 = 0x76;
    POWCON1 = 0x024; --> Please use 0x020 this if using ADC6 to 9
    POWKEY4 = 0xB1;

    DACCON = 0x0013;
    DACDAT = 0x04ff0000;


    while(1)
    {

    GP0CON0 = 0x00000000; //p0.0~p0.4 gpio
    GP0PAR = 0x0f; //01110
    GP0DAT = 0x10100000;

    GP0KEY1 = 0x7;
    GP0CON1 = 0x1; // adc
    GP0KEY2 = 0x13;

    ADCCFG = 0x84; -->Moved after GPIO CFG
    ADCFLT = 0x8083;
    ADC0CON = 0;
    ADC1CON = 0x878c; --> This is an internal short to ADC3. Are you measuring ADC3 intentionally?

    s = ADCSTA;
    s = ADC0DAT;
    s = ADC1DAT;
    //////////
    ADCMDE = 0x83; //idle mode
    ////
    ADC1CON = 0x8004 | 0x0480;//ch 8 -> Measuring from CH8, is ADC5 biased with 0.1V?
    //ADC1CON = 0x800c | 0x0300;//ch 4 -> Measuring from CH4, is ADC5 biased with 0.1V? Note the gain difference

    s = ADC1DAT;
    s = ADCSTA;
    ADCMDE = 0x82;

    do
    {
    s = ADCSTA;
    if (s & 0x2000) //adc1cerr
    {
    Err |= 1; //over range
    }
    } while(!(s & 0x2));

    s = ADC1DAT;
    ADCMDE = 0x83; //idle

    //3. exit adc
    ADCMDE = 0x83; //idle
    ADCFLT = 0x80ff;
    ADC1CON = 0x78c; //internally shorted

    GP0CON0 = 0x00001011; //back to spi
    GP0PAR = 0x04;
    GP0DAT = 0x10100000;

    GP0KEY1 = 0x7;
    GP0CON1 = 0x0; // exit adc
    GP0KEY2 = 0x13;
    }


  • void DelayMs(long d)
    {
    long i, j;
    for (j=0; j<d; j++)
    {
    for (i=0; i<900; i++)
    {
    //T2CLRI = 0x55;
    }
    }
    }
    void SetDacInmv(signed short mV)
    {
    signed long v;
    signed long vdac;
    v = mV;
    vdac = (v * 4095) / 1200; //by Vdd=2.5V
    vdac <<= 16;
    if (vdac > 0xfff0000)
    {
    vdac = 0xfff0000;
    }
    DACCON = 0x10;
    DACDAT = vdac;
    }

    int main()
    {
    SetDacInmv(0);
    while(1)
    {
    // T2CLRI = 0x55;
    GP0KEY1 = 0x7;
    GP0CON1 = 0x1;
    GP0KEY2 = 0x13;
    SetDacInmv(1200);
    DelayMs(5);
    SetDacInmv(600);
    DelayMs(5);

    SetDacInmv(0);
    DelayMs(5);
    GP0KEY1 = 0x7;
    GP0CON1 = 0x0;
    GP0KEY2 = 0x13;
    SetDacInmv(1200);
    DelayMs(5);
    SetDacInmv(600);
    DelayMs(5);

    SetDacInmv(0);
    DelayMs(10);
    }
    }