mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32 Timer Interrupt Priority


Autor: Mark W. (mark_wer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich komme grad nicht wirklich weiter und würde mich über eure Hilfe 
freuen. Ich hätte gern zwei seperate Interrupt Handler für OVF und 
Capture Interrupt mit verschiedenen Prioritäten. Im meinem Beispiel Code 
wird ja der Handler bei beiden aufgerufen und dann geprüft, welche Flag 
gesetzt wurde. Könnte man das auch in zwei seperaten Interrupts machen 
und bräuchte ich dafür TIM1 (nur bei dem gibts's anscheinend den Capture 
Handler)? Und wie genau funktioniert beim CaptureInterrupt der Filter, 
also was macht 0x01, 0x02 usw. für einen Unterschied, habe dazu bisher 
noch nichts gefunden.
void Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  TIM_ICInitTypeDef TIM_ICInitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

  // Clock Enable
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

  // Clock enable
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

  // Config des Pins PA1 als AF-Input
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  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_NOPULL;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  // Alternative-Funktion mit dem IO-Pin PA1 verbinden
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource1, GPIO_AF_TIM2);

  TIM_TimeBaseStructure.TIM_Period = 0xFFFF;
  TIM_TimeBaseStructure.TIM_Prescaler = 0;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  // Vorteiler einstellen (Vorteiler von 167 => 1MHz)
  TIM_PrescalerConfig(TIM2, 0, TIM_PSCReloadMode_Immediate);

  // Channel 2
  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Falling;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0;
  TIM_ICInit(TIM2, &TIM_ICInitStructure);

  // Timer enable
  TIM_Cmd(TIM2, ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

  //Interrupt Enable
  TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
}


//-----------------------
// TIM2 Interrupt Handler
//-----------------------

void TIM2_IRQHandler(void)
{

  // Überprüfen ob Overflow-Flag gesetzt wurde
  if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
  {
    // delete Interrupt Flags
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
    //Funktion
    }
  }

  // Überprüfung ob Capture-Flag gesetzt wurde
  if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET)
  {
    // delete Interrupt Flags
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
    //Funktion
  }
}

PS: Ich verwende USB-CDC-Kommunikation, die soweit auch läuft. Ich würde 
aber gern den Timer auf einer Frequenz laufen lassen, für die ich den 
CPU-Takt etwas runtertakten müsste, um einen ganzzahligen Prescaler zu 
erhalten, könnte dieses runtertakten zu Problemen mit der 
USB-Kommikation führen (Library baut auf der von ST auf)

Autor: Mark W. (mark_wer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Okay, könnte die meisten Probleme jetzt lösen, aber eine Frage bleibt 
noch, wo ich nirgends eine Antwort finde: Was bewirken verschiedene 
Werte bei TIM_ICFilter? Würde mich sehr über eure Hilfe freuen :) Schon 
mal danke und einen schönen Start in die Woche.

Autor: Christopher J. (christopher_j23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist ein digitaler Filter, den man z.B. zum digitalen entprellen 
hernehmen kann. Man beeinflusst damit die Abtastfrequenz (gewissermaßen 
ein zusätzlicher Prescaler) und kann zusätzlich noch einstellen wie 
viele aufeinander folgende Events erst den Interrupt auslösen. Einfach 
mal im passenden RefMan in die Doku vom "capture/compare mode register" 
des entsprechenden Timers schauen.

Autor: Mark W. (mark_wer)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die Hilfe, jetzt habe ich es gefunden :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.