Forum: Mikrocontroller und Digitale Elektronik DMA geht nur einmal! STM32


von Ingo (Gast)


Lesenswert?

Ich habe folgende Problem. Der DMA Funktioniert nur einmal, dann bleibt 
er auf 9999 stehen bzw. 10000. Ich finde den Fehler einfach nicht!

Der Timer der den ADC-Triggert läuft weiterhin, aber geht halt nur 
einmal. Im Circular-Mode gibts keine Probleme, also irgendwas übersehe 
ich noch bei Neustarten des DMA! Woran liegts?

Ingo

STM32F405, CooCox.
1
while(1){
2
3
      if (Flags.RS232DebugOut){
4
        Flags.RS232DebugOut = OFF;
5
        Set_DataCounter(10000);
6
        uint32_t Temp = 0;
7
        Temp = DMA_GetCurrDataCounter(DMA2_Stream0);
8
        printf("\n%u", (unsigned int)Temp);
9
        MyDelayMS(10);
10
        Temp = DMA_GetCurrDataCounter(DMA2_Stream0);
11
        printf("\n%u", (unsigned int)Temp);
12
      }
13
14
    }
15
16
17
void Init_ADC ( void )
18
{
19
  /* Takt für Peripherie setzen */
20
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
21
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 , ENABLE);
22
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1, ENABLE);
23
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
24
25
    GPIO_InitTypeDef GPIO_InitStructure;
26
    GPIO_StructInit(&GPIO_InitStructure);
27
    ADC_InitTypeDef ADC_InitStructure;
28
    ADC_StructInit(&ADC_InitStructure);
29
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
30
    ADC_CommonStructInit(&ADC_CommonInitStructure);
31
    DMA_InitTypeDef DMA_InitStructure;
32
    DMA_StructInit(&DMA_InitStructure);
33
    TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
34
    TIM_TimeBaseStructInit (&TIM_TimeBase_InitStructure);
35
//    NVIC_InitTypeDef NVIC_InitStructure;
36
37
    TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
38
    TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;
39
40
41
    TIM_TimeBase_InitStructure.TIM_Period = 840;
42
    TIM_TimeBase_InitStructure.TIM_Prescaler = 0;
43
    TIM_TimeBaseInit(TIM2, &TIM_TimeBase_InitStructure);
44
45
    TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
46
    TIM_SelectOutputTrigger(TIM2,TIM_TRGOSource_Update);
47
    TIM_ARRPreloadConfig(TIM2, ENABLE);
48
49
//    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
50
//    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
51
//    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
52
//    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
53
//    NVIC_Init(&NVIC_InitStructure);
54
    //TIM_Cmd(TIM2, ENABLE);
55
56
57
    /////////////////////////////////////////////////////////////////
58
    // GPIOC
59
    /////////////////////////////////////////////////////////////////
60
61
62
    /* ADC Kanäle */
63
    /* IO initialisieren */
64
    GPIO_StructInit(&GPIO_InitStructure);
65
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
66
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
67
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
68
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
69
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
70
    GPIO_Init(GPIOC, &GPIO_InitStructure);
71
72
    GPIO_StructInit(&GPIO_InitStructure);
73
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
74
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
75
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
76
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
77
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
78
    GPIO_Init(GPIOC, &GPIO_InitStructure);
79
80
    /* DMA Controll */
81
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;
82
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&(ADC1->DR);
83
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)DataBuffer;
84
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
85
    DMA_InitStructure.DMA_BufferSize = BUFFERSIZE;
86
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
87
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
88
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
89
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
90
  //  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
91
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
92
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;
93
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
94
    DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
95
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
96
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
97
    DMA_Init(DMA2_Stream0, &DMA_InitStructure);
98
99
    /* ADC */
100
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
101
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;
102
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
103
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
104
    ADC_CommonInit(&ADC_CommonInitStructure);
105
106
    ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
107
    ADC_InitStructure.ADC_ScanConvMode = DISABLE;
108
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
109
    ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
110
    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO;
111
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
112
    ADC_InitStructure.ADC_NbrOfConversion = 1;
113
    ADC_Init(ADC1, &ADC_InitStructure);
114
115
    ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE);
116
    ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_3Cycles);
117
118
    DMA_Cmd(DMA2_Stream0, ENABLE);
119
    ADC_Cmd(ADC1, ENABLE);
120
    ADC_DMACmd(ADC1, ENABLE);
121
    ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
122
    TIM_Cmd(TIM2, ENABLE);
123
}
124
125
void Set_DataCounter ( uint16_t Value )
126
{
127
  DMA_ClearITPendingBit(DMA2_Stream0,DMA_IT_TCIF0);
128
  DMA_ClearITPendingBit(DMA2_Stream0,DMA_IT_HTIF0);
129
  DMA_ClearITPendingBit(DMA2_Stream0,DMA_IT_TEIF0);
130
  DMA_ClearITPendingBit(DMA2_Stream0,DMA_IT_DMEIF0);
131
  DMA_ClearITPendingBit(DMA2_Stream0,DMA_IT_FEIF0);
132
  // Disable DMA Stream
133
        DMA_Cmd(DMA2_Stream0, DISABLE);
134
135
  // Clear Interrupt Flag
136
  DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TCIF0);
137
  DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_HTIF0);
138
  DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_TEIF0);
139
  DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_DMEIF0);
140
  DMA_ClearFlag(DMA2_Stream0, DMA_FLAG_FEIF0);
141
142
  // Set new Countervalue
143
  DMA_SetCurrDataCounter(DMA2_Stream0,Value);
144
  // Enable DMA Stream
145
  DMA_Cmd(DMA2_Stream0, ENABLE);
146
}

von Ingo (Gast)


Lesenswert?

Push

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

InitStructure.DMA_Mode = DMA_Mode_Circular;

von Ingo (Gast)


Lesenswert?

Genau das will ich ja nicht, ich möchte per Befehl n Messungen machen 
und danach erst wieder n Messungen wenn ich es sage!

von Ingo (Gast)


Lesenswert?

Wobei der ADC zwar ständig durch den Timer getriggert werden, aber die 
Messwerte nur gespeichert werden sollen wenn der DMA läuft.

Sonst müsste ich die Trigger-Events mitzählen, was mir aber blöde 
erscheint angesichts dessen, das die Hardware das komplett ohne CPU 
Belastung kann!

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

AD Wandler Aktivieren und mit dem DMA Interrupt den AD-Wandler 
deaktivieren.
Dann sind auch alle Wandlungen da und man kann die Daten weiter 
verarbeiten.
Mit DMA_Mode_Circular.

von Ingo (Gast)


Lesenswert?

Auf was triggert der DMA-Interrupt dann?

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Auf den Wert:
DMA_InitStructure.DMA_BufferSize = BUFFERSIZE;

von Ingo (Gast)


Lesenswert?

Aber warum meine Code nicht geht würde mich auch interessieren! Hast du 
ne Idee?

von Ingo (Gast)


Lesenswert?

Tja, sehr merkwürdig das es im "Normal-Mode" nur einmal funktioniert und 
die Tricks im Internet mit Interrupt-Flags löschen nicht helfen...

Hab jetzt tatsächlich einen Interrupt wenn er seine n Messungen fertig 
hat. Funktioniert auch sauber. Besten dank!

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Bitteschön.

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.