Forum: Mikrocontroller und Digitale Elektronik STM32F205RC Probleme mit ADC und DMA


von Johnas M. (jom)


Lesenswert?

Hi,
ich versuche gerade den AD Wandler des STM32F205RC mit DMA zum Laufen zu 
bekommen und habe anscheinend noch einige Verständnisprobleme.

Als Basis für die Initialisierung habe ich das Beispiel ADC3_DMA aus der 
STM32F2xx Standard Peripherals Library verwendet. Diese initialisiert 
den ADC3 am GPIO Port F Pin 9. Nun möchte ich den ADC1 am Port A Pin 4 
für die AD Wandlung verwenden. Hintergrund ist, dass ich in meiner 
Schaltung den STM32F205RC im LQFP64 Gehäuse verwende und dieser keinen 
Port F hat.

Das Beispiel aus der Standard Peripherals Library hatte ich bereits für 
das Evaluation Board STM3220G-EVAL verwendet, wo es einwandfrei lief.

Folgende Änderungen habe ich in dem Beispiel vorgenommen:

Peripherie Takt:
-  Peripherie Clock des ADC1 angeschaltet.

DMA Einstellungen:
-  DMA2  auf Kanal 0 Stream 0 eingestellt.
-  Die DR Adresse vom ADC1 verwendet  (0x4001204C).

GPIO Einstellung:
-  GPIO_Mode_AN  für den Port A Pin 4 verwendet.

Sämtliche weitere Einstellungen habe ich von ADC3 auf ADC 1 geändert.

Der einzige Punkt, bei dem ich mir nicht ganz sicher bin, ist der ADC 
Kanal. Hier sollte es nach meinem Verständnis egal sein, welchen Kanal 
ich verwende. Wie gesagt, ich bin mir da aber nicht ganz sicher.

Trotz der oben aufgeführten Änderungen, bekomme ich den AD Wandler nicht 
zum Laufen.

Der AD Wert bewegt sich unabhängig von der Spannung zwischen 0x0070 und 
ca. 0x007f, was meiner Meinung nach lediglich ein Rauschen ist.

Evtl. erkennt einer von euch, was ich noch übersehen habe.

Schon mal Danke im Voraus.


Anbei der Quelltext:
1
#define ADC1_DR_ADDRESS    ((uint32_t)0x4001204C)
2
3
__IO uint16_t ADC1ConvertedValue;
4
5
void Hardware_AD_Init(void)
6
{
7
  ADC_InitTypeDef       ADC_InitStructure;
8
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
9
  DMA_InitTypeDef       DMA_InitStructure;
10
  GPIO_InitTypeDef      GPIO_InitStructure;
11
12
  /* Enable ADC1, DMA2 and GPIO clocks ****************************************/
13
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOA, ENABLE);
14
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
15
16
  /* DMA2 Stream0 channel0 configuration **************************************/
17
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
18
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
19
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADC1ConvertedValue;
20
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
21
  DMA_InitStructure.DMA_BufferSize = 1;
22
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
23
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
24
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
25
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
26
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
27
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
28
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
29
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
30
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
31
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
32
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
33
  DMA_Cmd(DMA2_Stream0, ENABLE);
34
35
  /* Configure ADC1 as analog input 
36
*********************************************************/
37
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
38
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
39
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
40
  GPIO_Init(GPIOA, &GPIO_InitStructure);
41
42
  /* ADC Common Init **********************************************************/
43
  ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
44
  ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
45
  ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
46
  ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
47
  ADC_CommonInit(&ADC_CommonInitStructure);
48
49
  /* ADC1 Init ****************************************************************/
50
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
51
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
52
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
53
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
54
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
55
  ADC_InitStructure.ADC_NbrOfConversion = 1;
56
  ADC_Init(ADC1, &ADC_InitStructure);
57
58
  /* ADC1 regular channel1 configuration *************************************/
59
  ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_3Cycles);
60
61
 /* Enable DMA request after last transfer (Single-ADC mode) */
62
  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
63
64
  /* Enable ADC1 DMA */
65
  ADC_DMACmd(ADC1, ENABLE);
66
67
  /* Enable ADC1 */
68
  ADC_Cmd(ADC1, ENABLE);
69
}
70
71
void StartConversion(void)
72
{
73
  ADC_SoftwareStartConv(ADC1);   // A/D convert start
74
}
75
76
UINT16 ui16_Read_ADC1_ConvertedValue(void)
77
{
78
  return ADC1ConvertedValue;      // Read and return conversion result 
79
}

von Uwe B. (derexponent)


Lesenswert?

Hi Johnas,

hier ist dein Fehler :
1
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_3Cycles);

wenn du den Pin PA4 benutzen willst, musst du schreiben
1
ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_3Cycles);


und beim Clock musst du mal nachschauen ob der nicht über dem Limit 
liegt
beim STM32F4 und max Clock reicht ein Teiler 2 nicht aus
(das kann beim STM32F2 aber auch anders sein)

Gruss Uwe

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Hallo,

les Dir auch die F2 Erratas durch und pruefe, ob
2.1.7 DMA2 data corruption when managing AHB and APB peripherals in a
      concurrent way . . . . . . . . . . . . . . . . . . . . . . . 14
fuer Deinen Fall zutrifft.

von Johnas M. (jom)


Lesenswert?

Hi Uwe,
du hast recht, ich hatte den falschen AD Kanal eingestellt.

Danke für die schnelle Antwort.

Gruß,
JoM

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.