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.
Could we see you code that sets up the ADC?
| ADC_SC3_AVGS(AVGS_32);
In this configuration, you are actually taking 32 conversions and averaging per sample!
I have averaging disabled, note below in red
Master_Adc_Config.STATUS3 = CAL_OFF | ADCO_SINGLE | AVGE_DISABLED | ADC_SC3_AVGS(AVGS_32);
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?
Yes, I'm using MQX. It is essentially verbatim from the Tower demo code.
You may want to just try doing it bare metal. A context switch may be happening in your polling loop.
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.
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
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
}