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]

  • Are _you_ able to read the code in that post?

    If you see some issues reading the code, then it might be an idea to take a closer look at the very clear instructions how to post source code to this forum...

  • The quality of code consultants post is for sure going downhill.

  • When oh when will Keil do something about un-formatted code?!?! The comments and re-posts associated with this painful issue consume so much bandwidth...

  • Not if you're in the habit of watching streamed video.

    It's all relative.

  • It's not just Keil.

    Keil's forum does seem to manage to make the worst mess of un-tagged (or mis-tagged) code - but I don't know of any forum that can "auto-detect" code and apply appropriate formats.

    There are even some forums that don't have any facility at all to properly format code!

  • How should I post code in here,
    in most forums we use [code] [/code] to place code!

  • Exactly as it tells you in the instructions!

    Look at the picture: www.danlhenry.com/.../keil_code.png

    Read the Tips for Posting Messages: http://www.keil.com/forum/tips.asp

  • There's one person around here who seems to spend an awful lot of time monitoring Keil and other forums.

  • 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);
    //single shot mode
    ADC0->SC3 &= ~ADC_SC3_ADCO_MASK;
    }
    
    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];
    }
    

    Main loop codes

    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++); } }

  • Dear Ali,

    This is an old thread. Am curious though, how did you resolve the fluctuating ADC result?