2013-06-12 11:12 AM
Hello --
I'm trying to use the ADC functionality and am having some issues. I can get different values out of the ADC in response to changing inputs, but I can not get the EOC (end of conversion) flag to work, nor does the calibration work. This is my initialization code: ADC_InitTypeDef ADC_InitStructure; /******************************* ADC1, Input 0 ********************************/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfChannel = 1; /* * As per initialization in Board_Init(), I'm running the ADCs at 9 MHz. * Total conversion time is 12.5 + 239.5 = 252 cycles. * 252 cycles at 9 MHz is 28 uS. */ ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5); ADC_Init ( ADC1, &ADC_InitStructure); //Enable ADC 1 ADC_Cmd (ADC1,ENABLE); /******************************* ADC2, Input 1 ********************************/ ADC_RegularChannelConfig(ADC2, ADC_Channel_1, 1, ADC_SampleTime_55Cycles5); ADC_Init ( ADC2, &ADC_InitStructure); //Enable ADC 2 ADC_Cmd (ADC2,ENABLE); /******************************* Calibrate both ADCs ********************************/ //Reset the ADC calibration registers ADC_ResetCalibration(ADC1); #if 0 comment out as this is not yet working..... //Wait for reset while(ADC_GetResetCalibrationStatus(ADC1)); ADC_StartCalibration(ADC1); //RESET indicates the end of calibration while(ADC_GetCalibrationStatus(ADC1)); //Reset the ADC calibration registers ADC_ResetCalibration(ADC2); //Wait for reset while(ADC_GetResetCalibrationStatus(ADC2)); ADC_StartCalibration(ADC2); //RESET indicates the end of calibration while(ADC_GetCalibrationStatus(ADC2)); #endif This is how I'm calling it the ADC: //Start the conversion //ADC_SoftwareStartConvCmd(ADC1, ENABLE); ADC_Cmd (ADC1,ENABLE); //this doesn't work yet.... //while(RESET == ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)) val = ADC_GetConversionValue(ADC1); sprintf(Debug_String, '' ADC 1= %d'',val); I've re-read the manual, checked the registers etc and can't see anything wrong. Any ideas? Thank you Mark2013-06-12 01:06 PM
I've re-read the manual, checked the registers etc and can't see anything wrong. Any ideas?
I'd rather look at a stand alone example rather than a selective cut-n-paste. I'm apt to think the problem is elsewhere. The fact the calibration doesn't work suggests one or more of the bus clocks is not enabled. You'd definitely want to do the ADC_Init() prior to setting up the channels.
2013-06-12 02:14 PM
2013-06-13 01:37 PM
I changed the ADC_Init() as suggested.
I am now reading correct voltage leves from both ADCs, but I have to read EACH ADC twice before it will respond with the correct voltage. I don't know why this is happening. For example, if the correct ADC value is 0x10 and I change the input, the next ADC read will still return 0x10. The subsequent one will report the changed value. The EOC flag seems to be set immediately after I enable the ADC. Is the first read bogus? I've tried two ways with the same results: ADC_SoftwareStartConvCmd(ADC1, ENABLE); while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); val1 = ADC_GetConversionValue(ADC1); ADC_SoftwareStartConvCmd(ADC1, DISABLE); and ADC_Cmd (ADC1,ENABLE); while(RESET == ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)); val1 = ADC_GetConversionValue(ADC1); I reading the ADC at 5 second intervals so there is ample time for conversion to occur. Thanks Mark2013-06-13 02:18 PM
This seems to solve the ''double read'' problem:
ADC_Cmd (ADC1,ENABLE); while(RESET == ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)); if (SET == ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)) { Delay a while...... } val1 = ADC_GetConversionValue(ADC1); This tells me the EOC flag is not really set..... ??