0
votes

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;

1
I used the mode ``Register for that. Port A Pin 1 to 7 defined as analoge mode GPIOA->MODER |= 0x0000FFFC; // Pin 1-7 Port a as analogFalk
you do not understand and do not want cooperate - i am out This is CMSIS definitions ADC_CR2_CONT and this is magic number : 0x00022901. do you see the difference? Registers do not matter here0___________
yes you are right, i don't understand what you want to tell me with your commentFalk
mamy increment Has to be enabled.0___________
Thanks. mamy increment? Can't find this in the manualFalk

1 Answers

0
votes

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.