2
\$\begingroup\$

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;
}
| improve this question | | | | |
\$\endgroup\$
2
\$\begingroup\$

When i added ADC1->CR2 |= ADC_CR2_DDS;it worked

DDS: DMA disable selection (for single ADC mode) This bit is set and cleared by software.

0: No new DMA request is issued after the last transfer (as configured in the DMA controller)

1: DMA requests are issued as long as data are converted and DMA=1

| improve this answer | | | | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Congratulations on solving your problem. The essence of the answer is here, but it would be a better posting if you used the edit button to explicitly say that the solution was to set the configuration bit which makes requests be re-issued continuously. And don't forget to come back and accept your answer after the self-answer timer expires. \$\endgroup\$ – Chris Stratton Nov 26 '18 at 19:40
2
\$\begingroup\$

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.
| improve this answer | | | | |
\$\endgroup\$
1
\$\begingroup\$

You should enable scan mode too

ADC1->CR1 |= ADC_CR1_SCAN;

as the Reference Manual says,

The Scan mode is selected by setting the SCAN bit in the ADC_CR1 register. Once this bit has been set, the ADC scans all the channels selected in the ADC_SQRx registers (for regular channels) or in the ADC_JSQR register (for injected channels). A single conversion is performed for each channel of the group. After each end of conversion, the next channel in the group is converted automatically. If the CONT bit is set, regular channel conversion does not stop at the last selected channel in the group but continues again from the first selected channel. If the DMA bit is set, the direct memory access (DMA) controller is used to transfer the data converted from the regular group of channels (stored in the ADC_DR register) to SRAM after each regular channel conversion.

| improve this answer | | | | |
\$\endgroup\$
  • \$\begingroup\$ thank you berendi but it still the same problem \$\endgroup\$ – Mourad Nov 26 '18 at 18:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.