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:
CR2_DDS
bit, as in the accepted answer. However this might cause overrun error, as data is continuously converted.CR2_DMA
bit before setting it again (or callADC_HAL_Start_DMA
) to start the sampling again. This method should give you better control of when the sampling should be done.