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
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.
Hmm, wenn es so wäre, würde bei jeder Clock Flanke ein TIMER IRQ auslösen, dies ist jedoch nicht der Fall. Die Timer IRQs kommen regelmäßig entsprechend der Einstellung des Timers.
Es sollte eigentlich so funktionieren, da man das Counterregister auch bei laufendem Timer lesen und schreiben kann. Ohne Code wird das dann nix, da der Fehler vermutlich dort liegt.
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.
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.
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.
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.
:-) :-) Das Odern mit Null macht natürlich nichts, aber sollte nur zeigen, dass an dieser Stelle normalerweise der entsprechende Pin gesetzt würde.
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?
Du hast recht, dass ist mir in der Zwischezeit auch aufgefallen, es scheint also nur machmal zu passieren, dass noch ein IRQ durchkommt. Danke fürs ausprobieren.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.