STM32F103C8 ADC Problem
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-06-12 11:12 AM
Posted on June 12, 2013 at 20:12
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 Mark
This discussion is locked. Please start a new topic to ask your question.
4 REPLIES 4
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-06-12 1:06 PM
Posted on June 12, 2013 at 22:06
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.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Up vote any posts that you find helpful, it shows what's working..
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-06-12 2:14 PM
Posted on June 12, 2013 at 23:14If you haveADC_InitTypeDef ADC_InitStructure;inside a function, you will need to initialise that structure completely or the fields that you do not initialise will hold random garbage.
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-06-13 1:37 PM
Posted on June 13, 2013 at 22:37
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 MarkOptions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2013-06-13 2:18 PM
Posted on June 13, 2013 at 23:18
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..... ??