STM32 Timer synchronisieren

OP #6488798
Lesenswert?

Hi,

ich möchte bei einem STM32F446RE Timer 1 und Timer 8 synchron laufen 
lassen. Als Trigger nehme ich dazu Timer 2.

Folgendes Setup:
Master: TIM2
- MSM bit gesetzt
- TRGO = Enable Bit (CNT_EN)

Slaves: TIM1, TIM8
- Salve Mode: Reset Mode
- Trigger Source: ITR1

Meine CubeMX-Konfiguration und die Auszüge aus AN4013 und dem Reference 
Manual, auf denen basierend ich meine Konfig erstellt habe sind im 
Anhang.

Ich nutze folgenden Code:
1
HAL_TIM_Base_Start(&htim2);
2
HAL_TIM_PWM_Start(&htim8, CH_LVL_1);
3
HAL_TIM_PWM_Start(&htim1, CH_LVL_2);

Die Idee dahinter: TIM2 generiert durch sein Enable-Bit das TRGO, das an 
ITR1 von TIM1 und TIM8 gelesen wird. Dadurch werden deren Enable-Bits 
zeitgleich gesetzt. HAL_TIM_PWM_Start(...) startet nur die Ausgabe der 
jeweiligen Kanäle; der Timer läuft bereits.

Leider sind die PWMs um 900 ns verschoben, das Counter-Enable-Bit wird 
also in Software gesetzt.

Was habe ich übersehen?
Vielen Dank für eure Tipps,

Traubensaft
Angehängte Dateien:
OP #6489038
Lesenswert?

Falls das missverständlich war: das PDF habe ich selbst erstellt; das 
sind nicht irgendwelche "Beispiele". Sie enthält die relevanten Auszüge 
der Herstellerdokumentation, sowie die Einstellungen die ich daraus für 
mein Projekt abgeleitet habe.

Anbei de Inhalt der tim.c-Datei, die CubeMX aus meinen Einstellungen 
generiert. In den Anhang packe ich die (ungetestete) main.c des 
Beispiels von ST aus dem Verzeichnis
1
\Repository\STM32Cube_FW_F4_V1.21.0\Projects\STM32446E_EVAL\Examples\TIM\TIM_ParallelSynchro\Src

1
/* Includes ------------------------------------------------------------------*/
2
#include "tim.h"
3

4
#include "gpio.h"
5

6
/* USER CODE BEGIN 0 */
7

8
/* USER CODE END 0 */
9

10
TIM_HandleTypeDef htim1;
11
TIM_HandleTypeDef htim2;
12
TIM_HandleTypeDef htim8;
13

14
/* TIM1 init function */
15
void MX_TIM1_Init(void)
16
{
17
  TIM_ClockConfigTypeDef sClockSourceConfig;
18
  TIM_SlaveConfigTypeDef sSlaveConfig;
19
  TIM_MasterConfigTypeDef sMasterConfig;
20
  TIM_OC_InitTypeDef sConfigOC;
21
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
22

23
  htim1.Instance = TIM1;
24
  htim1.Init.Prescaler = 0;
25
  htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
26
  htim1.Init.Period = 1199;
27
  htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
28
  htim1.Init.RepetitionCounter = 0;
29
  if (HAL_TIM_Base_Init(&htim1) != HAL_OK)
30
  {
31
    _Error_Handler(__FILE__, __LINE__);
32
  }
33

34
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
35
  if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK)
36
  {
37
    _Error_Handler(__FILE__, __LINE__);
38
  }
39

40
  if (HAL_TIM_PWM_Init(&htim1) != HAL_OK)
41
  {
42
    _Error_Handler(__FILE__, __LINE__);
43
  }
44

45
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
46
  sSlaveConfig.InputTrigger = TIM_TS_ITR1;
47
  if (HAL_TIM_SlaveConfigSynchronization(&htim1, &sSlaveConfig) != HAL_OK)
48
  {
49
    _Error_Handler(__FILE__, __LINE__);
50
  }
51

52
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
53
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
54
  if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK)
55
  {
56
    _Error_Handler(__FILE__, __LINE__);
57
  }
58

59
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
60
  sConfigOC.Pulse = 600;
61
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
62
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
63
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
64
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
65
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
66
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
67
  {
68
    _Error_Handler(__FILE__, __LINE__);
69
  }
70

71
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
72
  {
73
    _Error_Handler(__FILE__, __LINE__);
74
  }
75

76
  if (HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
77
  {
78
    _Error_Handler(__FILE__, __LINE__);
79
  }
80

81
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
82
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
83
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
84
  sBreakDeadTimeConfig.DeadTime = 0;
85
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
86
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
87
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
88
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim1, &sBreakDeadTimeConfig) != HAL_OK)
89
  {
90
    _Error_Handler(__FILE__, __LINE__);
91
  }
92

93
  HAL_TIM_MspPostInit(&htim1);
94

95
}
96
/* TIM2 init function */
97
void MX_TIM2_Init(void)
98
{
99
  TIM_ClockConfigTypeDef sClockSourceConfig;
100
  TIM_MasterConfigTypeDef sMasterConfig;
101

102
  htim2.Instance = TIM2;
103
  htim2.Init.Prescaler = 0;
104
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
105
  htim2.Init.Period = 0;
106
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
107
  if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
108
  {
109
    _Error_Handler(__FILE__, __LINE__);
110
  }
111

112
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
113
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
114
  {
115
    _Error_Handler(__FILE__, __LINE__);
116
  }
117

118
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_ENABLE;
119
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
120
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
121
  {
122
    _Error_Handler(__FILE__, __LINE__);
123
  }
124

125
}
126
/* TIM8 init function */
127
void MX_TIM8_Init(void)
128
{
129
  TIM_ClockConfigTypeDef sClockSourceConfig;
130
  TIM_SlaveConfigTypeDef sSlaveConfig;
131
  TIM_MasterConfigTypeDef sMasterConfig;
132
  TIM_OC_InitTypeDef sConfigOC;
133
  TIM_BreakDeadTimeConfigTypeDef sBreakDeadTimeConfig;
134

135
  htim8.Instance = TIM8;
136
  htim8.Init.Prescaler = 0;
137
  htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
138
  htim8.Init.Period = 1199;
139
  htim8.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
140
  htim8.Init.RepetitionCounter = 0;
141
  if (HAL_TIM_Base_Init(&htim8) != HAL_OK)
142
  {
143
    _Error_Handler(__FILE__, __LINE__);
144
  }
145

146
  sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
147
  if (HAL_TIM_ConfigClockSource(&htim8, &sClockSourceConfig) != HAL_OK)
148
  {
149
    _Error_Handler(__FILE__, __LINE__);
150
  }
151

152
  if (HAL_TIM_PWM_Init(&htim8) != HAL_OK)
153
  {
154
    _Error_Handler(__FILE__, __LINE__);
155
  }
156

157
  sSlaveConfig.SlaveMode = TIM_SLAVEMODE_RESET;
158
  sSlaveConfig.InputTrigger = TIM_TS_ITR1;
159
  if (HAL_TIM_SlaveConfigSynchronization(&htim8, &sSlaveConfig) != HAL_OK)
160
  {
161
    _Error_Handler(__FILE__, __LINE__);
162
  }
163

164
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
165
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
166
  if (HAL_TIMEx_MasterConfigSynchronization(&htim8, &sMasterConfig) != HAL_OK)
167
  {
168
    _Error_Handler(__FILE__, __LINE__);
169
  }
170

171
  sConfigOC.OCMode = TIM_OCMODE_PWM1;
172
  sConfigOC.Pulse = 600;
173
  sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
174
  sConfigOC.OCNPolarity = TIM_OCNPOLARITY_HIGH;
175
  sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
176
  sConfigOC.OCIdleState = TIM_OCIDLESTATE_RESET;
177
  sConfigOC.OCNIdleState = TIM_OCNIDLESTATE_RESET;
178
  if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_2) != HAL_OK)
179
  {
180
    _Error_Handler(__FILE__, __LINE__);
181
  }
182

183
  if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
184
  {
185
    _Error_Handler(__FILE__, __LINE__);
186
  }
187

188
  sConfigOC.Pulse = 0;
189
  if (HAL_TIM_PWM_ConfigChannel(&htim8, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
190
  {
191
    _Error_Handler(__FILE__, __LINE__);
192
  }
193

194
  sBreakDeadTimeConfig.OffStateRunMode = TIM_OSSR_DISABLE;
195
  sBreakDeadTimeConfig.OffStateIDLEMode = TIM_OSSI_DISABLE;
196
  sBreakDeadTimeConfig.LockLevel = TIM_LOCKLEVEL_OFF;
197
  sBreakDeadTimeConfig.DeadTime = 0;
198
  sBreakDeadTimeConfig.BreakState = TIM_BREAK_DISABLE;
199
  sBreakDeadTimeConfig.BreakPolarity = TIM_BREAKPOLARITY_HIGH;
200
  sBreakDeadTimeConfig.AutomaticOutput = TIM_AUTOMATICOUTPUT_DISABLE;
201
  if (HAL_TIMEx_ConfigBreakDeadTime(&htim8, &sBreakDeadTimeConfig) != HAL_OK)
202
  {
203
    _Error_Handler(__FILE__, __LINE__);
204
  }
205

206
  HAL_TIM_MspPostInit(&htim8);
207

208
}
209

210
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle)
211
{
212

213
  GPIO_InitTypeDef GPIO_InitStruct;
214
  if(tim_baseHandle->Instance==TIM1)
215
  {
216
    /* USER CODE BEGIN TIM1_MspInit 0 */
217

218
    /* USER CODE END TIM1_MspInit 0 */
219
    /* TIM1 clock enable */
220
    __HAL_RCC_TIM1_CLK_ENABLE();
221

222
    /**TIM1 GPIO Configuration    
223
    PA8     ------> TIM1_CH1 
224
     */
225
    GPIO_InitStruct.Pin = TIM1_CH1_Pin;
226
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
227
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
228
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
229
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
230
    HAL_GPIO_Init(TIM1_CH1_GPIO_Port, &GPIO_InitStruct);
231

232
    /* USER CODE BEGIN TIM1_MspInit 1 */
233

234
    /* USER CODE END TIM1_MspInit 1 */
235
  }
236
  else if(tim_baseHandle->Instance==TIM2)
237
  {
238
    /* USER CODE BEGIN TIM2_MspInit 0 */
239

240
    /* USER CODE END TIM2_MspInit 0 */
241
    /* TIM2 clock enable */
242
    __HAL_RCC_TIM2_CLK_ENABLE();
243
    /* USER CODE BEGIN TIM2_MspInit 1 */
244

245
    /* USER CODE END TIM2_MspInit 1 */
246
  }
247
  else if(tim_baseHandle->Instance==TIM8)
248
  {
249
    /* USER CODE BEGIN TIM8_MspInit 0 */
250

251
    /* USER CODE END TIM8_MspInit 0 */
252
    /* TIM8 clock enable */
253
    __HAL_RCC_TIM8_CLK_ENABLE();
254

255
    /**TIM8 GPIO Configuration    
256
    PC6     ------> TIM8_CH1 
257
     */
258
    GPIO_InitStruct.Pin = TIM8_CH1_Pin;
259
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
260
    GPIO_InitStruct.Pull = GPIO_PULLDOWN;
261
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
262
    GPIO_InitStruct.Alternate = GPIO_AF3_TIM8;
263
    HAL_GPIO_Init(TIM8_CH1_GPIO_Port, &GPIO_InitStruct);
264

265
    /* USER CODE BEGIN TIM8_MspInit 1 */
266

267
    /* USER CODE END TIM8_MspInit 1 */
268
  }
269
}
270
void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle)
271
{
272

273
  GPIO_InitTypeDef GPIO_InitStruct;
274
  if(timHandle->Instance==TIM1)
275
  {
276
    /* USER CODE BEGIN TIM1_MspPostInit 0 */
277

278
    /* USER CODE END TIM1_MspPostInit 0 */
279
    /**TIM1 GPIO Configuration    
280
    PA9     ------> TIM1_CH2
281
    PA10     ------> TIM1_CH3
282
    PA11     ------> TIM1_CH4 
283
     */
284
    GPIO_InitStruct.Pin = TIM1_CH2_PWM_LVL4_Pin|TIM1_CH3_PWM_LVL5_Pin|TIM1_CH4_PWM_LVL2_Pin;
285
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
286
    GPIO_InitStruct.Pull = GPIO_NOPULL;
287
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
288
    GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
289
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
290

291
    /* USER CODE BEGIN TIM1_MspPostInit 1 */
292

293
    /* USER CODE END TIM1_MspPostInit 1 */
294
  }
295
  else if(timHandle->Instance==TIM8)
296
  {
297
    /* USER CODE BEGIN TIM8_MspPostInit 0 */
298

299
    /* USER CODE END TIM8_MspPostInit 0 */
300

301
    /**TIM8 GPIO Configuration    
302
    PC7     ------> TIM8_CH2
303
    PC8     ------> TIM8_CH3
304
    PC9     ------> TIM8_CH4 
305
     */
306
    GPIO_InitStruct.Pin = TIM8_CH2_PWM_LVL3_Pin|TIM8_CH3_PWM_LVL1_Pin|TIM8_CH4_reserved_Pin;
307
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
308
    GPIO_InitStruct.Pull = GPIO_NOPULL;
309
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
310
    GPIO_InitStruct.Alternate = GPIO_AF3_TIM8;
311
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
312

313
    /* USER CODE BEGIN TIM8_MspPostInit 1 */
314

315
    /* USER CODE END TIM8_MspPostInit 1 */
316
  }
317

318
}
319

320
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle)
321
{
322

323
  if(tim_baseHandle->Instance==TIM1)
324
  {
325
    /* USER CODE BEGIN TIM1_MspDeInit 0 */
326

327
    /* USER CODE END TIM1_MspDeInit 0 */
328
    /* Peripheral clock disable */
329
    __HAL_RCC_TIM1_CLK_DISABLE();
330

331
    /**TIM1 GPIO Configuration    
332
    PA8     ------> TIM1_CH1
333
    PA9     ------> TIM1_CH2
334
    PA10     ------> TIM1_CH3
335
    PA11     ------> TIM1_CH4 
336
     */
337
    HAL_GPIO_DeInit(GPIOA, TIM1_CH1_Pin|TIM1_CH2_PWM_LVL4_Pin|TIM1_CH3_PWM_LVL5_Pin|TIM1_CH4_PWM_LVL2_Pin);
338

339
    /* USER CODE BEGIN TIM1_MspDeInit 1 */
340

341
    /* USER CODE END TIM1_MspDeInit 1 */
342
  }
343
  else if(tim_baseHandle->Instance==TIM2)
344
  {
345
    /* USER CODE BEGIN TIM2_MspDeInit 0 */
346

347
    /* USER CODE END TIM2_MspDeInit 0 */
348
    /* Peripheral clock disable */
349
    __HAL_RCC_TIM2_CLK_DISABLE();
350
    /* USER CODE BEGIN TIM2_MspDeInit 1 */
351

352
    /* USER CODE END TIM2_MspDeInit 1 */
353
  }
354
  else if(tim_baseHandle->Instance==TIM8)
355
  {
356
    /* USER CODE BEGIN TIM8_MspDeInit 0 */
357

358
    /* USER CODE END TIM8_MspDeInit 0 */
359
    /* Peripheral clock disable */
360
    __HAL_RCC_TIM8_CLK_DISABLE();
361

362
    /**TIM8 GPIO Configuration    
363
    PC6     ------> TIM8_CH1
364
    PC7     ------> TIM8_CH2
365
    PC8     ------> TIM8_CH3
366
    PC9     ------> TIM8_CH4 
367
     */
368
    HAL_GPIO_DeInit(GPIOC, TIM8_CH1_Pin|TIM8_CH2_PWM_LVL3_Pin|TIM8_CH3_PWM_LVL1_Pin|TIM8_CH4_reserved_Pin);
369

370
    /* USER CODE BEGIN TIM8_MspDeInit 1 */
371

372
    /* USER CODE END TIM8_MspDeInit 1 */
373
  }
374
} 
375

376
/* USER CODE BEGIN 1 */
377

378
/* USER CODE END 1 */
379

380
/**
381
 * @}
382
 */
383

384
/**
385
 * @}
386
 */
387

388
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Angehängte Dateien:
Gast #6489939
Lesenswert?

Mangels F446 habe ich angefangen alles auf einen F401 zu portieren.
Man muss ja erst einmal wissen, wie die Signale am Ende aussehen sollen.

Im Hinterkopf natürlich die eigentliche Frage und ob nicht noch eine 
andere Lösung möglich wäre.

Mit anderen Worten, das wurde mir zu viel Aufwand.

Vielleicht versucht sich noch einer daran, der einen F446 da hat.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren