cancel
Showing results for 
Search instead for 
Did you mean: 

Can't get multiple ADC via DMA working

mh.ferris9
Associate II
Posted on August 12, 2015 at 17:50

Hi,

I've been jumping between the regular libraries and Hal and the Cube and I've now settled on the Cube and HAL libs. I'm trying to get multiple ADC channel conversions to work via DMA to an array, but with no success as yet. I'm using a Nucleo-F411RE, and trying to use PC0 (ADC1_CH10) and PC1(ADC1_CH11). I've got a single channel working correctly (PC0), but multiple channels still alludes me and looking at hte examples I'm not sure where I'm going wrong. I thought the only real difference would be changing the

AdcHandle.Init.NbrOfConversion = 2;

and setting the

HAL_ADC_ConfigChannel

ranks.

static
GPIO_InitTypeDef GPIO_InitStruct;
/* ADC handler declaration */
ADC_HandleTypeDef AdcHandle;
/* Variable used to get converted value */
__IO uint32_t uhADCxConvertedValue[2] = {0};
void
HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct;
static
DMA_HandleTypeDef hdma_adc;
/* Enable peripherals and GPIO Clocks */
/* Enable GPIO clock */
__HAL_RCC_GPIOC_CLK_ENABLE();
/* ADC3 Periph clock enable */
__HAL_RCC_ADC1_CLK_ENABLE();
/* Enable DMA2 clock */
__HAL_RCC_DMA2_CLK_ENABLE(); 
/* Configure peripheral GPIO */
/* ADC1 GPIO pin configuration */
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* Configure the DMA streams */
/* Set the parameters to be configured */
hdma_adc.Instance = DMA2_Stream0;
hdma_adc.Init.Channel = DMA_CHANNEL_0;
hdma_adc.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_adc.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_adc.Init.MemInc = DMA_MINC_ENABLE;
hdma_adc.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_adc.Init.MemDataAlignment = DMA_PDATAALIGN_WORD;
hdma_adc.Init.Mode = DMA_CIRCULAR;
hdma_adc.Init.Priority = DMA_PRIORITY_HIGH;
hdma_adc.Init.FIFOMode = DMA_FIFOMODE_DISABLE; 
hdma_adc.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
hdma_adc.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_adc.Init.PeriphBurst = DMA_PBURST_SINGLE; 
HAL_DMA_Init(&hdma_adc);
/* Associate the initialized DMA handle to the the ADC handle */
__HAL_LINKDMA(hadc, DMA_Handle, hdma_adc);
}
int
main(
void
)
{
ADC_ChannelConfTypeDef sConfig;
/* STM32F4xx HAL library initialization:
- Configure the Flash prefetch, instruction and Data caches
- Configure the Systick to generate an interrupt each 1 msec
- Set NVIC Group Priority to 4
- Global MSP (MCU Support Package) initialization
*/
HAL_Init();
/* Configure the system clock to 100 MHz */
SystemClock_Config();
/* Configure the ADC peripheral */
AdcHandle.Instance = ADC1;
AdcHandle.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
AdcHandle.Init.Resolution = ADC_RESOLUTION_12B;
AdcHandle.Init.ScanConvMode = DISABLE;
AdcHandle.Init.ContinuousConvMode = ENABLE;
AdcHandle.Init.DiscontinuousConvMode = DISABLE;
AdcHandle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
AdcHandle.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
AdcHandle.Init.DataAlign = ADC_DATAALIGN_RIGHT;
AdcHandle.Init.NbrOfConversion = 2;
AdcHandle.Init.DMAContinuousRequests = ENABLE;
AdcHandle.Init.EOCSelection = DISABLE;
if
(HAL_ADC_Init(&AdcHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler(); 
}
/* Configure ADC regular channel */
sConfig.Channel = ADC_CHANNEL_10;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_144CYCLES;
sConfig.Offset = 0;
if
(HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
/* Channel Configuration Error */
Error_Handler(); 
}
sConfig.Channel = ADC_CHANNEL_11;
sConfig.Rank = 2;
if
(HAL_ADC_ConfigChannel(&AdcHandle, &sConfig) != HAL_OK)
{
/* Channel Configuration Error */
Error_Handler(); 
}
/* Start the conversion process and enable interrupt */
if
(HAL_ADC_Start_DMA(&AdcHandle, (uint32_t *)uhADCxConvertedValue, 1) != HAL_OK)
{
/* Start Conversation Error */
Error_Handler(); 
}
while
(1)
{
}
}

13 REPLIES 13
Posted on February 23, 2018 at 04:46

When the ADC scans you really want to use DMA, your long sample time may permit polling, but I'm not going to test that theory.

Per Data Sheet

PA0 ADC1_CH1

PA1 ADC1_CH2

PA2 ADC1_CH3

PA3 ADC1_CH4

PA4 ADC2_CH1

PA5 ADC2_CH2

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
David Pekin
Senior
Posted on February 23, 2018 at 17:37

Where is the documentation for DMA/peripheral mapping and ADC/GPIP line mapping?

Posted on February 23, 2018 at 17:39

Data Sheet (pins)

Reference Manual (DMA, ADC)

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on February 23, 2018 at 20:36

Thanks again.  Have it working w/ PA4/PA5.