Forum: Mikrocontroller und Digitale Elektronik STM32F0 TIM15 -> ADC -> DMA


von Elzaar (Gast)


Lesenswert?

Guten Tag,
Kurz das Ziel was ich erreichen möchte:
Timer 15 soll mit einer Frequenz von 10 KHz den ADC Start Triggern der 
dann 6 Kanäle Wandelt und der DAM die Wert abholt.

- Der Timer 15 läuft auch schon und Setze auch brav das Flag mit 10KHz

Beim ADC ... naja ... das Scannen geht, auch mit dem DAM jedoch nur wenn 
ich ihn in Software Trigger, das Beispiel basiert auf dem CCP4 Modul vom 
Timer 1 den ich jedoch wegen der 4 PWM Ausgängen brauche.
1
void ADC1_CH_DMA_Config(void)
2
{
3
  GPIO_InitTypeDef        GPIO_InitStructure;
4
  ADC_InitTypeDef         ADC_InitStructure;
5
  DMA_InitTypeDef         DMA_InitStructure;
6
  TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
7
8
//------------------------------------------------------------------
9
//-------- DAM einstellen
10
//------------------------------------------------------------------
11
  /* DMA1 clock enable */
12
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
13
14
  /* DMA1 Channel1 Config */
15
  DMA_DeInit(DMA1_Channel1);
16
17
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;    //ADC Adresse
18
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_DMA_BUFFER;      //ADC Buffer
19
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;              //ADC -> DMA -> RAM
20
  DMA_InitStructure.DMA_BufferSize = 6;                    //Buffer Size 6
21
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
22
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
23
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //ADC Datenword = 16bit
24
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;      //RAM Datenword = 16bit, beide MÜSSEN gleich sein
25
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                //DAM als Ring Buffer (DMA_Mode_Normal)
26
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;              //Hohe Prio
27
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                //Memory -> DMA -> Memory = Disabelt
28
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
29
30
  /* DMA1 Channel1 enable */
31
  DMA_Cmd(DMA1_Channel1, ENABLE);
32
33
34
35
36
//------------------------------------------------------------------
37
//-------- Eingänge an PORTC auf Analog stellen
38
//------------------------------------------------------------------
39
  /* GPIOC Periph clock enable */
40
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
41
42
  /* Configure ADC Channel 10, 11, 12, 13 as analog input */
43
  GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2| GPIO_Pin_3);
44
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
45
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
46
  GPIO_Init(GPIOC, &GPIO_InitStructure);
47
48
49
50
//------------------------------------------------------------------
51
//-------- ADC einstellen
52
//------------------------------------------------------------------
53
  /* ADC1 Periph clock enable */
54
  RCC_ADCCLKConfig(RCC_ADCCLK_HSI14);              //14MHz RC Ozi als Clk Source benutzen
55
  RCC_HSI14Cmd(ENABLE);                    //14MHz RC Ozi für den ADC einschalten
56
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
57
58
  /* ADC1 DeInit */
59
  ADC_DeInit(ADC1);
60
61
  /* Initialize ADC structure */
62
  ADC_StructInit(&ADC_InitStructure);
63
64
  /* Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits  */
65
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;            //Res = 12bit
66
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
67
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
68
  ADC_InitStructure.ADC_ExternalTrigConv =  ADC_ExternalTrigConv_T2_TRGO;
69
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;            //Daten rechtsbündig (bis 11 bis 0)
70
  ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;        //Scannt CH 0 -> 18
71
  ADC_Init(ADC1, &ADC_InitStructure);
72
73
74
  /* Convert the ADC1 temperature sensor (ADC_IN16)  with 1.5 Cycles as sampling time */
75
  ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor , ADC_SampleTime_1_5Cycles);
76
  ADC_TempSensorCmd(ENABLE);
77
78
  /* Convert the ADC1 Vref (ADC_IN17) with 1.5 Cycles as sampling time -> 1MSa*/
79
  ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint , ADC_SampleTime_1_5Cycles);
80
  ADC_VrefintCmd(ENABLE);
81
82
  /* Convert the ADC Channel 10 with 1.5 Cycles as sampling time -> 1MSa*/
83
  ADC_ChannelConfig(ADC1, ADC_Channel_10 , ADC_SampleTime_1_5Cycles);
84
  /* Convert the ADC Channel 11 with 1.5 Cycles as sampling time -> 1MSa*/
85
  ADC_ChannelConfig(ADC1, ADC_Channel_11 , ADC_SampleTime_1_5Cycles);
86
  /* Convert the ADC Channel 12 with 1.5 Cycles as sampling time -> 1MSa*/
87
  ADC_ChannelConfig(ADC1, ADC_Channel_12 , ADC_SampleTime_1_5Cycles);
88
  /* Convert the ADC Channel 13 with 1.5 Cycles as sampling time -> 1MSa*/
89
  ADC_ChannelConfig(ADC1, ADC_Channel_13 , ADC_SampleTime_1_5Cycles);
90
91
92
  /* ADC Calibration */
93
  ADC_GetCalibrationFactor(ADC1);
94
95
  /* ADC DMA request in circular mode */
96
  ADC_DMARequestModeConfig(ADC1, DMA_Mode_Circular);          //ADC_DMAMode_Circular
97
98
  /* Enable ADC1 */
99
  ADC_Cmd(ADC1, ENABLE);
100
101
  /* Enable DMA for ADC1 Channel1 */
102
  ADC_DMACmd(ADC1, ENABLE);
103
104
//  /* Wait the ADCEN falg */
105
//  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
106
107
//  /* ADC1 regular Software Start Conv */
108
//  ADC_StartOfConversion(ADC1);
109
110
111
112
//------------------------------------------------------------------
113
//-------- Timer 15 Einstellen
114
//------------------------------------------------------------------
115
  /* TIM14 Configuration */
116
  TIM_DeInit(TIM15);
117
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
118
119
  /* Time base configuration */
120
  TIM_TimeBaseStructure.TIM_Period = (SystemCoreClock / 10000 ) - 1; //10KHz
121
  TIM_TimeBaseStructure.TIM_Prescaler = 0x0;
122
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
123
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
124
  TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStructure);
125
126
  /* TIM1 enable counter */
127
  TIM_Cmd(TIM15, ENABLE);
128
129
  TIM_SelectOutputTrigger(TIM15, TIM_TRGOSource_Update);
130
}

würde ich den Befehl:
1
ADC_StartOfConversion(ADC1);

benutzen geht es, aber eben nicht mit dem Trigger... zum überprüfen habe 
ich in der main schleife im moment nur folgendes drin:
1
  while (1)
2
  {
3
  if(TIM_GetFlagStatus(TIM2, TIM_FLAG_Update)){
4
    /* Set PC8 */
5
    GPIOC->BSRR = GPIO_Pin_8;
6
7
    TIM_ClearFlag(TIM2, TIM_FLAG_Update);
8
  }
9
  else{
10
    /* Reset PC8*/
11
    GPIOC->BRR = GPIO_Pin_8;
12
  }

was habe ich den da falsch gemacht?

vielen Dank schon mal :)

von Hauspapa (Gast)


Lesenswert?

Bist Du sicher das:
>ADC_InitStructure.ADC_ExternalTrigConv =  ADC_ExternalTrigConv_T2_TRGO;

richtig ist wenn du mit Timer 15 arbeitest?

Vergleiche reference manual S. 180/181 (RM0091)

viel Erfolg
Hauspapa

von Elzaar (Gast)


Lesenswert?

Ja du hast natürlich Recht ... das war ein kopie and Paste Fehler da 
seht TIM15_TRGO :)

Aktueller Stand ist:
Triggern geht, er scannt auch die 6 Ch. durch ... aber nur wenn ich sie 
von Hand auslesse ... ich muss jetzt aber los ... ich schreib das später 
noch mal genau.


danke schon mal :)

von Elzaar (Gast)


Lesenswert?

Also ich habe es jetzt am laufen, wie ich feststellen musste ist die 
Reihenfolge in der man die Komponenten Deinit / Clocks Einschalten etc 
ist sehr wichtig.
1
/* Includes ------------------------------------------------------------------*/
2
#include "stm32f0xx_conf.h"
3
#include "main.h"
4
5
/** @addtogroup STM32F0_Discovery_Peripheral_Examples
6
  * @{
7
  */
8
9
/** @addtogroup IO_Toggle
10
  * @{
11
  */
12
13
/* Private typedef -----------------------------------------------------------*/
14
/* Private define ------------------------------------------------------------*/
15
#define BSRR_VAL            0x0300
16
#define ADC1_DR_Address             0x40012440
17
18
/* Private macro -------------------------------------------------------------*/
19
/* Private variables ---------------------------------------------------------*/
20
GPIO_InitTypeDef       GPIO_InitStructure;
21
volatile uint32_t       TimingDelay;
22
23
//ADC BUFFER
24
enum ADC_Channels {
25
    CH10 = 0,
26
    CH11,
27
    CH12,
28
    CH13,
29
    TEMP,
30
    VREF
31
};
32
volatile uint16_t     ADC_DMA_BUFFER[6];
33
34
GPIO_InitTypeDef           GPIO_InitStructure;
35
36
/* Private function prototypes -----------------------------------------------*/
37
void TIM15_ADC1_DMA_config(void);
38
void Delay(uint32_t nTime);
39
40
/* Private functions ---------------------------------------------------------*/
41
42
43
int main(void)
44
{
45
//--------------------------------------------------------------------------------
46
//---- LED Ports des STM32F0 Discovery  Einstellen
47
//--------------------------------------------------------------------------------
48
  /* GPIOC Periph clock enable */
49
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
50
51
  /* Configure PC8 and PC9 in output pushpull mode */
52
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
53
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
54
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
55
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
56
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
57
  GPIO_Init(GPIOC, &GPIO_InitStructure);
58
59
60
  /* System Tick auf 1ms Stellen */
61
  SysTick_Config(SystemCoreClock / 1000);
62
63
  /* ADC1 channel with DMA configuration */
64
  TIM15_ADC1_DMA_config();
65
66
67
  while (1){
68
    /* Test DMA1 TC flag */
69
    if((DMA_GetFlagStatus(DMA1_FLAG_TC1)) == SET ){
70
      /* Set PC8 */
71
      GPIOC->BSRR = GPIO_Pin_8;
72
      /* Clear DMA TC flag */
73
      DMA_ClearFlag(DMA1_FLAG_TC1);
74
    }
75
    else{
76
        /* Reset PC8*/
77
        GPIOC->BRR = GPIO_Pin_8;
78
    }
79
  }
80
}
81
82
void TIM15_ADC1_DMA_config(void)
83
{
84
  ADC_InitTypeDef         ADC_InitStructure;
85
  DMA_InitTypeDef         DMA_InitStructure;
86
  TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;
87
88
//------------------------------------------------------------------
89
//-------- Periph Clocks einschalten
90
//------------------------------------------------------------------
91
  /* DMA1 clock enable */
92
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
93
94
  /* GPIOC Periph clock enable */
95
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
96
97
  /* ADC1 Periph clock enable */
98
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
99
100
  /* Initialize ADC 14MHz RC Ozi */
101
  RCC_ADCCLKConfig(RCC_ADCCLK_HSI14);              //14MHz RC Ozi als Clk Source benutzen
102
  RCC_HSI14Cmd(ENABLE);                    //14MHz RC Ozi für den ADC einschalten
103
104
  /* TIM15 clock enable */
105
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM15, ENABLE);
106
107
//------------------------------------------------------------------
108
//-------- Deinit (ADC, DMA, TIM15)
109
//------------------------------------------------------------------
110
  /* DMA1 Channel1 Config */
111
  DMA_DeInit(DMA1_Channel1);
112
113
  /* ADC1 DeInit */
114
  ADC_DeInit(ADC1);
115
116
  /* TIM15 DeInit */
117
  TIM_DeInit(TIM15);
118
119
120
//------------------------------------------------------------------
121
//-------- Port Init
122
//------------------------------------------------------------------
123
  /* Configure ADC Channel 10, 11, 12, 13 as analog input */
124
  GPIO_InitStructure.GPIO_Pin = (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2| GPIO_Pin_3);
125
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
126
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
127
  GPIO_Init(GPIOC, &GPIO_InitStructure);
128
129
130
//------------------------------------------------------------------
131
//-------- DMA Init
132
//------------------------------------------------------------------
133
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;    //ADC Adresse
134
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_DMA_BUFFER;      //ADC Buffer
135
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;              //ADC -> DMA -> RAM
136
  DMA_InitStructure.DMA_BufferSize = 6;                    //Buffer Size 6
137
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
138
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
139
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //ADC Datenword = 16bit
140
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;      //RAM Datenword = 16bit, beide MÜSSEN gleich sein
141
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                //DAM als Ring Buffer (DMA_Mode_Normal)
142
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;              //Hohe Prio
143
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                //Memory -> DMA -> Memory = Disabelt
144
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);
145
146
  /* DMA1 Channel1 enable */
147
  DMA_Cmd(DMA1_Channel1, ENABLE);
148
149
  /* ADC DMA request in circular mode */
150
  ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
151
152
  /* Enable ADC_DMA */
153
  ADC_DMACmd(ADC1, ENABLE);
154
155
  
156
  
157
//------------------------------------------------------------------
158
//-------- ADC1 Init
159
//------------------------------------------------------------------
160
  /* Initialize ADC structure */
161
  ADC_StructInit(&ADC_InitStructure);
162
163
  /* Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits  */
164
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;            //Res = 12bit
165
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
166
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
167
  ADC_InitStructure.ADC_ExternalTrigConv =  ADC_ExternalTrigConv_T15_TRGO;
168
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;            //Daten rechtsbündig (bis 11 bis 0)
169
  ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;        //Scannt CH 0 -> 18
170
  ADC_Init(ADC1, &ADC_InitStructure);
171
172
  /* Convert the ADC1 temperature sensor (ADC_IN16)  with 1.5 Cycles as sampling time */
173
  ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor , ADC_SampleTime_1_5Cycles);
174
  ADC_TempSensorCmd(ENABLE);
175
176
  /* Convert the ADC1 Vref (ADC_IN17) with 1.5 Cycles as sampling time -> 1MSa*/
177
  ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint , ADC_SampleTime_1_5Cycles);
178
  ADC_VrefintCmd(ENABLE);
179
180
  /* Convert the ADC Channel 10 with 1.5 Cycles as sampling time -> 1MSa*/
181
  ADC_ChannelConfig(ADC1, ADC_Channel_10 , ADC_SampleTime_1_5Cycles);
182
  /* Convert the ADC Channel 11 with 1.5 Cycles as sampling time -> 1MSa*/
183
  ADC_ChannelConfig(ADC1, ADC_Channel_11 , ADC_SampleTime_1_5Cycles);
184
  /* Convert the ADC Channel 12 with 1.5 Cycles as sampling time -> 1MSa*/
185
  ADC_ChannelConfig(ADC1, ADC_Channel_12 , ADC_SampleTime_1_5Cycles);
186
  /* Convert the ADC Channel 13 with 1.5 Cycles as sampling time -> 1MSa*/
187
  ADC_ChannelConfig(ADC1, ADC_Channel_13 , ADC_SampleTime_1_5Cycles);
188
189
190
  /* ADC Calibration */
191
  ADC_GetCalibrationFactor(ADC1);
192
193
  /* Enable ADC1 */
194
  ADC_Cmd(ADC1, ENABLE);
195
196
  /* Wait the ADCEN falg */
197
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));
198
199
  /* ADC1 regular Software Start Conv */
200
  ADC_StartOfConversion(ADC1);
201
202
203
204
//------------------------------------------------------------------
205
//-------- TIM15 Init
206
//------------------------------------------------------------------
207
  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);
208
209
  /* Time base configuration */
210
  TIM_TimeBaseStructure.TIM_Period = (SystemCoreClock / 10000 ) - 1; //10KHz
211
  TIM_TimeBaseStructure.TIM_Prescaler = 0x0;
212
  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;
213
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
214
  TIM_TimeBaseInit(TIM15, &TIM_TimeBaseStructure);
215
216
  /* TIM15 enable counter */
217
  TIM_Cmd(TIM15, ENABLE);
218
  /* TIM15 enable Trigger Output */
219
  TIM_SelectOutputTrigger(TIM15, TIM_TRGOSource_Update);
220
}
221
222
/**
223
  * @brief  Inserts a delay time.
224
  * @param  nTime: specifies the delay time length, in milliseconds.
225
  * @retval None
226
  */
227
void Delay(uint32_t nTime)
228
{
229
  TimingDelay = nTime;
230
231
  while(TimingDelay != 0);
232
}
233
/**
234
  * @brief  ADC1 channel with DMA configuration
235
  * @param  None
236
  * @retval None
237
  */
238
239
240
241
/**
242
  * @brief  Decrements the TimingDelay variable.
243
  * @param  None
244
  * @retval None
245
  */
246
void TimingDelay_Decrement(void)
247
{
248
  if (TimingDelay != 0x00)
249
  {
250
    TimingDelay--;
251
  }
252
}
253
254
255
#ifdef  USE_FULL_ASSERT
256
257
/**
258
  * @brief  Reports the name of the source file and the source line number
259
  *         where the assert_param error has occurred.
260
  * @param  file: pointer to the source file name
261
  * @param  line: assert_param error line source number
262
  * @retval None
263
  */
264
void assert_failed(uint8_t* file, uint32_t line)
265
{
266
  /* User can add his own implementation to report the file name and line number,
267
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
268
269
  /* Infinite loop */
270
  while (1)
271
  {
272
  }
273
}
274
#endif

viel Spaß damit

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.