Forum: Mikrocontroller und Digitale Elektronik STM32-F407: Probleme mit ADC_DMAAccessMode_1


von Rettungsbenny (Gast)


Lesenswert?

Hallo liebe Forumgemeinde,

ich habe folgendes Problem mit meinem STM32F4 Discoveryboard. Ich möchte 
6 Analogdigitalwandlerkanäle abtasten und nutze dafür ADC1, ADC2 und 
ADC3. Ich möchte die Werte über DMA auslesen und habe hierzu meinen 
Mikrocontroller wie in der ADC.c gezeigt programmiert.

Nun zu meinem Problem, wenn ich im Debugmodus auf meine Array 
"ADCConvertedValue[6]" schaue, ändern sich im ADC_DMAAccessMode_1 meine 
Werte nicht. Wenn ich das ganze auf Mode 3 stelle ändern sich die Werte 
scheinbar willkürlich. Hat jemand eine Idee, welche Einstellungen hier 
falsch sind?

Vielen Dank für eure Hilfe

Rettungsbenny

[[adc.c]]
[c]
/* Private Include*/

#include "ADC.h"
/* Private Defines*/

/* Privat Variable */
__IO uint16_t ADCConvertedValue[ADCSENSORn];

__IO uint32_t ADC3ConvertedVoltage=0;
__IO uint16_t ADC3ConvertedValue = 0;
__IO uint16_t ADC3ConvertedValue1 = 0;
__IO uint16_t ADC3ConvertedValue2= 0;


/*ADC Struct, contains the ADC Value Array and the Buffersize*/
struct ADCData dataSet1;

/* Function Area*/

// Set sample Time via recieve Command
// Set ADC Channel numbers via recieve Command

// INIT ADC
void InitADC(void){
  ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;
  GPIO_InitTypeDef      GPIO_InitStructure;

  // Enable GPIO Clocks, ADC1, ADC2, ADC3, DMA2
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA |
                         RCC_AHB1Periph_GPIOC, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2 |
                         RCC_APB2Periph_ADC3, ENABLE);

  // See DMA2 request mapping [STM32F407 reference Manual table 43
  // DMA2 Stream0 channel0 configuration DMAStream ADC1
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC_CDR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = 
(uint32_t)&ADCConvertedValue;//[2]
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 6;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = 
DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  DMA_Cmd(DMA2_Stream0, ENABLE);

  // GPIO Init ADC1 --> PA3; PA4; PA5; PA6

  GPIO_InitStructure.GPIO_Pin = ADCSENSOR1_PIN|ADCSENSOR2_PIN | 
ADCSENSOR3_PIN|ADCSENSOR4_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;  // Set PA3 and PA4 as 
Analog Input
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  // GPIO Init ADC2 --> PA5; PA6;
  GPIO_InitStructure.GPIO_Pin = ADCSENSOR3_PIN|ADCSENSOR4_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);


  // GPIO Init ADC3 --> PC0; PC2;
  GPIO_InitStructure.GPIO_Pin = ADCSENSOR5_PIN|ADCSENSOR6_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  // Common ADC Init
  ADC_CommonInitStructure.ADC_Mode = ADC_TripleMode_RegSimult;//;
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_1; //DMA 
mode 1 enabled (2 / 3 half-words one by one - 1 then 2 then 3)
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = 
ADC_TwoSamplingDelay_5Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);

  // Config the ADC
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_8b;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;//DISABLE
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = 
ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 2;//2
  // Init ADC1
  ADC_Init(ADC1, &ADC_InitStructure);
  // Init ADC2
  ADC_Init(ADC2, &ADC_InitStructure);
  // Init ADC3
  ADC_Init(ADC3, &ADC_InitStructure);


  // ADC regular channel configuration
  ADC_RegularChannelConfig(ADCSENSOR1_ADC, ADCSENSOR1_CHANNEL, 1, 
ADDCSENSORSampeTime);
  ADC_RegularChannelConfig(ADCSENSOR2_ADC, ADCSENSOR2_CHANNEL, 2, 
ADDCSENSORSampeTime);
  ADC_RegularChannelConfig(ADCSENSOR3_ADC, ADCSENSOR3_CHANNEL, 3, 
ADDCSENSORSampeTime);
  ADC_RegularChannelConfig(ADCSENSOR4_ADC, ADCSENSOR4_CHANNEL, 4, 
ADDCSENSORSampeTime);
  ADC_RegularChannelConfig(ADCSENSOR5_ADC, ADCSENSOR5_CHANNEL, 5, 
ADDCSENSORSampeTime);
  ADC_RegularChannelConfig(ADCSENSOR6_ADC, ADCSENSOR6_CHANNEL, 6, 
ADDCSENSORSampeTime);

 // Enable DMA request after last transfer (Single-ADC mode)
  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
  ADC_DMARequestAfterLastTransferCmd(ADC2, ENABLE);
  ADC_DMARequestAfterLastTransferCmd(ADC3, ENABLE);

  // Enable ADC DMA
  ADC_DMACmd(ADC1, ENABLE);

  // Enable ADC3
  ADC_Cmd(ADC1, ENABLE);
  ADC_Cmd(ADC2, ENABLE);
  ADC_Cmd(ADC3, ENABLE);

  // Start the ADC Software Conversion
  ADC_SoftwareStartConv(ADC1);
  ADC_SoftwareStartConv(ADC2);
  ADC_SoftwareStartConv(ADC3);

}

uint32_t ADC_convertToVoltage(int l){
/* convert the ADC value (from 0 to 0xFFF) to a voltage value (from 0V 
to 3.3V)*/
   // ADC3ConvertedVoltage = ADC3ConvertedValue *3300/0x0FF;//0xFFF
    ADC3ConvertedVoltage = ADCConvertedValue[l] *3300/0x0FF;//0xFFF

    return(ADC3ConvertedVoltage);

}
[\c]
[[adc.h]]
[c]
/* recursive inclusion guard */
#ifndef __ADC_H
#define __ADC_H

/* Includes */
#include "stm32f4xx.h"
#include "stm32f4x7_eth_bsp.h"
#include "SensorTrigger.h"
#include <stdio.h>


/* Private Define*/

#define ADC_CDR_ADDRESS     ((uint32_t)0x40012308)
#define ADC1_DR_ADDRESS     ((uint32_t)0x4001224C)
#define ADC2_DR_ADDRESS     ((uint32_t)0x4001224C)
#define ADC3_DR_ADDRESS     ((uint32_t)0x4001224C)
#define BufferSize 1024

typedef enum
{
  ADCSENSOR1 = 0,
  ADCSENSOR2 = 1,
  ADCSENSOR3 = 2,
  ADCSENSOR4 = 3,
  ADCSENSOR5 = 4,
  ADCSENSOR6 = 5
} ADCTypeDef;


#define ADCSENSORn                             6
#define ADDCSENSORSampeTime                    ADC_SampleTime_480Cycles

#define ADCSENSOR1_ADC                         ADC1
#define ADCSENSOR1_PIN                         GPIO_Pin_3
#define ADCSENSOR1_CHANNEL                     ADC_Channel_3
#define ADCSENSOR1_GPIO_CLK                    RCC_AHB1Periph_GPIOA

#define ADCSENSOR2_ADC                         ADC1
#define ADCSENSOR2_PIN                         GPIO_Pin_4
#define ADCSENSOR2_CHANNEL                     ADC_Channel_4
#define ADCSENSOR2_GPIO_CLK                    RCC_AHB1Periph_GPIOA

#define ADCSENSOR3_ADC                         ADC2
#define ADCSENSOR3_PIN                         GPIO_Pin_5
#define ADCSENSOR3_CHANNEL                     ADC_Channel_5
#define ADCSENSOR3_GPIO_CLK                    RCC_AHB1Periph_GPIOA

#define ADCSENSOR4_ADC                         ADC2
#define ADCSENSOR4_PIN                         GPIO_Pin_6
#define ADCSENSOR4_CHANNEL                     ADC_Channel_6
#define ADCSENSOR4_GPIO_CLK                    RCC_AHB1Periph_GPIOA

#define ADCSENSOR5_ADC                         ADC3
#define ADCSENSOR5_PIN                         GPIO_Pin_0
#define ADCSENSOR5_CHANNEL                     ADC_Channel_10
#define ADCSENSOR5_GPIO_CLK                    RCC_AHB1Periph_GPIOC

#define ADCSENSOR6_ADC                         ADC3
#define ADCSENSOR6_PIN                         GPIO_Pin_2
#define ADCSENSOR6_CHANNEL                     ADC_Channel_12
#define ADCSENSOR6_GPIO_CLK                    RCC_AHB1Periph_GPIOC
/* Privat Variable */
/*__IO uint16_t ADC3ConvertedValue;
__IO uint32_t ADC3ConvertedVoltage;*/

//Struct ADC Add contains the a Array of Voltage Values and a Length of 
the Array
struct ADCData{
uint32_t ValueSetr[BufferSize];
uint32_t i;// Laufzeitvariable für For-Schleifen
};

/*Exported Functions*/
//uint32_t ADC_convertToVoltage(void);
void InitADC(void);
uint32_t ADC_convertToVoltage(int l);
void ADC3_CH12_DMA_Config(void);
void takeOneSet (void);


#endif /* __ADC_H */
[\c]

von Peter M. (lctromnml)


Lesenswert?

Du hast nur DMA2 channel 0 stream 0 konfiguriert, das ist korrekt für 
ADC1. ADC2 und 3 liegen aber auf anderen Channels/Streams siehe 
Reference Manual Seite 165, und die konfigurierst du nicht, oder?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.