Electronic – STM32 ADC+DMA occurring only once

adcdmastm32

I'm trying to poll the value of the ADC and store it in a variable using DMA but the variable store the value of the ADC1->DR only once(when the program start).
In the debug the value of ADC1->DR change but the variable stay the same.
This is my code:

#include "stm32f4xx.h"                  // Device header
volatile uint16_t DMAVALUE =0;
int main()
{
RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN | RCC_AHB1ENR_GPIOAEN;
RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;

GPIOA->MODER |= GPIO_MODER_MODE0;
GPIOA->PUPDR |= GPIO_PUPDR_PUPD0_1;

DMA2_Stream4->PAR = (uint32_t)( &(ADC1->DR));
DMA2_Stream4->M0AR =(uint32_t)( &(DMAVALUE));
DMA2_Stream4->NDTR = 1;
DMA2_Stream4->CR &=~ DMA_SxCR_CHSEL; //STREAM4 CHANNEL 0
DMA2_Stream4->CR |= DMA_SxCR_PSIZE_0 | DMA_SxCR_MSIZE_0 | DMA_SxCR_TCIE | 
DMA_SxCR_CIRC  | DMA_SxCR_EN ;// CIRCULAR MODE IS ENABLED
NVIC_EnableIRQ(DMA2_Stream4_IRQn);
NVIC_SetPriority(DMA2_Stream4_IRQn,0);

ADC1->CR2 |= ADC_CR2_ADON | ADC_CR2_CONT | ADC_CR2_DMA;
ADC1->SMPR2 |= ADC_SMPR2_SMP0;
ADC1->SQR3 &=~ ADC_SQR3_SQ1; //CHANNEL 0 IS FIRST IN SEQUENCE
ADC1->CR2 |= ADC_CR2_SWSTART;


while(1)
{

}
}
void DMA2_Stream4_IRQHandler(void)
{
DMA2->HIFCR &=~ DMA_HIFCR_CTCIF4;
}

Best Answer

I know it's late, but I'm going to put my answer here for other people's reference. I was using the STM HAL library and ran into this problem. The HAL library had the same bug as the code above.

To solve it, either:

  1. Set the CR2_DDS bit, as in the accepted answer. However this might cause overrun error, as data is continuously converted.
  2. Clear the CR2_DMA bit before setting it again (or call ADC_HAL_Start_DMA) to start the sampling again. This method should give you better control of when the sampling should be done.