This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

FRDM-KL25Z

Dear All
I have done some coding on FRDM-KL25Z platform from freescal to use it’s 16bit ADC, But I will get very unstable results, I have attached PE20 of the board to an 5K external pot which is connected to the 3.3V power and ground,PE0 is ADC channel zero, the readings are very unstable, do you have any Idea?

ADC codes
[code]
void ADC_Init(void)
{ //Turn on ADC SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; //bus clock/2 & singled-ended 16bit mode & div by 4 ADC0->CFG1 = ADC_CFG1_ADICLK(1) | ADC_CFG1_MODE(3) | ADC_CFG1_ADIV(2); //select channel A & high speed mode ADC0->CFG2 = !ADC_CFG2_MUXSEL_MASK;// | ADC_CFG2_ADHSC_MASK; //hardware trigger & VREFH/VREFL ADC0->SC2 = ADC_SC2_REFSEL(0); //ADC_SC2_ADTRG_MASK | ADC_SC2_REFSEL(0); //single shot mode ADC0->SC3 &= ~ADC_SC3_ADCO_MASK; //hardware average 32 sample //ADC0->SC3 |= ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(3);
}

uint8_t Calibrate_ADC(void) {

uint16_t cal_temp;

ADC_Init();

ADC0->SC3 |= ADC_SC3_CALF_MASK; // clear any existing calibration failed flag ADC0->SC3 |= ADC_SC3_CAL_MASK; // Start Calibration

while(ADC0->SC3 & ADC_SC3_CAL_MASK); // wait for calibration to finish

if(ADC0->SC3 & ADC_SC3_CALF_MASK) // There was a fault during calibration return 1;

// Initialize (clear) a 16b variable in RAM. cal_temp = 0;

//Add the following plus-side calibration results CLP0, CLP1, CLP2, CLP3, CLP4, CLPS and CLPD to the variable. cal_temp += ADC0->CLP0; cal_temp += ADC0->CLP1; cal_temp += ADC0->CLP2; cal_temp += ADC0->CLP3; cal_temp += ADC0->CLP4; cal_temp += ADC0->CLPS;

// Divide the variable by two. cal_temp = cal_temp >> 1; // Set the MSB of the variable. cal_temp |= 0x8000;

// Store the value in the plus-side gain calibration registers ADCPG ADC0->PG = cal_temp;

// Repeat procedure for the minus-side gain calibration value. // Initialize (clear) a 16b variable in RAM. cal_temp = 0;

//Add the following minus-side calibration results CLM0, CLM1, CLM2, CLM3, CLM4, CLMS and CLMD to the variable. cal_temp += ADC0->CLM0; cal_temp += ADC0->CLM1; cal_temp += ADC0->CLM2; cal_temp += ADC0->CLM3; cal_temp += ADC0->CLM4; cal_temp += ADC0->CLMS;

// Divide the variable by two. cal_temp = cal_temp >> 1; // Set the MSB of the variable. cal_temp |= 0x8000;

// Store the value in the minus-side gain calibration registers ADCMG ADC0->MG = cal_temp;

return 0;
}

void adc_start_conversion(uint8_t channel)
{ ADC0->SC1[0] = !ADC_SC1_AIEN_MASK | ADC_SC1_DIFF_MASK | ADC_SC1_ADCH(channel);
}

uint16_t adc_read(uint8_t channel)
{

ADC0->SC1[0] = !ADC_SC1_AIEN_MASK | ADC_SC1_DIFF_MASK | ADC_SC1_ADCH(channel) ; // start conversion while((ADC0->SC1[0] & ADC_SC1_COCO_MASK)!= 0){}; return ADC0->R[0];
} [/code]

Main loop codes
[code]
int main (void) { static int calc=0; char buff[100]; SystemCoreClockUpdate(); /* Get Core Clock Frequency */ uart0_init(); ADC_Init(); Calibrate_ADC(); uart0_puts("Hello world\r\n"); while(1) {

sprintf(buff,"adc %d\r",adc_read(0)); uart0_puts(buff); for(int i=0;i<1000000;i++); }
} [/code]