stm32f4discovery PWM InputMode (DutyCycle und Frequenz)

OP #2790735
Lesenswert?

Hallo zusammen,

ich versuche gerade PWM Signal(Frequenzbereich 100-1000 HZ) auszuwerten. 
Um zu testen, schließe ich ein Signalgenerator an. Ich benutze das 
offizielle Beispiel(PWM-Input),im Debugmode versuchte ich Schritt für 
Schritt, aber habe leider nicht die richtigen Werte von DutyCycle und 
Frequenz ermittelt. Jeder Versuch bekam ich ein verschiedenes Ergebnis. 
Ich habe schon viel Zeit damit verbracht, um den Fehler zu finden. Aber 
zur Zeit noch keine Ahnung, wo der Fehler liegt. Ich weiss nicht, ob ich 
irgendwo nicht richtig programmierte. Kann mir jemand helfen? Ich 
bedanke mich im Voraus.

Mfg
Kevin

int main(void)
{
  /* TIM Configuration */
  TIM_Config();
/* TIM4 configuration: PWM Input mode ------------------------
     The external signal is connected to TIM4 CH2 pin (PB.07),
     The Rising edge is used as active edge,
     The TIM4 CCR2 is used to compute the frequency value
     The TIM4 CCR1 is used to compute the duty cycle value
  ------------------------------------------------------------ */
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0;

  TIM_PWMIConfig(TIM4, &TIM_ICInitStructure);

  /* Select the TIM4 Input Trigger: TI2FP2 */
  TIM_SelectInputTrigger(TIM4, TIM_TS_TI2FP2);

  /* Select the slave Mode: Reset Mode */
  TIM_SelectSlaveMode(TIM4, TIM_SlaveMode_Reset);
  TIM_SelectMasterSlaveMode(TIM4,TIM_MasterSlaveMode_Enable);

  /* TIM enable counter */
  TIM_Cmd(TIM4, ENABLE);

  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM4, TIM_IT_CC2, ENABLE);

  while (1);
}

void TIM_Config(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  /* TIM4 clock enable */
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

  /* GPIOB clock enable */
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

  /* TIM4 chennel2 configuration : PB.07 */
  GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP ;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  /* Connect TIM pin to AF2 */
  GPIO_PinAFConfig(GPIOB, GPIO_PinSource7, GPIO_AF_TIM4);

  /* Enable the TIM4 global Interrupt */
  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

}


void TIM4_IRQHandler(void)
{
  RCC_ClocksTypeDef RCC_Clocks;
  RCC_GetClocksFreq(&RCC_Clocks);

  /* Clear TIM4 Capture compare interrupt pending bit */
  TIM_ClearITPendingBit(TIM4, TIM_IT_CC2);

  /* Get the Input Capture value */
  IC2Value = TIM_GetCapture2(TIM4);

  if (IC2Value != 0)
  {
    /* Duty cycle computation */
    DutyCycle = (TIM_GetCapture1(TIM4) * 100) / IC2Value;

    /* Frequency computation
       TIM4 counter clock = (RCC_Clocks.HCLK_Frequency)/2 */

    Frequency = (RCC_Clocks.HCLK_Frequency)/2 / IC2Value;
  }
  else
  {
    DutyCycle = 0;
    Frequency = 0;
  }
}
Gast #2791205
Lesenswert?

Ob das while so läuft....  nimm lieber while(1) {;}

Welche Entwicklungsumgebung?

system_init(); fehlt auch. Dein F4 läuft mit irgendeiner Frequenz.

Deine HSE Quarz Konfiguration stimmt sicher auch nicht.
Gast #2791224
Lesenswert?

Bist Du Dir sicher, dass es nicht geht ?
Wenn Du mit dem Debugger Schritt für Schritt durchgehst, dann hältst Du 
den Timer ja immer an, und damit stimmt die Messung nicht mehr.

Geht auch dann noch schief, wenn Du den Debugger laufen lässt, dann auf 
Pause drückst und dann die Ergebnisse anschaust ?
OP #2791257
Lesenswert?

Hallo Hans,

Dank für Deine Antwort. Ich benutze Coocox unter WindowsXP. Habe 
system_init() versucht, aber geht's auch nicht. Mein F4 läuft mit 168M 
Hz Frequenz, ich habe Frequenz des Timers nicht eingesetzt. Dann läuft 
Counter mit 84M Hz. Ich versuche die Frequenz des Signals mit 100 bis 
1000 Hz auszumessen.
könntest du mir sagen, wie kann ich "HSE Quarz" konfigurieren? Ich habe 
das offizielle Beispiel gesehen, aber diese Konfiguration wurde nicht 
macht. Sollte man selbst noch mal einsetzen?

MfG
Kevin
Gast #2791369
Lesenswert?

Sieh dir die Datei "system_stm32f4xx.c" im coocox "cmsis.boot/startup" 
Ordner an. Am Anfang stehen die verwendeten Einstellungen.
Mit dem angehängten Excel sheet mußt du dir deinen Sys Clock unbedingt
konfigurieren. Dieses sheet erzeigt dir diese Datei mit deinen 
Einstellungen. Dann musst du diese mit der von Coocox verwendeten 
austauschen.

"The default value of HSE crystal is set to 25MHz, refer to "HSE_VALUE" 
definein "stm32f4xx.h" file. When HSE is used as system clock source, 
directly or through PLL, and you are using different crystal you have to 
adapt the HSE value to your own configuration."

HSE musst du aber trotzdem noch händisch in "stm32f4xx.h" ändern (dein 
verw. Quarz ( 8 MHZ ! hoffentlich)


Grüße Hans
Angehängte Dateien:
OP #2791536
Lesenswert?

Hallo Hans,
ich habe gerade die Einstellung in der Datei "system_stm32f4xx.c" 
gesehen.
System Clock source: PLL (HSE)
SYSCLK(Hz): 64000000
HSE Frequency(Hz): 8000000
und in der Datei"stm32f4xx.h" schreibt auch
"#if !defined  (HSE_VALUE)
 #define HSE_VALUE    ((uint32_t)8000000)"
Es ist schon richtig konfiguriert, oder?

Kann es sein, dass Counter Frequenz so hoch ist, dass jedes Mal CCR1 und 
CCR2 überläufen?
Angehängte Dateien:
OP #2791551
Lesenswert?

Hallo Flix und Holger,

ja, ich bin ganz sicher, ich habe viel mal versucht. Aber ich machte so, 
setzte ein Breakpoint hinter dem Befehl " Frequency = 
(RCC_Clocks.HCLK_Frequency)/2 / IC2Value;" Ich glaube, wenn ich hier 
setzte, wird das Ergebnis nicht beeinflusst, oder? naja, vermute ich, 
bin nicht sicher.

MgG
Kevin
Gast #2791561
Lesenswert?

Dein Timer 4 läüft zu schnell. Der schafft nur 36 MHz! Und lass das 
debuggen
über Coocox. Debugge lieber über die Uart. Und schau, ob dein Interrupt 
aufgerufen wird (ZB Byte setzen und dann über Uart Variable ausgeben)Und 
behalte dein PWM Signal mit einem Osci im Auge, ob es konstant läuft.


Gruß
Gast #2791573
Lesenswert?

Kann ich so leider nicht so sagen.

Bräuchte Infos über den Code und das System. Schreibe dir ein kleines
Betriebssystemchen, dass dich über den Status deines F4 informiert (beim 
booten, RCC Flags ausgeben. ZB LSE,LSI,HSI,HSE, Clock Fr. usw.)

Lass dir die Frequenz deines Timers auf einem Pin ausgeben um sie zu 
messen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren