Forum: Mikrocontroller und Digitale Elektronik STM32 PWM Input Mode Problem


von Flo (Gast)


Lesenswert?

Hallo zusammen,

versuche gerade eine PWM zu ermitteln
und der folgende mag nicht gehen...

Ich komme einfach nicht auf den Fehler

:
1
 
2
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
3
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
4
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO , ENABLE);



Einstellung des Timers und GPIOs
1
void TIM_IN_Configuration(void)
2
{
3
  GPIO_InitTypeDef GPIO_InitStructure;
4
  TIM_ICInitTypeDef TIM_ICInitStructure;
5
6
TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; 
7
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; 
8
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; 
9
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; 
10
TIM_ICInitStructure.TIM_ICFilter = 0x0;
11
12
TIM_ICInit(TIM2, &TIM_ICInitStructure);
13
14
15
TIM_PWMIConfig(TIM2, &TIM_ICInitStructure);
16
    
17
TIM_SelectInputTrigger(TIM2, TIM_TS_TI1FP1);  
18
19
     /* Select the slave Mode: Reset Mode */
20
TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
21
TIM_SelectMasterSlaveMode(TIM2,TIM_MasterSlaveMode_Enable);
22
23
TIM_Cmd(TIM2, ENABLE);
24
TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE); 
25
26
// TIM2 channel 2 pin (PA.01) configuration  
27
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; 
28
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
29
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
30
31
GPIO_Init(GPIOA, &GPIO_InitStructure);
32
33
}



1
   
2
   NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQChannel; 
3
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
4
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 
5
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
6
   NVIC_Init(&NVIC_InitStructure);




1
void TIM2_IRQHandler(void)
2
{
3
  if (TIM_GetITStatus(TIM2, TIM_IT_CC2) !=RESET)
4
  {
5
6
     /* Get the Input Capture value */
7
   IC2Value = TIM_GetCapture2(TIM2);
8
 
9
   if (IC2Value != 0)
10
   {
11
     /* Duty cycle computation */
12
     DutyCycle = (TIM_GetCapture1(TIM2) * 100) / IC2Value;
13
 
14
     /* Frequency computation */
15
     Frequency = 72000 / IC2Value;
16
   }
17
   else
18
   {
19
     DutyCycle = 0;
20
     Frequency = 0;
21
   }
22
       sendstring_usart("TIM2 Interrupt\n\r");
23
       countertim2++;
24
  TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
25
  }   
26
}

von Flo (Gast)


Lesenswert?

-_-

allen anschein nach,
nutzen das nicht sehr viele...

von Anschein (Gast)


Lesenswert?

>allen anschein nach, ....

.... bist Du nicht in der Lage, eine
vernünftige Fehlerbeschreibung zu formulieren.

>und der folgende mag nicht gehen...
>
>Ich komme einfach nicht auf den Fehler

Das ist jedenfalls keine.

- Was soll passieren?
- Was passiert stattdessen?
- Wie sieht Dein Versuchsaufbau aus?
- Wie sieht Dein main() aus?

Probier´s nochmal.

Anschein

von Anschein (Gast)


Lesenswert?

... ausserdem erscheint mir

> TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);

in der Config Routine

im Vergleich zu

>   if (TIM_GetITStatus(TIM2, TIM_IT_CC2) !=RESET)

oder

>   TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);

etwas merkwürdig.

Anschein.

von Matthias K. (matthiask)


Lesenswert?

Flo schrieb:
> versuche gerade eine PWM zu ermitteln
> und der folgende mag nicht gehen...

Was willst Du eigentlich machen?
[ ] Ein PWM Signal erzeugen.
[ ] Ein (PWM) Signal ausmessen.

von Flo (Gast)


Lesenswert?

so schuldigt, bin heute voll durch den wind

auch die beschreibung meines problems war müll.
habe soviel umher geschmissen, das ich nichts mehr erkannt habe.

nunja, es war tatsächlich dieses von anschein angesprochene problem -_-

wald... bäume ... und so :D

mir gings darum eine pwm zu messen...
nunja das geht irgendwie...

nunja, das pwm signal kommt von einem empfänger welches
man im RC Modell bereich nutzt...
es hat laut oszi 49,85Hz... und je nachdem wie man die steuerung tätigt, 
hat man eine größere pulsbreite oder weniger...

mein jetztiges problem ist ein mathematisches...
ich habe wie erwähnt einen grundpuls,
und möchte ab einer bestimmten breite,
eine bedingung einführen das zum motorstopp führt...

von wo weiß ich das verhältnis,
wie dutycycle zur periode steht...

z.b.
1
void TIM2_IRQHandler(void)
2
{
3
  if (TIM_GetITStatus(TIM2, TIM_IT_CC2) !=RESET)
4
  {
5
     /* Get the Input Capture value */
6
   IC2Value = TIM_GetCapture2(TIM2);
7
 
8
   if (IC2Value != 0)
9
   {
10
     /* Duty cycle computation */
11
     DutyCycle = (TIM_GetCapture1(TIM2) * 100) / IC2Value;
12
 
13
     /* Frequency computation */
14
     Frequency = 72000 / IC2Value;
15
   }
16
   else
17
   {
18
     DutyCycle = 0;
19
     Frequency = 0;
20
   }
21
       sendstring_usart("TIM2 Interrupt\n\r");
22
       countertim2++;
23
  TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
24
  } 
25
26
/*******************************************************/
27
// Start/Stopp
28
/*******************************************************/
29
30
if((DutyCycle > ???) && (DuryCycle < ????))  //<------
31
     {
32
      motorstopp();
33
      merker = 1;
34
     }
35
else if((DutyCycle > ?2?2?) && (DuryCycle < ?2?2?))  //<------
36
     {
37
      motorstopp();
38
      merker = 1;
39
     }
40
else
41
     {
42
        if(merker =1)
43
             {
44
              motorstart();
45
              merker = 0;
46
             }
47
       //motor ist an und wird weiterhin gefüttert 
48
     }
49
50
}



Ich weiß dass z.b. der Ruhezustand des Motors 1,4ms hat,
Min Breite 1,01ms und Max Breite 1,78ms

Also würde ich gerne von
(1,01 bis 1,3) oder (1,5 bis 1,78)
denn motor stoppen lassen

nur wie komme ich auf den wert?

z.B. (100/20) * den enstprechenden wert?

von RP6Conrad (Gast)


Lesenswert?

In diese Zeile wirden den Dutycycle berechnet :
 /* Duty cycle computation */
     DutyCycle = (TIM_GetCapture1(TIM2) * 100) / IC2Value;
Jetzt wird den Dutycycle in % bewertet. Das ist nich so gunstig da ein 
Servosignal ein Dutycycle hat zwischen 4 und 11% (von 0.8ms bis 2.2ms, 
periode 20 ms) . Ihre Auflosung ist damit relatif ungenau. Besser machen 
sie da eine andere Berechnung. Sie konne gleich die Werte von 
TIM_GetCapture1(TIM2) verwenden. Nur musst du wissen an welche Frequenz 
diese Zaehler lauft. Ich soll das so einstellen, das er genau an 1 MHz 
lauft. Damit wird die Pulsbreite sich bewegen zwischen 800µs und 2200µs. 
Eine komplette Periode von 20 ms ist dan 20000 µs, passt noch immer für 
ein 16 bit Timer.
Danaben siehe ich auch nog Syntaxfehler in die if(merker=0).Muss 
naturlich sein if(merker==0).

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.