cancel
Showing results for 
Search instead for 
Did you mean: 

ADC_CR_ADSTART resets after every conversion in DISCONT mode on STM32L052

Spider
Associate II

Hello!

I'm trying to measure 3 ADC channels in DISCONT mode.

I use STM32Cube initialisation code for ADC initing.

/* ADC init function */
void MX_ADC_Init(void)
{
  LL_ADC_REG_InitTypeDef ADC_REG_InitStruct = {0};
  LL_ADC_InitTypeDef ADC_InitStruct = {0};
 
  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
  /* Peripheral clock enable */
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1);
  
  LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
  /**ADC GPIO Configuration  
  PA6   ------> ADC_IN6 
  */
  GPIO_InitStruct.Pin = NTC_ADC_Pin;
  GPIO_InitStruct.Mode = LL_GPIO_MODE_ANALOG;
  GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
  LL_GPIO_Init(NTC_ADC_GPIO_Port, &GPIO_InitStruct);
 
  /* ADC interrupt Init */
  NVIC_SetPriority(ADC1_COMP_IRQn, 0);
  NVIC_EnableIRQ(ADC1_COMP_IRQn);
 
  /** Configure Regular Channel 
  */
  LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_6);
  /** Configure Regular Channel 
  */
  LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_TEMPSENSOR);
  LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_TEMPSENSOR);
  /** Configure Regular Channel 
  */
  LL_ADC_REG_SetSequencerChAdd(ADC1, LL_ADC_CHANNEL_VREFINT);
  LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_VREFINT);
  /** Common config 
  */
  ADC_REG_InitStruct.TriggerSource = LL_ADC_REG_TRIG_SOFTWARE;
  ADC_REG_InitStruct.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_1RANK;
  ADC_REG_InitStruct.ContinuousMode = LL_ADC_REG_CONV_SINGLE;
  ADC_REG_InitStruct.DMATransfer = LL_ADC_REG_DMA_TRANSFER_NONE;
  ADC_REG_InitStruct.Overrun = LL_ADC_REG_OVR_DATA_PRESERVED;
  LL_ADC_REG_Init(ADC1, &ADC_REG_InitStruct);
  LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_160CYCLES_5);
  LL_ADC_SetOverSamplingScope(ADC1, LL_ADC_OVS_DISABLE);
  LL_ADC_REG_SetSequencerScanDirection(ADC1, LL_ADC_REG_SEQ_SCAN_DIR_FORWARD);
  LL_ADC_SetCommonFrequencyMode(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_CLOCK_FREQ_MODE_LOW);
  LL_ADC_DisableIT_EOC(ADC1);
  LL_ADC_DisableIT_EOS(ADC1);
  LL_ADC_EnableInternalRegulator(ADC1);
  ADC_InitStruct.Clock = LL_ADC_CLOCK_SYNC_PCLK_DIV1;
  ADC_InitStruct.Resolution = LL_ADC_RESOLUTION_12B;
  ADC_InitStruct.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
  ADC_InitStruct.LowPowerMode = LL_ADC_LP_AUTOWAIT;
  LL_ADC_Init(ADC1, &ADC_InitStruct);
 
}

After this I try to use

LL_ADC_REG_StartConversion(ADC1);
do {
	do {} while(!LL_ADC_IsActiveFlag_EOC(ADC1));
	results = LL_ADC_REG_ReadConversionData12(ADC1);
	if (LL_ADC_IsActiveFlag_EOS(ADC1))
		break;
	LL_ADC_ClearFlag_EOC(ADC1);
} while(1);

but after first EOC flag ADSTART setted to low also and conversion stopping.

I expected that ADSTART will in high level during all sequence. (13.4.5 from reference manual)

0690X00000ARQGLQA5.png

What I do wrong?

5 REPLIES 5

But that's the very purpose of *discontinuous* mode, to break up the sequence of conversions to individual conversions. Read Discontinuous mode (DISCEN) subchapter.

JW

But how I can undestand, during all sequence ADSTART must be in HIGH level. And only EOC bit sets every channel conversion end. And only after all sequence complite ADC reset ADSTART  bit.

In my case ADSTART resets after every channel conversion.

> But how I can undestand, during all sequence ADSTART must be in HIGH level. And only EOC bit sets every channel conversion end. And only after all sequence complite ADC reset ADSTART bit.

Yes, that's how it works if you *don't* set *discontinuous*.

JW

In this picture *not* continuous mode

0690X00000ARUF7QAP.png

Not CONTinuous is not DISContinuous.

The first is switched on by setting ADC_CFGR1.CONT bit, the second by ADC_CFGR1.DISCEN

This may be confusing, but there are in fact three "autorun" modes: normal, when none of these bits is set. when all conversions of a sequence are carried on automatically, stopping after the sequence, this is what you are after. Then you have Continuous, when after a completed sequence a new sequence is started automatically, there is no stop. Then you have Discontinuous, where there is a stop after each conversion in the sequence.

JW