Forum: Mikrocontroller und Digitale Elektronik Stm32F4 - Output und Input Compare an einem Timer gleichzeitig?


von BaumelndesEi (Gast)


Lesenswert?

Hi,

ich hätte mal ne Frage. Ist es möglich bei einem Timer des Stm32f4 mit 4 
Channeln 2 Channel für Output Compare und 2 für Input Compare zu nutzen? 
Jeder Channel hat ja eigene Output Compare Register.

Und ich habe noch ein anderes Problem, ich versuche einen Pin zu Toggeln 
mit dem Stm32F4Discovery. An dem hängt sonst nichts anderes. Aber das 
einzige was ich bekomme, ist etweder 3,3V oder 0V. Abhänig vom 
Pullup-Widerstand.
1
void timer_init()
2
{
3
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE,ENABLE);
4
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1,ENABLE);
5
6
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource9,GPIO_AF_TIM1);
7
  GPIO_PinAFConfig(GPIOE,GPIO_PinSource11,GPIO_AF_TIM1);
8
9
  GPIO_InitTypeDef gpio;
10
  gpio.GPIO_Mode = GPIO_Mode_AF;
11
  gpio.GPIO_OType = GPIO_OType_PP;
12
  gpio.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_11;
13
  gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
14
  gpio.GPIO_Speed = GPIO_Speed_100MHz;
15
  GPIO_Init(GPIOE,&gpio);
16
17
  TIM_TimeBaseInitTypeDef tim;
18
  tim.TIM_ClockDivision = TIM_CKD_DIV4;
19
  tim.TIM_CounterMode = TIM_CounterMode_Up;
20
  tim.TIM_Period = 23040;
21
  tim.TIM_Prescaler = 41;
22
  tim.TIM_RepetitionCounter = 0x00;
23
  TIM_TimeBaseInit(TIM1,&tim);
24
25
26
  TIM_OCInitTypeDef oc;
27
  oc.TIM_OCMode = TIM_OCMode_Toggle;
28
29
  oc.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
30
  oc.TIM_OCNPolarity = TIM_OCNPolarity_Low;
31
  oc.TIM_OutputNState = TIM_OutputNState_Enable;
32
33
  oc.TIM_OCIdleState = TIM_OCIdleState_Set;
34
  oc.TIM_OCPolarity = TIM_OCNPolarity_High;
35
  oc.TIM_OutputState = TIM_OutputState_Enable;
36
37
  oc.TIM_Pulse = 4000;
38
  TIM_OC2Init(TIM1,&oc);
39
40
  TIM_ITConfig(TIM1,TIM_IT_CC1,ENABLE);
41
  TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
42
43
  NVIC_InitTypeDef nvic;
44
  nvic.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
45
  nvic.NVIC_IRQChannelCmd = ENABLE;
46
  nvic.NVIC_IRQChannelPreemptionPriority = 0xf0;
47
  nvic.NVIC_IRQChannelSubPriority = 0xf0;
48
  NVIC_Init(&nvic);
49
50
  nvic.NVIC_IRQChannel = TIM1_CC_IRQn;
51
  nvic.NVIC_IRQChannelCmd = ENABLE;
52
  nvic.NVIC_IRQChannelPreemptionPriority = 0xf0;
53
  nvic.NVIC_IRQChannelSubPriority = 0xf0;
54
  NVIC_Init(&nvic);
55
56
  TIM_Cmd(TIM1,ENABLE);
57
}
58
59
void TIM1_UP_TIM10_IRQHandler()
60
{
61
  if(TIM_GetITStatus(TIM1,TIM_IT_Update))
62
  {
63
    TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
64
    GPIO_ToggleBits(GPIOD,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
65
  }
66
}
67
68
void TIM1_CC_IRQHandler()
69
{
70
  if(TIM_GetITStatus(TIM1,TIM_IT_CC1))
71
  {
72
    TIM_ClearITPendingBit(TIM1,TIM_IT_CC1);
73
74
75
  }
76
}

Ich hoffe jemand kann mir helfen. Ich kann einfach keinen Fehler finden.

MfG
Baumeln

von Michael F. (startrekmichi)


Lesenswert?

> Ist es möglich bei einem Timer des Stm32f4 mit 4
> Channeln 2 Channel für Output Compare und 2 für Input Compare zu nutzen?
> Jeder Channel hat ja eigene Output Compare Register.
Ja, sollte gehen.

> Und ich habe noch ein anderes Problem, ich versuche einen Pin zu Toggeln
> mit dem Stm32F4Discovery. An dem hängt sonst nichts anderes. Aber das
> einzige was ich bekomme, ist etweder 3,3V oder 0V. Abhänig vom
> Pullup-Widerstand.
Nach dem Timer base-init fehlt ev was. Folgendes ist zwar für 4xPWM 
output, aber das dürfte ja ähnlich sein:
1
  TIM_OCStructInit(&timocinit);
2
  timocinit.TIM_OCIdleState = TIM_OCIdleState_Reset;
3
  timocinit.TIM_OCMode = TIM_OCMode_PWM1;
4
  timocinit.TIM_OCPolarity = TIM_OCPolarity_High;
5
  timocinit.TIM_OutputState = TIM_OutputState_Enable;
6
  timocinit.TIM_Pulse = 1500;
7
  TIM_OC1Init(RC_PWM_OUT_TIMER, &timocinit);
8
  TIM_OC2Init(RC_PWM_OUT_TIMER, &timocinit);
9
  TIM_OC3Init(RC_PWM_OUT_TIMER, &timocinit);
10
  TIM_OC4Init(RC_PWM_OUT_TIMER, &timocinit);
11
12
  TIM_OC1PreloadConfig(RC_PWM_OUT_TIMER, TIM_OCPreload_Enable);
13
  TIM_OC2PreloadConfig(RC_PWM_OUT_TIMER, TIM_OCPreload_Enable);
14
  TIM_OC3PreloadConfig(RC_PWM_OUT_TIMER, TIM_OCPreload_Enable);
15
  TIM_OC4PreloadConfig(RC_PWM_OUT_TIMER, TIM_OCPreload_Enable);
16
17
  TIM_ARRPreloadConfig(RC_PWM_OUT_TIMER, ENABLE);
18
  TIM_Cmd(RC_PWM_OUT_TIMER, ENABLE);

Und 0xf0 als Priorität im NVIC geht nicht, das Maximum ist 0x0f. 
Abgesehen davon werden die Pins, die du im IRQ setzt nicht 
initialisiert.

von BaumelndesEi (Gast)


Lesenswert?

Hi,

danke erstmal. Die Pins im Update Interrupt werden vorher initialisiert.
Die Interrupt Priorität hab ich geändert und meinen Code noch ergänzt. 
Ich habe das ganze auchnochmal auf Timer8 versucht, aber es funtzt 
einfach nicht. Das CC1 Interrupt wird ausgeführt, wie es soll, aber der 
Pins dazu Togglet nicht.
1
void timer_init()
2
{
3
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
4
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8,ENABLE);
5
6
  GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_TIM8);
7
  GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_TIM8);
8
9
  GPIO_InitTypeDef gpio;
10
  gpio.GPIO_Mode = GPIO_Mode_AF;
11
  gpio.GPIO_OType = GPIO_OType_PP;
12
  gpio.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
13
  gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
14
  gpio.GPIO_Speed = GPIO_Speed_100MHz;
15
  GPIO_Init(GPIOC,&gpio);
16
17
  TIM_TimeBaseInitTypeDef tim;
18
  tim.TIM_ClockDivision = TIM_CKD_DIV4;
19
  tim.TIM_CounterMode = TIM_CounterMode_Up;
20
  tim.TIM_Period = 23040;
21
  tim.TIM_Prescaler = 41;
22
  tim.TIM_RepetitionCounter = 0x00;
23
  TIM_TimeBaseInit(TIM8,&tim);
24
25
26
  TIM_OCInitTypeDef oc;
27
  TIM_OCStructInit(&oc);
28
  oc.TIM_OCIdleState = TIM_OCIdleState_Reset;
29
  oc.TIM_OCMode = TIM_OCMode_Toggle;
30
  oc.TIM_OCPolarity = TIM_OCPolarity_High;
31
  oc.TIM_OutputState = TIM_OutputState_Enable;
32
  oc.TIM_Pulse = 1500;
33
  TIM_OC1Init(TIM8,&oc);
34
35
  TIM_OC1PreloadConfig(TIM8, TIM_OCPreload_Enable);
36
37
  TIM_ARRPreloadConfig(TIM8, ENABLE);
38
39
  TIM_ITConfig(TIM8,TIM_IT_CC1,ENABLE);
40
  TIM_ITConfig(TIM8,TIM_IT_Update,ENABLE);
41
42
  NVIC_InitTypeDef nvic;
43
  nvic.NVIC_IRQChannel = TIM1_UP_TIM10_IRQn;
44
  nvic.NVIC_IRQChannelCmd = ENABLE;
45
  nvic.NVIC_IRQChannelPreemptionPriority = 0x00;
46
  nvic.NVIC_IRQChannelSubPriority = 0x00;
47
  NVIC_Init(&nvic);
48
49
  nvic.NVIC_IRQChannel = TIM8_CC_IRQn;
50
  nvic.NVIC_IRQChannelCmd = ENABLE;
51
  nvic.NVIC_IRQChannelPreemptionPriority = 0x00;
52
  nvic.NVIC_IRQChannelSubPriority = 0x00;
53
  NVIC_Init(&nvic);
54
55
  TIM_Cmd(TIM8,ENABLE);
56
}
57
58
void TIM1_UP_TIM10_IRQHandler()
59
{
60
  if(TIM_GetITStatus(TIM1,TIM_IT_Update))
61
  {
62
    TIM_ClearITPendingBit(TIM1,TIM_IT_Update);
63
    GPIO_ToggleBits(GPIOD,GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
64
  }
65
}
66
67
void TIM8_CC_IRQHandler()
68
{
69
  if(TIM_GetITStatus(TIM8,TIM_IT_CC1))
70
  {
71
    TIM_ClearITPendingBit(TIM8,TIM_IT_CC1);
72
73
74
  }
75
}

Hat vielelicht noch jemand einen Vorschlag?

MfG
Philipp

von BaumelndesEi (Gast)


Lesenswert?

Moin,

Ich habe den Code wieder auf Tim1 umgeschrieben und statt Output Compare 
mal Input capture probiert. Das funktioniert wunderbar an der Pins, also 
ein verschosseneer Pins ist dann eher unwahrscheinlich.

MfG
Philipp

von Ruphy .. (ruphy)


Lesenswert?

Probier ma mit Pull Up:
gpio.GPIO_PuPd.GPIO_PuPd = GPIO_PuPd_UP;
bei mir funkioniert es mit Pull Up.
hier ma meine Init:

  //Enable Pin - siehe µPC datasheet for the right Port -> TIM2 Ch1: 
PortA0
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
  GPIO_InitTypeDef GPIO_InitStructure;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5);

  //Time base Config
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);
  TIM_TimeBaseInitTypeDef TIM_TimebaseStructure;

  TIM_TimebaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;  // Time Base 
initialisieren
  TIM_TimebaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimebaseStructure.TIM_Prescaler= 1000-1; // 84MHz / 1000 = 84 kHz 
nach Prescaler
  TIM_TimebaseStructure.TIM_Period= 84000-1; //  84 khz /84000 = 1 Hz -> 
endg�ltige Updaterate des Timers
  TIM_TimebaseStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM5, &TIM_TimebaseStructure);


  //Output Compare Modus Config
  TIM_OCInitTypeDef TIM_OCStructure;

  TIM_OCStructure.TIM_OCMode=TIM_OCMode_Toggle;
  TIM_OCStructure.TIM_OutputState=TIM_OutputState_Enable;
  TIM_OCStructure.TIM_OCPolarity=TIM_OCPolarity_Low;
  TIM_OCStructure.TIM_Pulse = 0;
  TIM_OC1Init(TIM5, &TIM_OCStructure);            // TIM_OC1Init => 
Channel 1 aktivieren


  TIM_ITConfig(TIM5,TIM_IT_CC1,ENABLE); //enable Interrupt
  TIM_Cmd(TIM5,ENABLE); // timer starts


gruß

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.