AD-Wandler STM32

Gast #5017940
Lesenswert?

Hallo,
ich versuche mit einem STM32F103 einen 4 Kanaligen AD-Wandler in betrieb 
zu nehmen. Dazu soll der DMA genutz werden. Allerdings habe ich nun das 
Problem, das nur in ADC_values[0] ein sinnvoller Wert. Sieht hier 
irgendjemand wo das Problem liegen könnte?

#define UEW_24V               GPIO_Pin_0
#define UEW_24V_Channel       ADC_Channel_0
#define UEW_7V5               GPIO_Pin_1                  ///<PA1 
ADC12_IN1
#define UEW_7V5_Channel       ADC_Channel_1
#define UEW_5V                GPIO_Pin_2                  ///<PA2 
ADC12_IN2
#define UEW_5V_Channel        ADC_Channel_2
#define UEW_3V3               GPIO_Pin_3                  ///<PA3 
ADC12_IN3
#define UEW_3V3_Channel       ADC_Channel_3
#define UEW_GPIO_PORT         GPIOA                       ///< 
Verwendeter Port mit AD-Wandler

/**
 * @brief Auswahl moeglicher AD-wandler Kanaele
 */
typedef enum {
  AN_UEW_24V,     ///< AD-Wert 24V
  AN_UEW_7V5,     ///< AD-Wert 7,5V
  AN_UEW_5V,      ///< AD-Wert 5V
  AN_UEW_3V3,     ///< AD-Wert 3,3V
  MAX_ANALOG      ///< Anzahl Analoger Eingaenge
} analog_t;

volatile uint16_t ADC_values[MAX_ANALOG];       ///< Array mit Werten 
des AD-Wandlers

/*********************************************************************** 
************  Beginn der Initialisierung 
*************************************/

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ANALOG, ENABLE);
  RCC_ADCCLKConfig(RCC_PCLK2_Div6);
  // GPIO Pins für ADC konfigurieren
  GPIO_InitStructure.GPIO_Pin = UEW_24V | UEW_3V3 | UEW_5V | AN_UEW_7V5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // Analog Mode
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(UEW_GPIO_PORT, &GPIO_InitStructure);

  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;       // ENABLE = 
Multiple Channels
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = MAX_ANALOG;
  ADC_Init(ADC1, &ADC_InitStructure);

  // ADC1 regular channel12 configuration
  ADC_RegularChannelConfig(ADC1, UEW_24V_Channel, 1, 
ADC_SampleTime_41Cycles5);
  ADC_RegularChannelConfig(ADC1, UEW_7V5_Channel, 2, 
ADC_SampleTime_41Cycles5);
  ADC_RegularChannelConfig(ADC1, UEW_5V_Channel,  3, 
ADC_SampleTime_41Cycles5);
  ADC_RegularChannelConfig(ADC1, UEW_3V3_Channel, 4, 
ADC_SampleTime_41Cycles5);

  // Enable ADC1 reset calibration register
  ADC_ResetCalibration(ADC1);
  ADC_StartCalibration(ADC1);
  // Enable ADC1
  ADC_Cmd(ADC1, ENABLE);
  // Enable ADC1 DMA
  ADC_DMACmd(ADC1, ENABLE);

  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
    // DMA Configuration
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
  // reset DMA channel
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_values;
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_PeripheralDataSize = 
DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = MAX_ANALOG;
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR;
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
  // Enable DMA1 Channel Transfer Complete interrupt
  DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);
  //    Enable DMA1 Channel Transfer Complete interrupt
  DMA_Cmd(DMA1_Channel1, ENABLE); //Enable the DMA1 - Channel1
  DMA_Cmd(DMA1_Channel1, ENABLE); //Enable the DMA1 - Channel1
Gast #5018186
Lesenswert?

Ohne dass ich mich im Detail mit den einzelnen Funktionen beschäftigt
hatte:
Ich würde mir mal mit den zeitlichen Abhängigkeiten der
DMAEnable, ADCEnable und ADC_SoftwareStartConv Kommandos ansehen.

>Allerdings habe ich nun das Problem, das nur in ADC_values[0] ein >sinnvoller 
Wert

WANN stellst Du das fest? Im DMA1 Channel Transfer Complete interrupt?
Gast #5018229
Lesenswert?

Ich habe gerade erst mit dem STM32 angefangen und bin daher ncht sicher 
ob ich noch den NVIC für den DMA zu initialisieren muss.

TripTrab schrieb:
> WANN stellst Du das fest? Im DMA1 Channel Transfer Complete interrupt?

ich habe einen kontinuierlichen Funktionsaufruf alle paar Millisekunden 
in dem ich den Inhalt des Arrays (ADC_values) prüfe
Gast #5018233
Lesenswert?

pegel schrieb:
> MAX_ANALOG
>
> kommt mehrfach vor, aber was steht drin?


MAX_ANALOG kommt aus dem folgenden enum. Steht also 4 drin.


1
 typedef enum {
2
  AN_UEW_24V,     ///< AD-Wert 24V
3
  AN_UEW_7V5,     ///< AD-Wert 7,5V
4
  AN_UEW_5V,      ///< AD-Wert 5V
5
  AN_UEW_3V3,     ///< AD-Wert 3,3V
6
  MAX_ANALOG      ///< Anzahl Analoger Eingaenge
7
} analog_t;
Gast #5018295
Lesenswert?

was ich nicht ganz verstehe, ist wie das erste element des Arrays 
richtig beschrieben werden kann. Das wird doch wenn ich das richtig sehe 
über
1
 DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_values;
eingeleitet. Was muss ich dem DMA für weitere ANgaben machen ,das er das 
Array mit den Werten der anderen ADC s füllt?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren