Forum: Mikrocontroller und Digitale Elektronik [STM32F746VGT] ADC1 durch Timer triggern


von Michael (Gast)


Lesenswert?

Hallo,

ich habe bei oben genanntem Controller folgendes Problem:

Ich verwende ADC1 um analoge Werte zu Samplen und diese per DMA in den 
Speicher zu schreiben. Um eine konstante Abtastrate zu erreichen, 
aktiviere ich die ADC-Conversion durch einen Timer. Wenn ich hierzu den 
TIM8 hernehme (das Signal heißt dann ADC_EXTERNALTRIGCONV_T8_TRGO), 
funktioniert alles super!

Leider benötige ich TIM8 für eine andere Funktion, und Timer 1,2,3,4 
sind auch schon belegt. Bleibt noch TIM5 & TIM6, diese sind laut 
Connection Matrix auch dafür ausgelegt.

Doch egal welchen der beiden Timern ich verwende, der ADC springt nicht 
an, mit TIM8 jedoch schon.
Dabei konfiguriere ich alle Timer (5, 6 oder 8) identisch und weise 
ihnen jeweils durch
1
sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
2
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
3
4
if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
5
{
6
    Error_Handler();
7
}

das Update-Event als Trigger Output zu. Im Debug-Modus sehe ich auch, 
dass alle 3 Timer laufen, da das CNT Register sich ändert.

Die im ADC Setup verwendeten Trigger lauten:
1
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T5_TRGO;

oder
1
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T6_TRGO;

oder
1
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T8_TRGO;


Was habe ich übersehen?

von Michael (Gast)


Lesenswert?

Hier noch die Init-Routinen am Beispiel TIM5:

ADC (relevanter Teil):
1
ADC_ChannelConfTypeDef sConfig = {0};
2
3
  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */
4
  hadc1.Instance = ADC1;
5
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; //25MHz ADC clock
6
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
7
  hadc1.Init.ScanConvMode = ENABLE; // scan through all channels sequentially
8
  hadc1.Init.ContinuousConvMode = DISABLE; // adc is triggered from TIM5 for each scan conversion
9
  hadc1.Init.DiscontinuousConvMode = DISABLE;
10
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
11
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T5_TRGO;
12
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
13
  hadc1.Init.NbrOfConversion = AN_NUM_CHANNELS;
14
  hadc1.Init.DMAContinuousRequests = ENABLE;
15
  hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
16
17
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
18
  {
19
    Error_Handler();
20
  }

TIM5:
1
TIM_MasterConfigTypeDef sMasterConfig = {0};
2
3
  /* TIM5 runns with SYSCLK / 2 = 100 MHz */
4
  htim5.Instance = TIM5;
5
  htim5.Init.Prescaler = 10 - 1; // results in 10MHz tick
6
  htim5.Init.CounterMode = TIM_COUNTERMODE_UP;
7
  htim5.Init.Period = (uint16_t)((10000000 / AN_SAMPLERATE) - 1);
8
  htim5.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
9
  htim5.Init.RepetitionCounter = 0;
10
  htim5.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
11
12
  if (HAL_TIM_Base_Init(&htim5) != HAL_OK)
13
  {
14
    Error_Handler();
15
  }
16
17
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE;
18
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
19
20
  if (HAL_TIMEx_MasterConfigSynchronization(&htim5, &sMasterConfig) != HAL_OK)
21
  {
22
    Error_Handler();
23
  }

von Michael (Gast)


Lesenswert?

Also ich habe die Lösung mittlerweile selber rausgefunden und möchte Sie 
hier kurz erwähnen, falls jemand ähnliche Probleme hat.

Wenn man mehrere Stunden an einem derart unplausiblen Problem sitzt 
hilft am Ende nur der Blick ins Errata Sheet, und siehe da:
1
2.2.1 Missed ADC triggers from TIM1/TIM8, TIM2/TIM5/TIM4/TIM6/TRGO or
2
TGRO2 event
3
4
Description
5
6
The ADC external triggers for regular and injected channels by the TIM1, TIM8, TIM2, TIM5, TIM4 and TIM6 TRGO or TRGO2 events are missed at the following conditions:
7
8
• Prescaler enabled on the PCLK2 clock.
9
• TIMxCLK = 2xADCCLK and the master mode selection (MMS or MMS2 bits in the
10
TIMx_CR2 timer register) as reset, update, or compare pulse configuration.
11
• TIMxCLK = 4xADCCLK.
12
13
Workarounds
14
15
• For TIM1 and TIM8 TRGO or TRGO 2 events: select the trigger detection on both the
16
rising and falling edges. The EXTEN[1:0] or JEXTEN[1:0] bits must be set to 0x11 in
17
the ADC_CR2 register.
18
• For TIM2/TIM4/TIM5/TIM6/ TRGO or TGRO2 events: enable the DAC peripheral clock
19
in the RCC_APB1ENR register.

Ich benutze den DAC zwar nicht, trotzdem füge ich folgende Zeile Code 
hinzu:
1
__HAL_RCC_DAC_CLK_ENABLE();

Und siehe da, alles klappt! Und dass mir jetzt keiner kommt und meint 
das wäre naheliegend!
Trotzdem Danke and die, die gegrübelt haben...

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.