cancel
Showing results for 
Search instead for 
Did you mean: 

How use ADC DMA Interrupt in CubeIDE?

NNam.18
Associate II

Hi

I read ADC 1 channel using DMA transfer to buffer array with length is 8.

int16_t aData[8];
 
HAL_ADC_Start_DMA(&hadc1, (uint32_t*) aData, 8);

I want to average data each 8 convertions. I plan to use DMA Interrupt with a counter, when counter reach 8, I calculate average value. But I can not find any example on ST site or google

Anyone help me?

Thanks

5 REPLIES 5
Amel NASRI
ST Employee

Hello @Ngô Nam​ ,

You need to precise the device you are using, then you can look to the examples provided in the relevant STM32Cube package depending on the selected STM32 product.

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Ozone
Lead

I don't use Cube/HAL.

> I plan to use DMA Interrupt with a counter,...

DMA will give you a TC interrupt (transmission complete) when a configured transfer has finished.

If you configure 8 items, you will get the TC interrupt as you want it. Just calculate the average over that buffer.

Not sure how this is modeled in Cuba/HAL. I usually implemented exactly this mechanism, but based on the "old" SPL.

I tried, but didn't find out, anyway thanks

NNam.18
Associate II

DMA has a Global Interrupt, but I can not find out how to call correctly

Some example code for the F407, though based on SPL. I do not do Cube/HAL.

Not complete, but hopefully enough to get the point.

Configures two channels of ADC3 for a TIM triggered conversion, and a DMA transfer through DMA2 Stream0 channel2, for 256 values each.

At the end, the DMA_IT_TC is enabled (interrupt on Transfer Complete).

#define ELFR_CFFT_LENGTH            256

#define ELFR_CFFT_LENGTH             256
#define AIN_CHANNELS                    2 
 ...
 
    /* NVIC DMA interrupt setup - priority is 1, below sampling clock int. priority */
    NVIC_InitStructure.NVIC_IRQChannel                   = DMA2_Stream1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Init (&NVIC_InitStructure);
...
    /* DMA2 Stream0 channel2 configuration **************************************/
    DMA_InitStructure.DMA_Channel            = DMA_Channel_2;
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) ADC3_DR_ADDRESS;
    DMA_InitStructure.DMA_Memory0BaseAddr    = (uint32_t) &AdcBuffer;
    DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralToMemory;
    DMA_InitStructure.DMA_BufferSize         = ELFR_CFFT_LENGTH * AIN_CHANNELS;
    DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode               = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority           = DMA_Priority_High;
    DMA_InitStructure.DMA_FIFOMode           = DMA_FIFOMode_Disable;
    DMA_InitStructure.DMA_FIFOThreshold      = DMA_FIFOThreshold_HalfFull;
    DMA_InitStructure.DMA_MemoryBurst        = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst    = DMA_PeripheralBurst_Single;
    DMA_Init (DMA2_Stream1, &DMA_InitStructure);
    DMA_Cmd (DMA2_Stream1, ENABLE);
 
    /* Configure ADC3 Channels 10 + 12 pin as analog input **********************/
    GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0 | GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init (GPIOC, &GPIO_InitStructure);
 
    /* ADC Common Init **********************************************************/
    ADC_CommonInitStructure.ADC_Mode             = ADC_Mode_Independent;
    ADC_CommonInitStructure.ADC_Prescaler        = ADC_Prescaler_Div2;           // CLK = (APB2_CLK / 2)
    ADC_CommonInitStructure.ADC_DMAAccessMode    = ADC_DMAAccessMode_Disabled;
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_10Cycles;
    ADC_CommonInit (&ADC_CommonInitStructure);
 
    /* ADC3 Init ****************************************************************/
    ADC_InitStructure.ADC_Resolution           = ADC_Resolution_12b;
    ADC_InitStructure.ADC_DataAlign            = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_ScanConvMode         = ENABLE; // DISABLE;
    ADC_InitStructure.ADC_ContinuousConvMode   = DISABLE;
    ADC_InitStructure.ADC_NbrOfConversion      = AIN_CHANNELS;
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
    ADC_InitStructure.ADC_ExternalTrigConv     = ADC_ExternalTrigConv_T3_TRGO;
    ADC_Init (ADC3, &ADC_InitStructure);
 
    /* ADC3 regular channel7 configuration *************************************/
    ADC_RegularChannelConfig (ADC3, ADC_Channel_10, 1, ADC_SampleTime_112Cycles);
    ADC_RegularChannelConfig (ADC3, ADC_Channel_12, 2, ADC_SampleTime_112Cycles);
 
    ADC_DMARequestAfterLastTransferCmd (ADC3, ENABLE);
    ADC_DMACmd (ADC3, ENABLE);                         /* Enable ADC3 DMA  */
    ADC_Cmd    (ADC3, ENABLE);                         /* Enable ADC3      */
    TIM_Cmd    (TIM3, ENABLE);                         /* TIM3 enable counter, to trigger ADC */
    DMA_ITConfig (DMA2_Stream1, DMA_IT_TC, ENABLE);    /* interrupt notification when the buffer full */

Associated handler was called DMA2_Stream0_IRQHandler () within the SPL for this MCU.