STM32F4 ADC with DMA 7 Channel regular group isn't working

0

I'm trying to setup my STM32F407-Discovery board to read multiple ADC channels from ADC1 using the DMA controller. It's possible to read one value without using DMA. When DMA is enabled only channel 1 is converted. The other array-elements are filled with 0.

Unfortunately I cannot find my mistake because I am not quite sure where to start. Maybe you can help me here.

My complete code is shown here:

#include "stm32f4xx.h"
#include "system_stm32f4xx.h"

/*****************************
MAIN function
*****************************/
void ADC_IRQHandler(void);

uint32_t n=0;                                               // defines global variable n for number of convertions
uint32_t value[2];
float show[2];
int i=0;

int main()
{
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;                    // activate clock for port A
    RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;                     // activate clock for DMA2
    RCC->APB2ENR |= RCC_APB2ENR_ADC1EN;                     // activate clock for ADC1
    
  DMA2_Stream0->PAR = (uint32_t) &ADC1->DR;                 // Regular Data Register to load ADC1 as DMA-Sourceadress
    DMA2_Stream0->M0AR = (uint32_t) &value;                 // Regular Data Register to store ADC1 DMA data     
    DMA2_Stream0->NDTR = 2;                                 // number of data to be transferred (here 1)    
    DMA2_Stream0->CR |= 0x00022901;                         // DMA Stream Konfiguration for the incoming ADC1 data (prio: Medium / MSIZE: Half-word / PSIZE: half-word / circular/ enable)
    
    GPIOA->MODER |= 0x0000FFFC;                                     // Pin 1-7 Port a as analog
    ADC1->SQR1 = 0x00100000;                                            // two conversions
    ADC1->SQR2 = 0; 
    ADC1->SQR3 = 0x00000041;                                            // conversion ADC in1 and in2
    ADC1->SMPR2 |= 0xFFFFFFFF;                                      // sampletime 
    ADC1->CR2 |= ADC_CR2_CONT;                                      // choose continiouse Mode for ADC3
    ADC1->CR2 |= ADC_CR1_SCAN;                                      // scan mode active
    ADC1->CR2 |= ADC_CR2_DDS;                                           // DMA via DDS-Bit
    ADC1->CR2 |= ADC_CR2_DMA;                                           // activate DMA module
    ADC1->CR2 |= ADC_CR2_ADON;                                      // Activate the AD converter
    ADC1->CR2 |= ADC_CR2_SWSTART;                                   // start convertion
    
    while(1)
    {
        show[0] = (float) value[0]*(float) 3.3 / (float)0xFFF;
        show[1] = (float) value[1]*(float) 3.3 / (float)0xFFF;
    }
}

So the DMA Stream is setup as:

  • 4 Bit Reserved
  • 3 Bit Channel Select: I am using channel 0 to access ADC1
  • 2 Bit Memory burst transfer configuration: single transfer
  • 2 Bit Peripheral burst transfer configuration: single transfer
  • 1 Bit Reserved
  • 1 Bit Current target 0 (DMA_SxM0AR pointer)
  • 1 Bit Double buffer mode: No buffer switching
  • 2 Bit Priority level: Medium: 01
  • 1 Bit Peripheral increment offset size disabled 0
  • 2 Bit Memory data size: half-word 01
  • 2 Bit Peripheral data size: half-word 01
  • 1 Bit Memory increment mode: disabled 0
  • 1 Bit Peripheral increment mode: disabled 0
  • 1 Bit Circular mode: enabled 1
  • 1 Bit Data transfer direction: Peripheral-to-memory 00
  • 1 Bit Peripheral flow controller 0
  • 1 Bit Transfer complete interrupt enable 0
  • 1 Bit Half transfer interrupt enable 0
  • 1 Bit Transfer error interrupt enable 0
  • 1 Bit Direct mode error interrupt enable 0
  • 1 Bit Enable 1 summarized: 10 0010 1001 0000 0001

GPIOA Pins 1 to 7 are configured for analoge mode with: 11 for seven channels

GPIOA->MODER |= 0x0000FFFC;

ADC 1 is regular sequence register 1 is configured for 2 conversions ADC1->SQR1 = 0x00100000;

regular sequence register 1 is configured for Pin A1 conversion on the 1st place and Pin A2 on the 2nd place. ADC1->SQR3 = 0x00000041;

For testing the sample time register is set to 480 cycles for channels 0 to 9 ADC1->SMPR2 |= 0xFFFFFFFF;

c
stm32
dma
adc
asked on Stack Overflow May 25, 2020 by Falk • edited Mar 31, 2021 by marc_s

1 Answer

0

Found my mistake, needed to enable the memory increment mode. The other mistake was the wrong memory data size. Changed my datatype from values to 16 bit. Works fine now.

Thank you all.

answered on Stack Overflow May 25, 2020 by Falk

User contributions licensed under CC BY-SA 3.0