cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F767 and read 4 ADC channels

Flour Beur
Associate II
Posted on March 14, 2018 at 08:25

Hello friends.

I need read 4 channel from ADC (PA0, PA1, PA2, PA3).

I read reference manual:

http://www.st.com/content/ccc/resource/technical/document/reference_manual/group0/96/8b/0d/ec/16/22/43/71/DM00224583/files/DM00224583.pdf/jcr:content/translations/en.DM00224583.pdf&sharppage=436

But i don't know, how to switch and measure next channel. Now, I'm reading only PA0.

My init function:

 

void ADC_init()

{

   /* Peripheral clock enable */

   LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1);

   LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_CLOCK_SYNC_PCLK_DIV4);

   LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_NONE);

   LL_ADC_SetResolution(ADC1, LL_ADC_RESOLUTION_12B);

   LL_ADC_SetDataAlignment(ADC1, LL_ADC_DATA_ALIGN_RIGHT);

   LL_ADC_SetSequencersScanMode(ADC1, LL_ADC_REG_SEQ_SCAN_DISABLE);

   LL_ADC_REG_SetSequencerLength(ADC1, LL_ADC_REG_SEQ_SCAN_ENABLE_4RANKS);

   LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_SOFTWARE);

   LL_ADC_REG_SetSequencerDiscont(ADC1, LL_ADC_REG_SEQ_DISCONT_DISABLE);

   LL_ADC_REG_SetContinuousMode(ADC1, LL_ADC_REG_CONV_SINGLE);

   LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_NONE);

   LL_ADC_REG_SetFlagEndOfConversion(ADC1, LL_ADC_REG_FLAG_EOC_UNITARY_CONV);

   /**Configure Regular Channel */

   LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_1, LL_ADC_CHANNEL_0);

   LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_0, LL_ADC_SAMPLINGTIME_480CYCLES);

   /**Configure Regular Channel */

   LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_2, LL_ADC_CHANNEL_1);

   LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_1, LL_ADC_SAMPLINGTIME_480CYCLES);

   /**Configure Regular Channel */

   LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_3, LL_ADC_CHANNEL_2);

   LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_2, LL_ADC_SAMPLINGTIME_480CYCLES);

   /**Configure Regular Channel */

   LL_ADC_REG_SetSequencerRanks(ADC1, LL_ADC_REG_RANK_4, LL_ADC_CHANNEL_3);

   LL_ADC_SetChannelSamplingTime(ADC1, LL_ADC_CHANNEL_3, LL_ADC_SAMPLINGTIME_480CYCLES);

   LL_ADC_Enable(ADC1);

}

And my reading:

void readADC(uint32_t *value1)

{

   LL_ADC_REG_StartConversionSWStart(ADC1);

   while (!LL_ADC_IsActiveFlag_EOCS(ADC1)){}

   LL_ADC_ClearFlag_EOCS(ADC1);

   value1[0] = LL_ADC_REG_ReadConversionData12(ADC1);

}

Any idea how to get to the next channel? Or how to scan 4 channels and return the value of all 4 ADC channels?

#adc-reads #nucleo-f767zi
1 REPLY 1
Flour Beur
Associate II
Posted on March 14, 2018 at 09:49

Here is my function modofication:

void ADC1_init()

{

   /* Peripheral clock enable */

   LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC1);

   LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_CLOCK_SYNC_PCLK_DIV4);

   LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1), LL_ADC_PATH_INTERNAL_NONE);

   LL_ADC_SetResolution(ADC1, LL_ADC_RESOLUTION_12B);

   LL_ADC_SetDataAlignment(ADC1, LL_ADC_DATA_ALIGN_RIGHT);

   LL_ADC_SetSequencersScanMode(ADC1, LL_ADC_REG_SEQ_SCAN_DISABLE);

   LL_ADC_REG_SetSequencerLength(ADC1, LL_ADC_REG_SEQ_SCAN_DISABLE);

   LL_ADC_REG_SetTriggerSource(ADC1, LL_ADC_REG_TRIG_SOFTWARE);

   LL_ADC_REG_SetSequencerDiscont(ADC1, LL_ADC_REG_SEQ_DISCONT_DISABLE);

   LL_ADC_REG_SetContinuousMode(ADC1, LL_ADC_REG_CONV_SINGLE);

   LL_ADC_REG_SetDMATransfer(ADC1, LL_ADC_REG_DMA_TRANSFER_NONE);

   LL_ADC_REG_SetFlagEndOfConversion(ADC1, LL_ADC_REG_FLAG_EOC_UNITARY_CONV);

   LL_ADC_Enable(ADC1);

}

And read from ADCx and channels 0-7 with easy peasy filter.

uint16_t adc_read(ADC_TypeDef *ADCx, uint8_t channel)

{

   uint32_t ADC_value = 0;

   uint32_t voltage = 0;

   for (int i = 0; i < 16; i++)

   {

      /* Select analog input */

      ADCx->SQR3 = channel;

      /* Clear status register */

      LL_ADC_ClearFlag_AWD1(ADCx);

      LL_ADC_ClearFlag_EOCS(ADCx);

      LL_ADC_ClearFlag_JEOS(ADCx);

      LL_ADC_ClearFlag_OVR(ADCx);

      /* Start Conversion */

      LL_ADC_REG_StartConversionSWStart(ADCx);

      /* Wait for conversion to complete */

      while (!LL_ADC_IsActiveFlag_EOCS(ADCx)){}

      ADC_value += LL_ADC_REG_ReadConversionData12(ADCx);

   }

   voltage = ((ADC_value >> 4)*3300)/4096;   /*   calculate voltage   */

   

   /* Retrieve result */

   return (uint16_t)voltage;

}