Hallo,
laut STM32 Reference Manual ist es möglich den externen Interrupt so zu
konfigurieren, dass dieser bei steigender und fallender Flanke auslöst.
Nur wie unterscheide ich in der ISR ob der Interrupt durch die steigende
bzw. fallende Flanke ausgelöst wurde?
Mein erster Lösungsansatz wäre: Ich überprüfe in der ISR ob der
entsprechende Portpin auf Low oder High liegt. Wenn der Portpin auf High
gezogen ist, dann war es eine steigende Flanke. Und wenn der Portpin auf
Low gezogen ist, dann war es eine fallende Flanke. Kann das so
funktionieren, oder gibt es vielleicht ein Register das diese
Information beinhaltet?
Kurz zum Hintergrund: Ich möchte einen Portpin überwachen und bei der
fallenden Flanke einen Timer starten. Bei der steigenden Flanke soll der
Timer wieder gestoppt werden und die gemessene Zeit ausgegeben werden.
Also im Prinzip möchte ich die Zeit zwischen zwei Flanken messen.
STM32_Beginner schrieb im Beitrag #1889786:
> Also im Prinzip möchte ich die Zeit zwischen zwei Flanken messen.
Wozu man normalerweise keinen externen Interrupt verwendet, sondern
Timer Capture. Ist dann taktgenau, während bei der ExtInt Variante die
variable Latenzzeit mit eingeht.
Lasse S. schrieb:> Ich mach das genauso, wie du es vor hast. Eine andere Möglichkeit habe> ich noch nicht gefunden.
Danke für den Hinweis, das ist schon mal gut zu wissen. Sollte ich das
mit dem Capture & Compare nicht hinbekommen, dann werd' ich das so
lösen.
A. K. schrieb:> Wozu man normalerweise keinen externen Interrupt verwendet, sondern> Timer Capture. Ist dann taktgenau, während bei der ExtInt Variante die> variable Latenzzeit mit eingeht.
So wie ich das im Reference Manual verstanden habe, kann ich den Timer
Capture so konfigurieren, dass dieser bei der entsprechenden Flanke(z.B:
steigende Flanke) den Counter Wert in ein Zusatzregister sichert. Wie
ich damit die Periodendauer eines Signals messen kann ist mir klar, doch
wie messe ich damit die Pulsbreite eines Signals?
Was mir gerade noch eingefallen ist:
Ich konfiguriere den Timer Capture so, dass ich zuerst den Counterstand
bei der fallenden Flanke bekomme. Und wenn ich diesen dann habe,
programmiere ich den Timer Capture um, sodass ich den Counterstand bei
der steigenden Flanke bekomme. Die Differenz der beiden Werte entspricht
dann der Pulsbreite. Kann das funktionieren?
Genau so geht das. Der primäre Unterschied zur Version über ExtInt ist
dabei, dass Latenz/Laufzeit des Interrupts nur noch in die erforderliche
Mindestdauer des Pulses eingehen, nicht mehr in die Messgenauigkeit.
Alternativ kannst du auch 2 Eingänge des gleichen Timers nutzen, auf
verschiedene Flanken konfiguriert. Dann muss nur noch durch das den Puls
beendende Capture-Event ein Interrupt ausgelöst werden.
A. K. schrieb:> Genau so geht das. Der primäre Unterschied zur Version über ExtInt ist> dabei, dass Latenz/Laufzeit des Interrupts nur noch in die erforderliche> Mindestdauer des Pulses eingehen, nicht mehr in die Messgenauigkeit.>> Alternativ kannst du auch 2 Eingänge des gleichen Timers nutzen, auf> verschiedene Flanken konfiguriert. Dann muss nur noch durch das den Puls> beendende Capture-Event ein Interrupt ausgelöst werden.
Vielen Dank für die Hilfestellung & die Erklärung! Ich werd' mich gleich
mal ransetzen und das ausprobieren.
Danke!
Hi,
ich hab mir heute die Capture & Compare Unit des STM32 angesehen. Ich
hab mich dazu entschlossen den TIM2_CH2 (entspricht Portpin PA.1) als
Capture Eingang zu verwenden. Dazu gleich eine Frage: Im Datenblatt
steht, dass PA.1 auch als USART2_RTS dient. Da ich in meiner Software
auch den USART2 verwende (also nur RX und TX), wollte ich fragen ob ich
den Portpin PA.1 nun verwenden kann oder nicht?
Meine Konfiguration von TIM2 sieht im Prinzip so aus:
-) GPIOA clock enable
-) configure PA.1 as input with pullup
-) CC2 channel is configured as input, IC2 is mapped on TI2.
-) capture is done on the rising edge
-) no prescaler, capture is done each time an edge is detected on the
capture input
-) enable capture
-) capture interrupt enable
-) TIM2 interrupt enable(NVIC)
-) TIM2 priority = 2
-) set TIM2 counter enable
Das Problem ist, dass der uC nie in die ISR springt. Hab ich bei der
TIM2 Konfiguration vielleicht etwas wichtiges übersehen, oder könnte es
etwas mit dem Portpin PA.1 zu tun haben?
Bei Bedarf poste ich auch gerne den Code der Initialisierungsroutine.
STM32_Beginner schrieb im Beitrag #1891037:
> steht, dass PA.1 auch als USART2_RTS dient. Da ich in meiner Software> auch den USART2 verwende (also nur RX und TX), wollte ich fragen ob ich> den Portpin PA.1 nun verwenden kann oder nicht?
Ja, RTS kann man da drauf mappen, muss man aber nicht. Aber
vorsorglich Errata-Sheet lesen, ob da irgendwas drüber drin steht.
> -) GPIOA clock enable
Timer auch?
> Bei Bedarf poste ich auch gerne den Code der Initialisierungsroutine.
Mach ma.
Markus Müller schrieb:> NVIC_InitTypeDef NVIC_InitStructure;> /* Enable the TIM2 global Interrupt */> NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;> NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;> NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;> NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;> NVIC_Init(&NVIC_InitStructure);
Von der ST Library hab ich leider nicht soviel Ahnung, ich hab die
bisher nicht genutzt.
A. K. schrieb:> Ja, RTS kann man da drauf mappen, muss man aber nicht. Aber> vorsorglich Errata-Sheet lesen, ob da irgendwas drüber drin steht.
Als ich gestern im Errata-Sheet gestöbert hab, ist mir nichts
aufgefallen. Aber es war schon spät, ich werd mir das daher heute
nochmal in Ruhe ansehen.
A. K. schrieb:> Mach ma.
Anbei mein Sourcecode zur Initialisierung von TIM2:
TIM2->ARR setzen. Beispielsweise auf 0xFFFF. Obacht, wenn man ARR
schreibt, dann schreibt man in ein Pufferregister, das erst bei einem
Update-Event wirklich greift. Es kann nötig sein, dieses Event manuell
auszulösen (UG bit in the TIMx_EGR).
"In upcounting mode, the counter counts from 0 to the auto-reload value
(content of the TIMx_ARR register), then restarts from 0 and generates a
counter overflow event."
"The counter is blocked while the auto-reload value is null."