AnsweredAssumed Answered

STM32F4 ADC polled

Question asked by John F. on Dec 12, 2012
Latest reply on Apr 11, 2013 by dmitry.dmitry
I am trying to use the STM32F4 ADC1 in a simple polled loop. HCLK is 168MHz.

My code calls RCC_Configuration_Adc1, GPIO_Configuration_Adc1, ADC_DeInit and ADC1_Configuration then goes to the main loop. Stepping through the code in the debugger seems to show the ADC is configured and started but EOC is never set. If I comment out the wait on EOC then the ADC DR seems to update with results. I'm confused. Is it possible to use the ADC for single coversions with EOC polled or do I need to set up a run of regular conversions? I have browsed for examples but they're DMA which I'm already using for other things.

void RCC_Configuration_Adc1(void)
{
  //for ADC1 on PC0 using IN10
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
}
 
void GPIO_Configuration_Adc1(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
 
  GPIO_StructInit(&GPIO_InitStructure);
   
  //for ADC1 on PC0 using IN10
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
}
 
ADC_DeInit();   //de-initialises ALL the ADCs in the microcontroller
 
void ADC1_Configuration(void)
{
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  ADC_InitTypeDef       ADC_InitStructure;
 
  //common init defaults are mode = independent, prescaler = 2, DMA disabled, two sampling delay = 5
  ADC_CommonStructInit(&ADC_CommonInitStructure);
  //ADCCLK is common to all ADCs and generated from the APB2 clock divided by a prescaler /2, /4, /6 or /8.
  //APB2 is HCLK/2 = 168 / 2 = 84MHz and ADC clock must be less than 30MHz so prescale by 4
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
  ADC_CommonInit(&ADC_CommonInitStructure);
   
  //adc init defaults are 12 bit, continuous = DISABLE, ExternalTrigConvEdge_None,
  //ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1, Data aligned right, number of conversions = 1;
  ADC_StructInit(&ADC_InitStructure);
  ADC_Init(ADC1, &ADC_InitStructure);
   
  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_480Cycles);
  ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE);
 
  ADC_Cmd(ADC1, ENABLE);    //The ADC is powered on by setting the ADON bit in the ADC_CR2 register.
  //When the ADON bit is set for the first time, it wakes up the ADC from the Power-down mode.
}
 
//in main ...
while(1)
{
  uint16_t ADCResult = 0x1234;
   
  ADC_SoftwareStartConv(ADC1);
  while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
  ADCResult = ADC_GetConversionValue(ADC1);
}

Outcomes