ADC Configuration

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

ADC Configuration

3,144 Views
frustrated
Contributor II

The Kinetis documentation claims the ADC can be configured for a conversion time of 2us but the best I've seen is 72.8us. I'm using the Tower with the demo code and flipping a GPIO to measure on a scope.

 

        PTC_BASE_PTR->PSOR |= (1 << 3);
        
        ADC1_BASE_PTR->SC1[0] = ADC_SC1_ADCH(20);
        while ( (ADC1_BASE_PTR->SC1[0] & ADC_SC1_COCO_MASK) == 0 ){}  // Wait conversion end
   
        PTC_BASE_PTR->PCOR |= (1 << 3);

 

This takes 72.8us. I've searched and searched for some kind of app note regarding the ADC configuration and I can't find any. Can anyone help me with an ADC configuration to get the claimed 2us conversion? Thanks.

0 Kudos
9 Replies

1,525 Views
emh203
Contributor II

Could we see you code that sets up the ADC?

0 Kudos

1,525 Views
emh203
Contributor II

| ADC_SC3_AVGS(AVGS_32);

 

In this configuration,  you are actually taking 32 conversions and averaging per sample!

 

 

0 Kudos

1,525 Views
frustrated
Contributor II

I have averaging disabled, note below in red

 

 Master_Adc_Config.STATUS3  = CAL_OFF | ADCO_SINGLE | AVGE_DISABLED | ADC_SC3_AVGS(AVGS_32);

0 Kudos

1,525 Views
emh203
Contributor II

Interesting..... I have some code I wrote based upon the same example.   With the 32- Avergages enabled, I get about 20uS sample time (for  an audio appplication).  

 

Are you using MQX or something similiar?

0 Kudos

1,525 Views
frustrated
Contributor II

Yes, I'm using MQX. It is essentially verbatim from the Tower demo code.

0 Kudos

1,525 Views
emh203
Contributor II

You may want to just try doing it bare metal.    A context switch may be happening in your polling loop.

0 Kudos

1,525 Views
frustrated
Contributor II

I've also tried this in an ISR which I would think is immune to context switches. Plus within the task, if there were context switches, I would think that I would see variation in the pulse on the scope. It is rock solid. Also, there is abiguity in Freescale's documentation. The Kinetis datasheet claims the max ADC clock is 12Mhz for a 16 bit conversion. Their online ADC conversion calculator claims the max clock is 22Mhz. Which is correct? I'm using 48Mhz and it works but the conversion is taking 18us. If I prescale the clock to 12Mhz, the conversion time jumps to 72us. The ADC calculator says it should take 2.771us at 12MHz. Something is very wrong.

0 Kudos

1,525 Views
mjbcswitzerland
Specialist V

Hi

 

I have done some tests in 16 bit mode, with the following reference results. They look to be fairly similar to the ones suggested in the manuals.

 

 

"Conversion time was tested with several setups as reference (K60 running at 100MHz with bus clock at 50MHz):

ADC clock Bus-clock/2 - Pre-scaler /8 - 16 bit mode single-ended - long-sample (24 clocks) – 32x hardware averaging = 460us

Pre-scaler reducted to /1 = 56us

+ Short-Sample mode = 32.4us

+ Bus not divided by 2 = 16us

+ No hardware averaging = 700ns

 

In 16 bit mode the ADC clock should however be restricted to the range of 2MHz to 12MHz, meaning that not all conversion times can be achieved to specification. Practically, the bus clock needs to be divided by 8 to clock with 6.25MHz, which gives a minimum conversion time of 5.6us – or theoretical maximum sample rate of 178kHz. If the ADC clock can be controlled to be exactly 12MHz the minimum conversion time of 2.6us and maximum sample rate of 383kHz is obtained in 16 bit mode (remembering that this will achieve about 13 bits of accuracy)."

 

Regards

 

Mark

 

 

0 Kudos

1,525 Views
frustrated
Contributor II

I'm basically using the setup from ADC_Task.c in the Tower demo code but I've been tweeking it to try to get better conversion times. All the register macros are as defined in MK60N512VMD100.h. The Tower board I'm using seems to have about a 48MHz system clock. Any help is apprechiated.

 

void InitializeADC()
{
   /* Turn on the ADCo and ADC1 clocks */
  SIM_SCGC6 |= (SIM_SCGC6_ADC0_MASK );
  SIM_SCGC3 |= (SIM_SCGC3_ADC1_MASK );

  /* setup the initial configuration */
//  Master_Adc_Config.CONFIG1  = ADLPC_NORMAL | ADC_CFG1_ADIV(ADIV_4) | ADLSMP_LONG | ADC_CFG1_MODE(MODE_16)| ADC_CFG1_ADICLK(ADICLK_BUS);
  Master_Adc_Config.CONFIG1  = ADLPC_NORMAL | ADC_CFG1_ADIV(ADIV_2) | ADC_CFG1_MODE(MODE_16)| ADC_CFG1_ADICLK(ADICLK_BUS_2);
//  Master_Adc_Config.CONFIG2  = MUXSEL_ADCA | ADACKEN_DISABLED | ADHSC_HISPEED | ADC_CFG2_ADLSTS(ADLSTS_20) ;
  Master_Adc_Config.CONFIG2  = MUXSEL_ADCA | ADACKEN_DISABLED | ADHSC_HISPEED | ADC_CFG2_ADLSTS(ADLSTS_2) ;
  Master_Adc_Config.COMPARE1 = 0x1234u ;
  Master_Adc_Config.COMPARE2 = 0x5678u ;
  Master_Adc_Config.STATUS2  = ADTRG_SW | ACFE_DISABLED | ACFGT_GREATER | ACREN_ENABLED | DMAEN_DISABLED | ADC_SC2_REFSEL(REFSEL_EXT);
  Master_Adc_Config.STATUS3  = CAL_OFF | ADCO_SINGLE | AVGE_DISABLED | ADC_SC3_AVGS(AVGS_32);
  Master_Adc_Config.PGA      = PGAEN_DISABLED | PGACHP_NOCHOP | PGALP_NORMAL | ADC_PGA_PGAG(PGAG_64);
  Master_Adc_Config.STATUS1A = AIEN_OFF | DIFF_SINGLE | ADC_SC1_ADCH(31);
  Master_Adc_Config.STATUS1B = AIEN_OFF | DIFF_SINGLE | ADC_SC1_ADCH(31);

  ADC_Config_Alt(ADC1_BASE_PTR, &Master_Adc_Config);  // config ADC
  ADC_Cal(ADC1_BASE_PTR);                    // do the calibration
  ADC_Read_Cal(ADC1_BASE_PTR,&CalibrationStore[1]);   // store the cal
}

0 Kudos