Forum: Compiler & IDEs ASTM32F4-discovery: DMA will nicht wie ich will


von Michaela (Gast)


Lesenswert?

Hallo zusammen,

ich muss euch schon wieder konsultieren. Mein Problem ist folgendes:
Ich möchte den STM32F4 dazu bringen per DMA Daten an den GPIOD zu 
schrieben. Getriggert werden soll der DMA von einem Timer.
Nun der Timer läuft, der GPIOD ist scheinbar richtig konfiguriert, denn 
er funktioniert ebenfalls. Nur der DMA scheint nichts zu tun. Was mache 
ich da falsch?
Wäre schön wenn mir jemand einen Tip geben könnte.

Mein Code: (also die main.c)
1
#include <stdint.h>
2
#include "stm32f4xx_conf.h"
3
4
void initDebugLEDs( void );
5
6
int main(void)
7
{
8
  GPIO_InitTypeDef    GPIO_InitStructure;
9
  TIM_TimeBaseInitTypeDef  TIM_TimeBase_InitStructure;
10
  TIM_OCInitTypeDef    TIM_OC_InitStructure;
11
  DMA_InitTypeDef      DMA_InitStructure;
12
13
  SystemInit();
14
15
  // Timer init
16
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
17
18
  TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
19
  TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
20
  TIM_TimeBase_InitStructure.TIM_Period = 1000 -1;
21
  TIM_TimeBase_InitStructure.TIM_Prescaler = 2700 -1;
22
  TIM_TimeBaseInit(TIM3, &TIM_TimeBase_InitStructure);
23
24
  TIM_Cmd(TIM3, ENABLE);
25
26
  // PWM to see Timer is running
27
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
28
29
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
30
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
31
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
32
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
33
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
34
  GPIO_Init(GPIOA, &GPIO_InitStructure);
35
36
  TIM_OC_InitStructure.TIM_OCMode = TIM_OCMode_PWM1;
37
  TIM_OC_InitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
38
  TIM_OC_InitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
39
  TIM_OC_InitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
40
  TIM_OC_InitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
41
  TIM_OC_InitStructure.TIM_OutputState = TIM_OutputState_Enable;
42
  TIM_OC_InitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
43
  TIM_OC_InitStructure.TIM_Pulse = 100;
44
  TIM_OC1Init(TIM3, &TIM_OC_InitStructure);
45
46
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3); // Pin A6 gibt ein 10%-PWM Signal aus (10Hz)
47
48
  // DMA
49
  uint16_t dma_buffer[3] = {
50
                GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15,
51
                GPIO_Pin_12 | GPIO_Pin_14,
52
                0x0000 };
53
54
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
55
56
  DMA_InitStructure.DMA_Channel = DMA_Channel_5;
57
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(GPIOD->ODR));
58
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dma_buffer;
59
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
60
  DMA_InitStructure.DMA_BufferSize = 3;
61
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
62
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
63
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
64
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
65
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
66
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
67
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
68
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
69
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
70
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
71
72
  DMA_Init(DMA1_Stream2, &DMA_InitStructure);
73
  DMA_Cmd(DMA1_Stream2, ENABLE);
74
75
  // Debug-pin
76
  initDebugLEDs();
77
78
  while(1)
79
  {
80
    for( volatile int i=0; i<1000000; i++ )
81
      ;
82
    GPIO_ToggleBits( GPIOD, GPIO_Pin_12 ); // LED blinkt ganz brav
83
84
  }
85
}
86
87
88
void initDebugLEDs( void ){
89
  GPIO_InitTypeDef GPIO_InitStructure;
90
91
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
92
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
93
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
94
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
95
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
96
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
97
  GPIO_Init(GPIOD, &GPIO_InitStructure);
98
}

Wäre super wenn jemand meinen Fehler erkennen kann.

vielen Dank
Grüße Michaela

von Michaela (Gast)


Lesenswert?

Langsam fange ich an, die STMs nicht mehr zu mögen. Die Datenblätter 
sind im Vergleich zu den Atmels totaler Nonsense.
Und für alles was man tut gibt es wieder ein verstecktes kleines Bit, 
das alles Blockiert.

in diesem Falle ist es:
1
  TIM_DMACmd(TIM1,TIM_DMA_Update,ENABLE);

So ein käse!

von Michaela (Gast)


Lesenswert?

Ganz vergessen: Der DMA1 hat keine Verbindung zum AHAB1 und kann daher 
nicht auf die GPIOs zugreifen.

Mein jetz funktionierender code sieht folgendermaßen aus:
1
#include <stdint.h>
2
#include "stm32f4xx_conf.h"
3
4
void initDebugLEDs( void );
5
6
int main(void)
7
{
8
  GPIO_InitTypeDef    GPIO_InitStructure;
9
  TIM_TimeBaseInitTypeDef  TIM_TimeBase_InitStructure;
10
  TIM_OCInitTypeDef    TIM_OC_InitStructure;
11
  DMA_InitTypeDef      DMA_InitStructure;
12
13
  SystemInit();
14
15
  // Timer init
16
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
17
18
  TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
19
  TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
20
  TIM_TimeBase_InitStructure.TIM_Period = 1000 -1;
21
  TIM_TimeBase_InitStructure.TIM_Prescaler = 2700 -1;
22
  TIM_TimeBaseInit(TIM3, &TIM_TimeBase_InitStructure);
23
24
  TIM_Cmd(TIM3, ENABLE);
25
26
  // PWM to see Timer is running
27
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
28
29
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
30
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
31
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
32
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
33
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
34
  GPIO_Init(GPIOA, &GPIO_InitStructure);
35
36
  TIM_OC_InitStructure.TIM_OCMode = TIM_OCMode_PWM1;
37
  TIM_OC_InitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
38
  TIM_OC_InitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Set;
39
  TIM_OC_InitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
40
  TIM_OC_InitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
41
  TIM_OC_InitStructure.TIM_OutputState = TIM_OutputState_Enable;
42
  TIM_OC_InitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
43
  TIM_OC_InitStructure.TIM_Pulse = 100;
44
  TIM_OC1Init(TIM3, &TIM_OC_InitStructure);
45
46
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_TIM3);
47
48
49
  // DMA
50
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
51
  TIM_TimeBaseStructInit(&TIM_TimeBase_InitStructure);
52
  //TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
53
  TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
54
  TIM_TimeBase_InitStructure.TIM_Period = 10000 -1;
55
  TIM_TimeBase_InitStructure.TIM_Prescaler = 5400 -1;
56
  TIM_TimeBaseInit(TIM1, &TIM_TimeBase_InitStructure);
57
  TIM_Cmd(TIM1, ENABLE);
58
59
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
60
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
61
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
62
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
63
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
64
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
65
  GPIO_Init(GPIOE, &GPIO_InitStructure);
66
67
  TIM_OCStructInit(&TIM_OC_InitStructure);
68
  TIM_OC_InitStructure.TIM_OCMode = TIM_OCMode_PWM1;
69
  TIM_OC_InitStructure.TIM_OCIdleState = TIM_OCIdleState_Set;
70
  TIM_OC_InitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
71
  TIM_OC_InitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
72
  TIM_OC_InitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
73
  TIM_OC_InitStructure.TIM_OutputState = TIM_OutputState_Enable;
74
  TIM_OC_InitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
75
  TIM_OC_InitStructure.TIM_Pulse = 100;
76
  TIM_OC1Init(TIM1, &TIM_OC_InitStructure);
77
78
  TIM_ARRPreloadConfig(TIM1, ENABLE);
79
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_TIM1);
80
    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
81
82
    TIM_CtrlPWMOutputs(TIM1, ENABLE);
83
84
  uint16_t dma_buffer[3] = {  GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15,
85
                GPIO_Pin_12 | GPIO_Pin_14,
86
                0x0000 };
87
88
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
89
90
  DMA_InitStructure.DMA_Channel = DMA_Channel_6;
91
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(GPIOD->ODR));
92
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)dma_buffer;
93
  DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
94
  DMA_InitStructure.DMA_BufferSize = 3;
95
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
96
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
97
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
98
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
99
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
100
  DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
101
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
102
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
103
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
104
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
105
106
  DMA_Init(DMA2_Stream5, &DMA_InitStructure);
107
  DMA_Cmd(DMA2_Stream5, ENABLE);
108
  TIM_DMACmd(TIM1,TIM_DMA_Update,ENABLE);
109
110
111
  // Debug-pin
112
  initDebugLEDs();
113
114
  while(1)
115
  {
116
  }
117
}
118
119
120
void initDebugLEDs( void ){
121
  GPIO_InitTypeDef GPIO_InitStructure;
122
123
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
124
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
125
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
126
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
127
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
128
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
129
  GPIO_Init(GPIOD, &GPIO_InitStructure);
130
}

Jetzt gibts nen PWM an PinA6 vom Timer3 und ein PWM am PinE9 vom Timer1.
Die Debug-LEDs schalten wie gedacht im Sekundentakt.
Kaum sind ein paar Stunden rum.....

Ich wünsche allen viel Spaß damit und hoffe es hilf jemandem
Grüße Michaela

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.