Forum: Mikrocontroller und Digitale Elektronik STM32f103 Timer parallel synchroniseren


von OlliW (Gast)


Lesenswert?

Hallo Zusammen

ich möchte bei einem STM32F103RB die Tim2 und Tim3 zur PWM-Erzeugung 
nutzen, und sie gleichzeitig starten so dass sie perfekt synchron 
zueinander (parallel) laufen.

Leider wird dieser Fall im Referenzmanual und der Timer-AN nicht konkret 
diskutiert, und so habe ich mir etwas zusammengbaut was leider nicht 
ganz funktioniert.

Wichtig, ich verwende zusätzlich noch I2C, welches ich mit der 
CPAL_V1.2.0 Library von ST mache.

Infos zur Umgebung:
CooCox 1.7.5 und entsprechende gnu tools, Win7, ich benutze CMSIS, 
Hardware ist ein Olimex H103 mit STM32F103RB (72MHz).

Zu den Timer:
ClockDivision = TIM_CKD_DIV1, CounterMode = 
TIM_CounterMode_CenterAligned1, Period = 1024-1, TIM_Prescaler = 0.

Fehlerbeschreibung:
(1) Wenn ich nur I2C benutze dann funktioniert I2C perfekt.
(2) Benutze ich I2C und Tim2 und Tim3 OHNE der Synchroroutine, also wenn 
sie jeweils einfach mit TIM_Cmd(TIMx, ENABLE) gestartet wurden, dann 
funktioniert alles perfekt.
(3) Benutze ich I2C und Tim2 und Tim3 MIT der Synchroroutine, dann 
funktioniert auch alles perfekt solange ich NICHT die Timer Ausgänge 
durch Beschreiben der Register TIM2->CCER und TIM3->CCER einschalte.
(4) Sobald ich in diese Register schreibe hängt sich früher oder später 
(innerhalb weniger Sekunden) das I2C auf.

Ich bastel da jetzt echt schon eine ganze Weile dran rum, und konnte 
selber und im Netz nichts zu finden. In der Hoffnung das jemand Rat 
weis,
Olli

Anhang: Code Stücke
1
/*das ist die Problem Routine, nach deren Aufruf sich das I2c früher oder später aufhängt*/
2
void motors_onoff_update()
3
{
4
uint16_t tim2_ccer, tim3_ccer;
5
6
  tim2_ccer |= (uint16_t)(1 << 4) | (uint16_t)(1 << 8) | (uint16_t)(1 << 12);
7
  tim3_ccer |= (uint16_t)(1 << 0) | (uint16_t)(1 << 4) | (uint16_t)(1 << 8);
8
9
  TIM2->CCER =  tim2_ccer;
10
  TIM3->CCER =  tim3_ccer;
11
}
12
13
14
15
void timer_init(void)
16
{
17
GPIO_InitTypeDef  GPIO_InitStructure;
18
TIM_TimeBaseInitTypeDef TIM_TimeBase_InitStructure;
19
TIM_OCInitTypeDef TIM_OC_InitStructure;
20
21
  //Initialize clocks for TIM2, TIM3
22
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE);
23
24
  //Initialize clocks for GPIOA, GPIOB, AFIO
25
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
26
27
  //Configure pin TIM2 CH1-CH4 = PA0-PA3, TIM3 CH1-CH2 = PA6,PA7 as alternative function push-pull
28
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3  |  GPIO_Pin_6 | GPIO_Pin_7;
29
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
30
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
31
  GPIO_Init(GPIOA, &GPIO_InitStructure);
32
33
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
34
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
35
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
36
  GPIO_Init(GPIOB, &GPIO_InitStructure);
37
38
  //Configure TIM2, TIM3 time base
39
  TIM_TimeBase_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
40
  TIM_TimeBase_InitStructure.TIM_CounterMode = TIM_CounterMode_CenterAligned1;
41
  TIM_TimeBase_InitStructure.TIM_Period = 1024-1;  //11kHz with F100RB, 35kHz with F103RB
42
  TIM_TimeBase_InitStructure.TIM_Prescaler = 0;
43
44
  TIM_TimeBaseInit(TIM2, &TIM_TimeBase_InitStructure);
45
  TIM_TimeBaseInit(TIM3, &TIM_TimeBase_InitStructure);
46
47
  //Configure TIM2, TIM3 waveform
48
  TIM_OC_InitStructure.TIM_OCMode = TIM_OCMode_PWM1;
49
  TIM_OC_InitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
50
  TIM_OC_InitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
51
  TIM_OC_InitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
52
  TIM_OC_InitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
53
  TIM_OC_InitStructure.TIM_OutputState = TIM_OutputState_Disable;
54
  TIM_OC_InitStructure.TIM_OutputNState = TIM_OutputNState_Disable;
55
56
  TIM_OC_InitStructure.TIM_Pulse = 512;
57
  TIM_OC2Init(TIM2, &TIM_OC_InitStructure);
58
  TIM_OC3Init(TIM2, &TIM_OC_InitStructure);
59
  TIM_OC4Init(TIM2, &TIM_OC_InitStructure);
60
  TIM_OC1Init(TIM3, &TIM_OC_InitStructure);
61
  TIM_OC2Init(TIM3, &TIM_OC_InitStructure);
62
  TIM_OC3Init(TIM3, &TIM_OC_InitStructure);
63
64
/*so hängt sich das I2C irgenwann auf, siehe oben*/
65
  //Set Master/Slave such to synchronize both timers at enable
66
  TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Enable);
67
  TIM_SelectMasterSlaveMode(TIM2, TIM_MasterSlaveMode_Enable);
68
  TIM_SelectInputTrigger(TIM3, TIM_TS_ITR1);
69
  TIM_SelectSlaveMode(TIM3, TIM_SlaveMode_Trigger);
70
71
  TIM_Cmd(TIM2, ENABLE);
72
//  TIM_Cmd(TIM3, ENABLE); //is enabled by TIM2
73
74
/* würde man die vier Befehle zur Synchronisation nicht benutzen,
75
aber dafür TIM_Cmd(TIM3, ENABLE) dann funktioniert alles perfekt*/
76
}

von OlliW (Gast)


Lesenswert?

keiner eine Idee??

Wie, d.h. mit welchem Codestück, würdet Ihr zwei Timer synchron started?

thx

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.