Forum: Mikrocontroller und Digitale Elektronik Knifflige Timer-Verschaltung bei STM32 - wer hat den Durchblick?


von Robert B. (robertb)


Lesenswert?

Hallo!

Ich möchte mit dem TIM3 OC1 einen Bitstrom generieren, welcher durch 
einen zweiten Timer (TIM1 mit OC1) eingeschaltet werden kann. 
Ausgeschaltet wird der Bitstrom durch das Compare-Match-Interrupts OC2 
des TIM3 (der zählt quasi mit und stoppt den TIM3 nach einer wechselnden 
Anzahl von Bits).

Gebraucht wird also:

TIM1-OC1: _________|--------|__________________|----------|___________
TIM3-OC1: _________|-|_|-|_|-|_|-|_|-|_________|-|_|-|_|-|_|-|________
nur als Hilfe:
TIM3-OC2: __________|___|___|___|___|___________|___|___|___|________
TIM3-CEN: _________###################_________###############_________

Folgender Auszug aus Main:
1
  /* Compute the prescaler value */
2
  PrescalerValue = (uint16_t) (SystemCoreClock / (1000*1000)) - 1;    /* TIM3 Peripheral Configuration ----------------------------------------*/
3
  /* Time base configuration */
4
  TIM_TimeBaseStructure.TIM_Period = 300-1;    TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
5
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
6
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
7
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
8
  
9
  TIM_ARRPreloadConfig(TIM3, ENABLE);
10
  
11
  /* Output Compare Active Mode configuration: Channel1 */
12
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
13
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
14
  TIM_OCInitStructure.TIM_Pulse = 100;
15
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
16
  TIM_OC1Init(TIM3, &TIM_OCInitStructure);
17
  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  // important to make pulse change in NEXT period
18
19
  /* Output Compare Active Mode configuration: Channel2 */
20
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
21
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
22
  TIM_OCInitStructure.TIM_Pulse = 20;
23
  TIM_OC2Init(TIM3, &TIM_OCInitStructure);
24
  TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Disable);
25
26
  /* Output Compare Active Mode configuration: Channel3 */
27
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
28
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
29
  TIM_OCInitStructure.TIM_Pulse = 150;
30
  TIM_OC3Init(TIM3, &TIM_OCInitStructure);
31
  TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Disable);
32
33
//  TIM_UpdateRequestConfig(TIM3, TIM_UpdateSource_Regular);  // avoid 
34
//  TIM_UpdateDisableConfig(TIM3, ENABLE);
35
  
36
  /* Slave Mode selection: TIM3 */
37
  TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Trigger);
38
//  TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Reset);
39
  TIM_SelectInputTrigger(TIM3, TIM_TS_ITR0);
40
41
  /* TIM IT enable */
42
  TIM_ITConfig(TIM3, TIM_IT_CC2, ENABLE);
43
44
//  TIM_GenerateEvent(TIM3, TIM_EventSource_Update);
45
  
46
47
  /* TIM1 Peripheral Configuration ----------------------------------------*/
48
  /* Time Base configuration */
49
  PrescalerValue = (uint16_t) (SystemCoreClock / (1000*1000)) - 1;  // 1MHz
50
  TIM_TimeBaseStructure.TIM_Period = 20000-1;
51
  TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
52
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
53
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
54
  TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
55
  
56
  TIM_ARRPreloadConfig(TIM1, ENABLE);
57
  
58
  /* Channel 1 Configuration in PWM mode */
59
  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
60
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
61
  TIM_OCInitStructure.TIM_Pulse = 10000;
62
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
63
  TIM_OC1Init(TIM1, &TIM_OCInitStructure);
64
  TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Disable);
65
    
66
  /* Master Mode selection */
67
  TIM_SelectOutputTrigger(TIM1, TIM_TRGOSource_OC1Ref);
68
  /* Select the Master Slave Mode */
69
  TIM_SelectMasterSlaveMode(TIM1, TIM_MasterSlaveMode_Enable);
70
71
  TIM_CtrlPWMOutputs(TIM1, ENABLE); 
72
73
  /* TIM1 counter enable */
74
  TIM_Cmd(TIM1, ENABLE);
75
76
  /* TIM1 counter enable */
77
  TIM_Cmd(TIM3, ENABLE);

Das restliche Programm manupuliert die Timer nicht, außer dass das TIM3 
OC1 Interrupt den TIM nach einer gewissen Zeit ausschaltet.

PROBLEM:

Grundsätzlich funktioniert die Triggerung. Allerdings bekomme ich es 
nicht hin dass mit der (testweise) ausgegebenen steigenden Flanke von 
TIM1 OC1 auch TIM3 OC1 high wird. Vielmehr dauert es noch fast eine 
TIM3-Periode bis TIM3-OC1 TIM1-OC1 folgt und die Sequenz ausgegeben 
wird. Die Verspätung entsteht weil ich TIM3 ja ausschalte und mit 
"undefinierten" Zählerstand belasse bis der nächste Trigger durch 
TIM1-OC1 ausgelöst wird. Absolut passend wäre es statt "Trigger Mode" 
den "Reset Mode" zu verwenden, welcher dann auch den TIM3 Zähler 
resetten würde. Jedoch funktioniert dann gar nicht mehr weil wohl die 
gesamte? Timer-Konfiguration resettet wird. Ein Einschalten des "Update 
disable"-Bits (UDIS) bzw. ein Eingrenzen des Updates mit dem "Update 
request source"-Bit (URS) brachte auch nicht das gewünschte Ergebnis. 
Ein weiterer Versuch war es, den TIM3 nicht per CEN auszuschalten 
sondern per One-Pulse-Mode in einem definierten Zustand abzuschalten. 
Leider wechselt dann der TIM3-OC1 Ausgang mit dem letzten Zähltakt von 
TIM3 auf high, was für mich völlig unbrauchbar ist.

Hat jemand noch einen Tipp?

Über Vorschläge wäre ich sehr sehr dankbar!

Grüße
Robert

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.