cancel
Showing results for 
Search instead for 
Did you mean: 

Multichannel ADC reading

er3481
Associate III
Posted on August 16, 2016 at 18:31

Hi,

I am trying to read two adc channels number 10 and 11 with cubemx output. I can read the 10th channel with this code:

HAL_ADC_Start(&hadc1);

HAL_ADC_PollForConversion(&hadc1,10);

value_adc=HAL_ADC_GetValue(&hadc1);

How can i read 11th channel? 

#adc #hal #no-hablo-hal
9 REPLIES 9
Sam Ellicott
Associate II
Posted on August 16, 2016 at 22:25

Hi

>How can i read 11th channel?

From my understanding of the reference manual (see the example timing diagrams and example code) I think this code aught to work.

uint16_t
adc_10;
uint16_t
adc_11;
HAL_ADC_Start(&hadc1);
//get channel 10
HAL_ADC_PollForConversion(&hadc1,10);
adc_10=HAL_ADC_GetValue(&hadc1);
//get channel 11
HAL_ADC_PollForConversion(&hadc1,10);
adc_11=HAL_ADC_GetValue(&hadc1);

To get more data just repeat the process. Disclaimer: I usually just mess with the registers directly for ADC conversions. -Sam Ellicott
er3481
Associate III
Posted on August 17, 2016 at 08:20

Hi Nebk

It does not work because you assign the same adc value to different variables, so it always shows the same values. I just want to read different adc channels and Show them with different variables.

Posted on August 17, 2016 at 14:51

The method preferred by the STM32 design is to configure the ADC to read two channels, using an enumerated list, to scan them in a non-continuous fashion, and be software triggered. Then you have an array holding two 16-bit half-words, describe the array, and length to the DMA unit, in circular mode.

Then, after you trigger the ADC, the DMA fills the two variables (in an array), and signals TC (Transfer Complete) to let you know it is complete.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Walid FTITI_O
Senior II
Posted on August 17, 2016 at 15:03

Hi  rapid84,

For multichannel ADC case, you ought to use DMA. I recommend that you look to the ''ADC_RegularConversion_DMA'' example in  the STM32CubeF4 and add the other ADC channel to the code. 

If you want to make change in your CubeMx project and read channels in continuous mode, follow these recommendations:

- Enable scan conversion mode

- Enable continuous conversion mode

- Add n regular channel configuration to be converted ( n=2 in your case)

- Select circular mode with data_width = word.

-Hannibal-

er3481
Associate III
Posted on August 17, 2016 at 15:29

Hi,

I am using the code and definitions for multichannel adc read:

ADC_HandleTypeDef hadc1;

DMA_HandleTypeDef hdma_adc1;

uint16_t value_adc[2];

main()

{

 MX_DMA_Init();

  MX_ADC1_Init();

 

  HAL_ADC_Start(&hadc1);

HAL_ADC_Start_DMA(&hadc1, value_adc, 2);

  HAL_ADC_PollForConversion(&hadc1,250);    

  *value_adc = HAL_ADC_GetValue(&hadc1);

}

void MX_ADC1_Init(void)

{

  ADC_ChannelConfTypeDef sConfig;

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)

    */

  hadc1.Instance = ADC1;

  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;

  hadc1.Init.Resolution = ADC_RESOLUTION_12B;

  hadc1.Init.ScanConvMode = ENABLE;

  hadc1.Init.ContinuousConvMode = ENABLE;

  hadc1.Init.DiscontinuousConvMode = DISABLE;

  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;

  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;

  hadc1.Init.NbrOfConversion = 2;

  hadc1.Init.DMAContinuousRequests = ENABLE;

  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;

  HAL_ADC_Init(&hadc1);

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.

    */

  sConfig.Channel = ADC_CHANNEL_10;

  sConfig.Rank = 1;

  sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES;

  HAL_ADC_ConfigChannel(&hadc1, &sConfig);

 

  sConfig.Channel = ADC_CHANNEL_11;

  sConfig.Rank = 2;

  //sConfig.SamplingTime = ADC_SAMPLETIME_28CYCLES;

  HAL_ADC_ConfigChannel(&hadc1, &sConfig); 

 

}

But it does not work clearly, what is my wrongness ?

Sam Ellicott
Associate II
Posted on August 17, 2016 at 18:49

If you do not mind using polling (against the superior wisdom of Hanibal and clive1) this code aught to work (it works on my stm32f0 board).

The important thing is to configure the ADC in discontinuous mode.

int
main(
void
)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_ADC_Init();
uint16_t adc_6, adc_7, adc_9;
while
(1) {
 //first ADC in the sequence 
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, 5);
adc_6 = HAL_ADC_GetValue(&hadc);
HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, 5);
adc_7 = HAL_ADC_GetValue(&hadc);

//last ADC in the sequence

HAL_ADC_Start(&hadc);
HAL_ADC_PollForConversion(&hadc, 5);
adc_9 = HAL_ADC_GetValue(&hadc);
}
}
void
MX_ADC_Init(
void
)
{
ADC_ChannelConfTypeDef sConfig;
/**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) 
*/
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 = ENABLE; 
// this is the important bit
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc.Init.DMAContinuousRequests = DISABLE;
hadc.Init.Overrun = ADC_OVR_DATA_PRESERVED;
HAL_ADC_Init(&hadc);
/**Configure for the selected ADC regular channel to be converted. 
*/
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = ADC_RANK_CHANNEL_NUMBER;
sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
/**Configure for the selected ADC regular channel to be converted. 
*/
sConfig.Channel = ADC_CHANNEL_7;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
/**Configure for the selected ADC regular channel to be converted. 
*/
sConfig.Channel = ADC_CHANNEL_9;
HAL_ADC_ConfigChannel(&hadc, &sConfig);
}

Sorry that my original code did not work. -Nebk
Sam Ellicott
Associate II
Posted on August 17, 2016 at 19:14

For using the DMA, you might want to look at

https://tunizem.blogspot.com/2014/09/using-adc-with-dma-on-stm32.html

er3481
Associate III
Posted on August 17, 2016 at 20:11

Hi Nebk,

What is the difference between your code and dma technique? Advantages or disadvantages...

Sam Ellicott
Associate II
Posted on August 17, 2016 at 21:18

I have just never bothered to use the DMA for ADCs. I don't think there are really any downsides of using the DMA once you get it working. I just have never had a project where setting up the DMA was worth the extra hassle. (I always have problems when I try to use the DMA.)

My code is more or less ''quick and dirty''. It should work but is definitely less efficient. I would not use it if your application depends heavily on having fast access to new ADC values.

-Nebk