cancel
Showing results for 
Search instead for 
Did you mean: 

how to use ADC in discontinuous mode without HAL?

deep_rune
Associate III

I am trying to use the ADC without using HAL (except for in the setup) on a STM32F031K6, using cubeIDE. Im using the ADC in discontinuous mode - as far as I can tell, the sequence of events should be 

 - ADC is setup, then enabled with ADEN

 - ADC start conversion by setting the ADSTART

 - check the EOC flag to see when the conversion is finished

 - when the data is read from the DR register, the EOC flag is cleared

here's where I'm confused - do I then have to set the ADSTART again? in continuous modes the reference manual seems to indicate the next conversion would automatically take place, but in discontinuos mode states the next conversion needs to be manually started - Im assuming this is done by the ADSTART? In simulation this doesn't seem to work. The datasheet says ADSTART is set by software, does this mean you can't write it directly?

My code is as follows, if I click through step by step it doesn't seem to work properly, if i set it running I can see the ADC1_data variable change as I change the pot on the board, but it works intermittently, changing between 0 and the correct value 

the HAL setup is 

  static void MX_ADC_Init(void)
  {
  ADC_ChannelConfTypeDef sConfig = {0};
  hadc.Instance = ADC1;
  hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1;
  hadc.Init.Resolution = ADC_RESOLUTION_12B;
  hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD;
  hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc.Init.LowPowerAutoWait = DISABLE;
  hadc.Init.LowPowerAutoPowerOff = DISABLE;
  hadc.Init.ContinuousConvMode = DISABLE;
  hadc.Init.DiscontinuousConvMode = DISABLE;
  hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc.Init.DMAContinuousRequests = DISABLE;
  hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
 
  if (HAL_ADC_Init(&hadc) != HAL_OK)
  {
  Error_Handler();
  }
 
  /** Configure for the selected ADC regular channel to be converted.  */
 
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
  Error_Handler();
  }
 
  /** Configure for the selected ADC regular channel to be converted.  */
 
  sConfig.Channel = ADC_CHANNEL_1;
  if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK)
  {
  Error_Handler();
  }
  }

The code within the program reads 

   ADC1->CR |= ADC_CR_ADEN; // enable ADC
   ADC1 ->SMPR = 0b11;// speed divider select
   ADC1 ->CHSELR |= 1<<0 | 1<<1; // set sequence to adc0, adc1
   ADC1 ->CFGR1 |= ADC_CFGR1_DISCEN; //discontinuous mode
   ADC1 ->CR |= 1<<2; // start conversion
 
   while (1)
   {
	 if((ADC1->ISR) & 0b00000100) //if EOC flag is on
	 {
	         ADC1_data = ADC1->DR; //store data
		 ADC1 ->CR |= 1<<2; // start new conversion
	 }
  }

can anyone confirm if I am making a mistake or not?

any help much appreciated

0 REPLIES 0