STM32: Timer reseten

OP #2274649
Lesenswert?

Hi,

ich habe folgendes Problem:

Per EXTI empfange ich von einem Client Daten. Wenn dieser keine mehr 
hat, hält der einfach seine Clock an.

Ich hab mir nun gedacht, nimm nen Timer, der bei jedem ankommenden 
Signal auf 0 zurückgesetzt wird, so dass der Timer IRQ nur dann 
ausgelöst wird, wenn der Abstant zwischen zwei Signalen größer ist als 
das Timerinterval.

So weit so schön, aber obwohl ich bei jeder ankommenden Flanke

  TIM_SetCounter(TIM2, 0);

mache, schert sich der Timer keinen Deut drum und löst stur in seinem 
Interval den Interrupt aus.

Oder muss man den Timer auf eine andere Art zurücksetzen?

Gruß
Thomas
Gast #2276200
Lesenswert?

Also eigentlich sollte das mit TIM_SetCounter() schon funktionieren. Ich 
bin mir aber nicht sicher, ob das beschreiben des CNT registers nicht 
auch einen Update IRQ auslöst...

Die "richtige" Art, den Counter rückzusetzen wäre über das UG Bit im EGR 
register, denn dabei wird auch der Prescaler zurückgesetzt. Allerdings 
hat letzteres nur ernsthafte Auswirkungen, wenn Du mit einem großen 
Prescaler und kleinem Reload Wert arbeitest.

Aber Achtung: Beim Rücksetzen über UG wird definitiv ein Update IRQ 
ausgelöst. Also am besten vorher abschalten.
OP #2276815
Lesenswert?

Ok, dann kommt hier der code

Initiallisierung von Timer und ETXI IRQs
1
// Timer to detect if transponder was removed    
2
#define TIMER_TAKT 10000                                            /* Timer wird mit 10kHz getaktet */
3
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
4
  uint16_t PrescalerValue;
5

6
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);              // TIMER 2 Takt freigeben
7

8
  PrescalerValue = (uint16_t) (SystemCoreClock / TIMER_TAKT) - 1;   // Vorteiler berechnen
9

10
  // Timer Grundkonfiguration
11
  TIM_TimeBaseStructure.TIM_Period = 100;                         // Timer zählt von 0 ... 100: also alle 10ms
12
  TIM_TimeBaseStructure.TIM_Prescaler = PrescalerValue;
13
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
14
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
15
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);                   // Timer einstellen
16

17
  //Timer Vorteiler-Taktkonfiguration
18
  TIM_PrescalerConfig(TIM2, PrescalerValue, TIM_PSCReloadMode_Immediate); // Auto-Reload
19

20
  
21
  // Timer aktivieren
22
  TIM_Cmd(TIM2, ENABLE);
23
  
24
  NVIC_InitTypeDef NVIC_InitStructure;
25
 /* Enable the Interrupt */
26
  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
27
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
28
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
29
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
30
  NVIC_Init(&NVIC_InitStructure);
31

32
  TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
33
  
34
  
35
  //Init IRQ for MLX90109
36
  RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;                     // enable clock for Alternate Function
37
  AFIO->EXTICR[2] &= 0xFFF0;            //clear used pin
38
  AFIO->EXTICR[2] |= (0x00);           // set pin 8 PORT A
39

40

41

42
  EXTI_InitTypeDef EXTI_InitStructure;
43
  EXTI_InitStructure.EXTI_Line= EXTI_Line8;
44
  EXTI_InitStructure.EXTI_Mode= EXTI_Mode_Interrupt;
45
  EXTI_InitStructure.EXTI_Trigger= EXTI_Trigger_Falling;
46
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
47
  EXTI_Init(&EXTI_InitStructure);
48

49

50

51
 /* Enable the Interrupt */
52
  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
53
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
54
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
55
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
56
  NVIC_Init(&NVIC_InitStructure);

IRQ-Handler für Clock Signal
1
void EXTI9_5_IRQHandler(void)
2
{
3
  TIM_SetCounter(TIM2, 0); // reset watchdog counter as we still receive clock ticks
4
  
5
  if (RFID.isValidID) // this tag was already read and not removed since
6
  {
7
    EXTI_ClearFlag(EXTI_Line8);
8
    return;
9
  }
10

11
//hier ist code der die Daten verarbeitet aber nichts mit er Hardware anstellt
12

13
  EXTI_ClearFlag(EXTI_Line8);
14
}

Timer IRQ-Handler:
1
void TIM2_IRQHandler(void)
2
{
3
  if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)                 // check interrupt source
4
  {
5
    TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
6
   Target.LEDOn(LED_RED);
7
//    Delay(0xAFFFF);
8

9
    /* Turn off LD1 */
10
    Target.LEDOff(LED_RED);
11

12
    RFID.isValidID = false;
13
  }
14
 }
15
}

Die LED Toggle ich nur, damit ich mit dem LA sehen wenn ein Timer IRQ 
ausgelöst wurde.
Sieht man auch schön auf dem LA Screenshot.
Angehängte Dateien:
Gast #2277048
Lesenswert?

Thomas Burkhart schrieb:
> //Init IRQ for MLX90109
>   RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;   // enable clock for Alternate Function
>   AFIO->EXTICR[2] &= 0xFFF0;            //clear used pin
betrifft EXTI4 an PA4.

>   AFIO->EXTICR[2] |= (0x00);           // set pin 8 PORT A
wie das?

Du meinst nicht zufällig EXTICR[3], wenn Du wirklich PA8  nutzen willst?

Thomas Burkhart schrieb:
> EXTI_InitStructure.EXTI_LineCmd = ENABLE;
>   EXTI_Init(&EXTI_InitStructure);
Muß die Reihenfolge nicht gedreht werden? Erst initialisieren, dann 
einschalten?

Thomas Burkhart schrieb:
> /* Enable the Interrupt */
>   NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
Jetzt EXTI9?

Sorry, aber nach dem Mittagsschlaf brauche ich erstmal einen Kaffee, um 
dem folgen zu können.
OP #2277107
Lesenswert?

Lutz schrieb:
> Thomas Burkhart schrieb:
>> //Init IRQ for MLX90109
>>   RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;   // enable clock for Alternate Function
>>   AFIO->EXTICR[2] &= 0xFFF0;            //clear used pin
> betrifft EXTI4 an PA4.
>
>>   AFIO->EXTICR[2] |= (0x00);           // set pin 8 PORT A
> wie das?
>
> Du meinst nicht zufällig EXTICR[3], wenn Du wirklich PA8  nutzen willst?

Das ARRAY EXTICR[] beginnt bei 0, die Registernummerierung aber bei 1, 
daher 2 und nicht 3.


>> EXTI_InitStructure.EXTI_LineCmd = ENABLE;
>>   EXTI_Init(&EXTI_InitStructure);
> Muß die Reihenfolge nicht gedreht werden? Erst initialisieren, dann
> einschalten?

Wieso, das erste setzt ja nur ein Feld in der InitStruktur und schaltet 
noch gar nichts ein.

>
> Thomas Burkhart schrieb:
>> /* Enable the Interrupt */
>>   NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
> Jetzt EXTI9?

EXTI9 - 5 teilen sich einen IRQ, da ich EXTI8 brauche muss ich den 
nehmen.

Gruß
Tom


> Sorry, aber nach dem Mittagsschlaf brauche ich erstmal einen Kaffee, um
> dem folgen zu können.
Gast #2277276
Lesenswert?

Thomas Burkhart schrieb:
> Das ARRAY EXTICR[] beginnt bei 0, die Registernummerierung aber bei 1,
> daher 2 und nicht 3.

Donnerwetter. Kein Wunder, daß man sich bei dieser Logik der Lib 
vergrüßt. Ich hätte nach dem Datenblatt eigentlich sowas wie
AFIO->EXTICR3 = ...
o.ä. erwartet. Aber ein Array, dessen Index nicht mit der Registernummer 
im Datenblatt übereinstimmt .... Kann ja nur zu Fehlern führen. Find ich 
nicht gut, aber interessiert wohl leider niemanden.

Thomas Burkhart schrieb:
>>>   AFIO->EXTICR[2] |= (0x00);           // set pin 8 PORT A
>> wie das?
Aber was bringt denn hier ein verODERn des Registerinhalts mit 0?

Thomas Burkhart schrieb:
>>> EXTI_InitStructure.EXTI_LineCmd = ENABLE;
>>>   EXTI_Init(&EXTI_InitStructure);
>> Muß die Reihenfolge nicht gedreht werden? Erst initialisieren, dann
>> einschalten?
>
> Wieso, das erste setzt ja nur ein Feld in der InitStruktur und schaltet
> noch gar nichts ein.
Oh ja, gesegnet sei der Kaffee, dann liest man es auch richtig und sieht 
nicht nur ENABLE ...

Thomas Burkhart schrieb:
> EXTI9 - 5 teilen sich einen IRQ, da ich EXTI8 brauche muss ich den
> nehmen.
So viel Kaffee kann ich doch gar nicht trinken.
P.S.: Diese ganze Peinlichkeit bleibt unter uns, bitte nicht 
weitererzählen.
Kurzum: Ich kann da leider nicht helfen.
Gast #2278828
Lesenswert?

Hab mal schnell das TIM_SetCounter(TIM2, 0); bei mir ausprobiert: Timer 
wird zurückgesetzt, wenn ich das in einer schlafe mache kommen keine 
Update IRQs mehr (allerdings auf F207 getestet).

Was mir aber auffällt: Wieso sind auf dem LA screenshot nur 3 Nadeln in 
einem abstand von 70ms bzw. 40ms? Du sagtest doch, dass der Timer 
ungerührt mit dem Intervall weiterläuft. Und das wäre ja eigentlich 
10ms?

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