cancel
Showing results for 
Search instead for 
Did you mean: 

How to read 3 channel ADC with DMA

ferhatyol-23
Senior
Posted on January 13, 2016 at 16:16

Hi

I'm using STM32f7 Discovery board.I want to read 3 channel adc with DMA.I currently run a single channel.But I could not run three channels. I want to use ADC3 Channel 6, Channel 7 and Channel 8 This is ADC config code

/**
* @brief ADC configuration
* @param htim : ADC handle
* @retval None
*/
static void ADC_Config(void)
{
ADC_ChannelConfTypeDef sConfig;
/*##-1- Configure the ADC peripheral #######################################*/
AdcHandle.Instance = ADC3;
AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.NbrOfConversion = 3;
AdcHandle.Init.ScanConvMode = ENABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
AdcHandle.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each conversion trig */
AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
AdcHandle.Init.NbrOfDiscConversion = 0;
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; /* Conversion start trigged at each external event */
AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIG2_T2_TRGO;
AdcHandle.Init.DMAContinuousRequests = ENABLE;
AdcHandle.Init.EOCSelection = DISABLE;
if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
/* ADC initialization Error */
}
/*##-2- Configure ADC regular channel ######################################*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
/* Channel Configuration Error */
}
/*##-3- Start the conversion process #######################################*/
if(HAL_ADC_Start_DMA(&AdcHandle, (uint32_t*)&uhADCxConvertedValue[0], 3) != HAL_OK)
{
/* Start Conversation Error */
}
}

How do I make ADC channel settings in HAL libraries? Thank you
12 REPLIES 12
Posted on January 13, 2016 at 17:14

Configure the pins, and add channels as Rank 1 thru 3

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ferhatyol-23
Senior
Posted on January 13, 2016 at 18:42

hi clive

I did not understand what I should do. I have configured the GPIO pins. GPIO_Pin_8, GPIO_Pin_7 and GPIO_Pin_6 is analog input. Settings are as follows.

static void ADC_Config(void)
{
ADC_ChannelConfTypeDef sConfig;
/*##-1- Configure the ADC peripheral #######################################*/
AdcHandle.Instance = ADC3;
AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.NbrOfConversion = 3;
AdcHandle.Init.ScanConvMode = ENABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
AdcHandle.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each conversion trig */
AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
AdcHandle.Init.NbrOfDiscConversion = 0;
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; /* Conversion start trigged at each external event */
AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIG2_T2_TRGO;
AdcHandle.Init.DMAContinuousRequests = ENABLE;
AdcHandle.Init.EOCSelection = DISABLE;
if (HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
/* ADC initialization Error */
}
/*##-2- Configure ADC regular channel ######################################*/
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
/* Channel Configuration Error */
}
/*##-2- Configure ADC regular channel ######################################*/
sConfig.Channel = ADC_CHANNEL_7;
sConfig.Rank = 2;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
/* Channel Configuration Error */
}
/*##-2- Configure ADC regular channel ######################################*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = 3;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.Offset = 0;
if (HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
/* Channel Configuration Error */
}
/*##-3- Start the conversion process #######################################*/
if(HAL_ADC_Start_DMA(&AdcHandle, (uint32_t*)&uhADCxConvertedValue[0], 3) != HAL_OK)
{
/* Start Conversation Error */
}
}

How do I do the Rank settings?
Posted on January 13, 2016 at 18:47

Ok, that looks like a good start, and the TIM2 is set to trigger these. At each trigger event the three conversions should occur one after the other.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ferhatyol-23
Senior
Posted on January 13, 2016 at 22:24

hi clive

Thank you for the reply, 

Yes, I used to timer TRGO output. ADC is working on a single channel. But, 3-channel ADCs is not working. I could not run. 

Exactly what should I do? 

Thank you

Posted on January 14, 2016 at 19:25

Exactly what should I do? 

Not sure, the HAL+F7 is not something I'm working on. You might want to dig into some of the board level examples provided with HAL/Cube.

Maybe someone from ST can pick this up?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ferhatyol-23
Senior
Posted on January 15, 2016 at 09:23

Hi Clive

I solved the problem,DMA size should be sixfor three channels,But now I have another problem.ADC channels are affecting by each other.

https://www.youtube.com/watch?v=NkiLlNQ1SH4

The final version of the ADC configuration code:

/**
* @brief ADC configuration
* @param htim : ADC handle
* @retval None
*/
static void ADC_Config(void)
{
ADC_ChannelConfTypeDef sConfig;
ADC_MultiModeTypeDef MultiMode;
/*##-1- Configure the ADC peripheral #######################################*/
AdcHandle.Instance = ADC3;
AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.NbrOfConversion = 3;
AdcHandle.Init.ScanConvMode = ENABLE; /* Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) */
AdcHandle.Init.ContinuousConvMode = DISABLE; /* Continuous mode disabled to have only 1 conversion at each conversion trig */
AdcHandle.Init.DiscontinuousConvMode = DISABLE; /* Parameter discarded because sequencer is disabled */
AdcHandle.Init.NbrOfDiscConversion = 0;
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING; /* Conversion start trigged at each external event */
AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIG2_T2_TRGO;
AdcHandle.Init.DMAContinuousRequests = ENABLE;
AdcHandle.Init.EOCSelection = DISABLE;
HAL_ADC_Init(&AdcHandle);
/*##-2- Configure ADC regular channel ######################################*/
sConfig.Channel = ADC_CHANNEL_6;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
/*##-3- Configure ADC regular channel ######################################*/
sConfig.Channel = ADC_CHANNEL_7;
sConfig.Rank = 2;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
/*##-4- Configure ADC regular channel ######################################*/
sConfig.Channel = ADC_CHANNEL_8;
sConfig.Rank = 3;
sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&AdcHandle, &sConfig);
/*##-5- Configure MultiMode Settings #######################################*/ 
MultiMode.Mode=ADC_MODE_INDEPENDENT;
MultiMode.TwoSamplingDelay=ADC_TWOSAMPLINGDELAY_20CYCLES;
HAL_ADCEx_MultiModeConfigChannel(&AdcHandle, &MultiMode);
/*##-6- Start the conversion process #######################################*/
HAL_ADC_Start_DMA(&AdcHandle, (uint32_t*)&uhADCxConvertedValue, 6);
}

Why it is affected by other each channel? Thank you
Posted on January 15, 2016 at 17:09

Link doesn't work for me.

I guess you'd need to check the nature of the sources, and how rapidly they can charge the capacitor on the front end of the ADC

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
ferhatyol-23
Senior
Posted on January 15, 2016 at 19:43

Hi Clive,

I'm sorry, The link was deformed. I've updated the link.

https://www.youtube.com/watch?v=NkiLlNQ1SH4

I don't think the problem is related to ADC Sample speed.  Because it had the same problem when working slowly(10-15Hz)

I need help. 

Thank you

Posted on January 15, 2016 at 20:34

Have you tried sampling pins tied to the power rails?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..