STM32F429 DMA und ADC

Gast #3751949
Lesenswert?
• ▲
▼
Hallo Leute,

ich bin im Moment dabei den DMA Controller des STM32F429 zu 
programmieren. Leider funktioniert da gar nichts... Ich habe versucht 
den DMA DataCounter (SxNDTR) zu setzen und ihn dirket danach auszulesen. 
Leider funktioniert das nicht, ich erhalte immer den Wert 0. Hier der 
Code dafür (die Initialisierung habe ich jetzt mal weggelassen).
1
DMA_SetCurDataCounter(DMA2_Stream0,10);
2
uint16_t asd = DMA_GetCurrDataCounter(DMA2_Stream0);
3

4
DMA_Cmd(DMA2_Stream0, ENABLE);

Woran kann das liegen? Ich schreibe doch nur einen Wert in ein 
Register...

Viele Grüße
Gast #3751989
Lesenswert?
• ▲
▼
muhh schrieb:
> Ich habe versucht
> den DMA DataCounter (SxNDTR) zu setzen und ihn dirket danach auszulesen.
> Leider funktioniert das nicht, ich erhalte immer den Wert 0.

Es funktioniert, wie es soll :-)
Das Register kann man nur lesen, wenn der DMA-Kanal aktiv ist. Das ist 
der 'wunderbare' STM32!
Gast #3752006
Lesenswert?
• ▲
▼
Wenn er aktiv ist, oder wenn er aktiviert ist?
Letzteres wäre ja nun das Muster, das man überall in dem Teil hat. Wenn 
ein Gerät abgeschaltet ist, dann hört es eben auch nicht am AHB mit...
Gast #3752012
Lesenswert?
• ▲
▼
Folgenden Code habe ich verwendet, vielleicht habe ich euch einfach auch 
nur missverstanden und es deswegen falsch gemacht.
1
DMA_Cmd(DMA2_Stream0, DISABLE);
2
DMA2_Stream0->NDTR = 10;
3
DMA_Cmd(DMA2_Stream0, ENABLE);
4
asd = DMA_GetCurrDataCounter(DMA2_Stream0);
5
asm volatile ("nop"::);

Bei dem As. Befehl habe ich einen Breakpoint gesetzt um zu schauen, 
welcher Wert in asd steht, leider immer noch 0. Ich benutze ganz am 
Anfang die Funktion DMA_DeInit(DMA_Stream0), aber eigentlich werden da 
alle Werte nur auf 0 gesetzt... Ich weiß echt nicht woran das liegt, ich 
bekomme den DMA einfach nicht zum laufen, selbst diese einfachen 
Sachen...
Gast #3752440
Lesenswert?
• ▲
▼
muhh schrieb:
> ich bin im Moment dabei den DMA Controller des STM32F429 zu
> programmieren. Leider funktioniert da gar nichts...

Was ich Dir weiter oben andeuten wollte: der DMA-Controller ist eine 
Krücke. Nimm das "Referece Manual" RM0090 und lies zwischen den Zeilen 
genau nach, was alles nicht geht.
Dann such Dir ein Beispielprogramm, was in etwa die von Dir gewünschte 
Funktion erfüllt und passe es an.

Wenn Du einen richtigen DMAC brauchst, dann nimm einen RX62/RX63 von 
Renesas.
#3753005
Lesenswert?
• ▲
▼
BastiDerBastler schrieb:
> Hast Du im RCC_AHB1ENR den DMA-Controller selber angeschaltet?

-.- Ich hatte anstelle von
1
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
 geschrieben:
1
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

Manchmal ist echt der Wurm drin... Dankeschön für die Tipps, ich bin 
froh das ich das jetzt geklärt habe, der DMA läuft jetzt mit dem ADC :)
#3753231
Lesenswert?
• ▲
▼
Clemens M. schrieb:
> Hätte es auch vorher, du hast ja zweimal das Selbe geschrieben ;-)

Oh man ey, Copy Paste Fehler :D

Vorher:
1
RCC_AHB1PeriphResetCmd(RCC_AHB1Periph_DMA2, ENABLE);

Nachher:
1
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

Ich habe doch noch ein kleines Problem mit dem ADC und dem DMA. Ich 
möchte erstmal 2 Channel im Scan Mode wandeln und diese Werte via DMA in 
ein Array mit 2 Feldern schreiben. Leider funktioniert das nicht so wie 
ich möchte. Die erste Gruppen-Wandlung wird in das Array geschrieben, 
die Werte ändern sich aber nie wieder.

Hier die Konfiguration:
1
/** Enable peripheral clocks */
2
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);  // 90 MHz ADC1 Clk
3
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
4
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
5

6
  ADC_DeInit();
7
  ADC_StructInit(&ADC_InitStructure);
8

9
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
10
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
11
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
12
  ADC_InitStructure.ADC_NbrOfConversion = 2;
13
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
14
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
15

16
  ADC_Init(ADC1, &ADC_InitStructure);
17
  ADC_Cmd(ADC1, ENABLE);
18
  ADC_DMACmd(ADC1, ENABLE);
19

20
  /**
21
   * Configure Regular Channel Group
22
   * Tconv = Sampling Time + 12 cycles
23
   */
24
  ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_15Cycles);    // => Tconv = (15 + 12) cycles = 1.2us
25
  ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_15Cycles);
26

27
  ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
28

29
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
30
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
31
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
32
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
33
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
34
  GPIO_Init(GPIOC, &GPIO_InitStructure);
35

36
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
37
  NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
38
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
39
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
40
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
41
  NVIC_Init(&NVIC_InitStructure);
42
  NVIC_EnableIRQ(ADC_IRQn);
43

44

45
  /*************************************************
46
   * DMA Configuration
47
   ************************************************/
48

49
  DMA_StructInit(&DMA_InitStructure);
50
  DMA_DeInit(DMA2_Stream0);
51

52
  DMA_InitStructure.DMA_BufferSize = 2;
53
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;
54
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
55
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t) &PedalConvValue[0];
56
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;      // Don't Care
57
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
58
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
59
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
60
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
61
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
62
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
63

64
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
65

66
  GPIO_ToggleBits(GPIOG, GPIO_Pin_13);
67
  GPIO_ToggleBits(GPIOG, GPIO_Pin_14);
68
  DMA_Cmd(DMA2_Stream0, ENABLE);

Auf Knopfdruck wird eine Wandlung gestartet. Das ADC Interrupt wird nach 
einer ScanConversion ausgelöst. Hier die ISR:
1
void ADC_IRQHandler(void)
2
{
3
  NVIC_ClearPendingIRQ(ADC_IRQn);
4
  ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
5

6
  uint_fast16_t DMACounterValue = DMA_GetCurrDataCounter(DMA2_Stream0);
7

8
  uint16_t PedalValue = ADC_GetConversionValue(ADC1);
9
  uint16_t asdasd[4] = {PedalConvValue[0],PedalConvValue[1],PedalConvValue[2],PedalConvValue[3]};
10

11
  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
12

13
  uint32_t adc_cr = ADC1->CR2 & 0x00000200;           // Wird das DDS Bit gesetzt?
14
  GPIO_ToggleBits(GPIOG, GPIO_Pin_13);
15
}

Wenn ich die die DMA_BufferSize auf 4 setze, dann funktioniert das ganze 
einwandfrei, er füllt immer zwei Felder mit Daten und nach zwei 
ScanConversions fängt er von vorne an.
#3753245
Lesenswert?
• ▲
▼
m.n. schrieb:
> muhh schrieb:
>> Ich habe versucht
>> den DMA DataCounter (SxNDTR) zu setzen und ihn dirket danach auszulesen.
>> Leider funktioniert das nicht, ich erhalte immer den Wert 0.
>
> Es funktioniert, wie es soll :-)
> Das Register kann man nur lesen, wenn der DMA-Kanal aktiv ist. Das ist
> der 'wunderbare' STM32!

Das stimmt meines wissens nach nicht. das DMA-SxNDTR Register kann, wenn 
der Stream aus ist sowohl geschrieben als auch gelesen werden. Ist der 
Stream jedoch an kann er gelesen aber nicht beschrieben werden.

Gruß
Christopher

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.