Serious problem with calibration of ADC on Kinetis K60 (Urgent)

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Serious problem with calibration of ADC on Kinetis K60 (Urgent)

2,880 Views
lequanghuy
Contributor II

Hi everybody,

I'm facing a serious problem with calibration of ADC on Kinetis K60. I configure output mode differential 16 bits, Vdda=3,3 V, Voltage reference select Valt = 3V, bus clock  = 50 Mhz, internal clock ADCK = 50/4 = 12,5 MHz (Registers CFGx config is the same with exemple ADC_demo of Fresscale).

I use also calibration routine of this exemple:

int ADC_Cal(int Num_adc)

{

    unsigned short cal_var;

    ADC_MemMapPtr adcmap;

   

    if(Num_adc==ADC0)

    {

        adcmap = ADC0_BASE_PTR;

    }

    else if(Num_adc==ADC1)

    {

        adcmap = ADC1_BASE_PTR;

    }

   

    // Turn on the ADC0 and ADC1 clocks

    SIM_SCGC6 |= (SIM_SCGC6_ADC0_MASK );

    SIM_SCGC3 |= (SIM_SCGC3_ADC1_MASK );

   

    ADC_SC2_REG(adcmap) &=  ~ADC_SC2_ADTRG_MASK ;                     // Enable Software Conversion Trigger for Calibration Process  

    ADC_SC3_REG(adcmap) &= (~ADC_SC3_ADCO_MASK & ~ADC_SC3_AVGS_MASK); // set single conversion, clear avgs bitfield for next writing

    ADC_SC3_REG(adcmap) |= (ADC_SC3_AVGE_MASK|ADC_SC3_AVGS(AVGS_32)); // Turn averaging ON and set at max value ( 32 )

   

    ADC_CFG1_REG(adcmap)&= (~ADC_CFG1_ADIV(ADIV_4)& ~ADC_CFG1_ADICLK(ADICLK_BUS)); // Clear fADCK initiated

    ADC_CFG1_REG(adcmap)|= ADC_CFG1_ADIV(ADIV_8)|ADC_CFG1_ADICLK(ADICLK_BUS_2); // fADCK = 50/2/8

    ADC_SC2_REG(adcmap) &= ~ADC_SC2_REFSEL(REFSEL_ALT);    // Clear Vrefh initiated

    ADC_SC2_REG(adcmap) |= ADC_SC2_REFSEL(REFSEL_EXT); // Vrefh = VDDA

   

    ADC_SC3_REG(adcmap) |= ADC_SC3_CAL_MASK ;                          // Start CAL

    while ((ADC_SC1_REG(adcmap,A) & ADC_SC1_COCO_MASK ) == COCO_NOT); // Wait calibration end

   

    if ((ADC_SC3_REG(adcmap)& ADC_SC3_CALF_MASK) == CALF_FAIL )

    { 

    return 1;                                                            // Check for Calibration fail error and return

    }

    // Calculate plus-side calibration

    cal_var  = 0x00;

   

    cal_var  = ADC_CLP0_REG(adcmap);

    cal_var += ADC_CLP1_REG(adcmap);

    cal_var += ADC_CLP2_REG(adcmap);

    cal_var += ADC_CLP3_REG(adcmap);

    cal_var += ADC_CLP4_REG(adcmap);

    cal_var += ADC_CLPS_REG(adcmap);

   

    cal_var = cal_var/2;

    cal_var |= 0x8000;    // Set MSB

   

    ADC_PG_REG(adcmap) = ADC_PG_PG(cal_var);

   

   

    // Calculate minus-side calibration

    cal_var  = 0x00;

   

    cal_var  = ADC_CLM0_REG(adcmap);

    cal_var += ADC_CLM1_REG(adcmap);

    cal_var += ADC_CLM2_REG(adcmap);

    cal_var += ADC_CLM3_REG(adcmap);

    cal_var += ADC_CLM4_REG(adcmap);

    cal_var += ADC_CLMS_REG(adcmap);

    cal_var  = cal_var/2;

   

    cal_var |= 0x8000;     // Set MSB

   

    ADC_MG_REG(adcmap)   = ADC_MG_MG(cal_var);

   

    ADC_SC3_REG(adcmap) &= ~ADC_SC3_CAL_MASK ; /* Clear CAL bit */

   

    return 0;

}

But when i make a conversion, after eache reset, results vary greatly with a gap of 80 points(ex input DADP3 = 2,18 V, DADM3 = 0,82 V, output (before reset 15137, after reset 15050)). I tried looking values of registers ADCx_CLPD and ADCx_CLMD and write  these values in the calib function in order to these registers don't change after each reset. Therefore, output value don't vary.


How can I fix this don't write registers ADCx_CLPD and ADCx_CLMD ?

Many thanks

LE Quang Huy

Labels (1)
Tags (2)
3 Replies

1,274 Views
lequanghuy
Contributor II


1,274 Views
Monica
Senior Contributor III

Hello LE!

Were this suggestions helpful?

Keep us posted, we'd like to know :smileywink:

Best regards,

Monica

0 Kudos
Reply

1,274 Views
rastislav_pavlanin
NXP Employee
NXP Employee

Hi Le,

not sure I will help but the accurancy of ADC measurement is dependent on many features like:

- on ADC clock + sampling time + total conversion time + averaging use/or not,

- on your external component design (if the external impedance is too high it can also degradate accurancy) etc.

Some recomendations :

- the maximum recommended ADC clock for 16-bit mode is 12MHz (you use clock slightly higher which can also decrease accurancy),

- see the ENOB value in datasheet (ENOB represents effective number of bits for specified ADC configuration)

- if you use 16-bit ADC mode it does not mean the accurancy you can get, it only means that SAR ADC will make16 "aproximations" till the conversion done (16 active bits used in result register).

- also improtant value in datasheet is TUE (total unadjusted error).

I do not think you faceing a problem with calibration process, this look ok from my point of view.

hope I helped.

Rastislav