Forum: Mikrocontroller und Digitale Elektronik STM32F4 Timer Interrupt


von Dennis (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich muss an zwei GPIOs die Siagnale decodieren (siehe Bild).
Meine Idee wäre das mit einem Timer zu realisieren. Bei steigender 
Flanke würde der Timer anfangen zu zählen und in der Mitte würde immer 
ein Interrupt auslösen um die beiden GPIO-Werte zu holen. Die Daten 
liegen mit einer Geschwindigkeit von 500kHz an den GPIOs an.

Die frage ist wie der Timer konfiguriert werden muss. Hat jemand eine 
Idee?

Grüße Dennis

von deren Beitrag einf (Gast)


Lesenswert?

Freilaufender Timer.
GPIO Interrupts.
Im Interrupt Timer auslesen und Zeiten berechnen?

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Vermutlich lauft der Takt des GPIO Signales asynchron zum Prozessortakt. 
Nach Shannon musst Du dann mindestens 2 mal pro Takt abtasten. Also 
setzt Du eine Timer, der Dir mindestens zwei Interrupts pro Takt erzeugt 
und wertest in der Interruptroutine entsprechend aus.

Was erzeugt diese komischen Signale?

von Dennis (Gast)


Angehängte Dateien:

Lesenswert?

Es ist eigentlich ein 3-Level Siganl was an zwei Komperatoren geht was 
mir je nach Pegel die oberen Siganel ausgibt

von Dennis (Gast)


Lesenswert?

Kann man auch hier mit DMA arbeiten?

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Dennis schrieb:
> Kann man auch hier mit DMA arbeiten?
Nur falls beide GPIO am gleichen PORT haengen. Dann koenntest Du mit dem 
DMA Signal vom Timer das GPIOx->IDR Register auslesen und wegschreiben.

von Dennis (Gast)


Lesenswert?

Ich fasse mal zusammen:
-Ein freilaufender Timer der alle 666ns auslöst um die Siganel zweimal 
abzutasten.
-Der Timer wird über einen externen Interrupt (EXTI#) gestartet.

Ist es möglich das alles in einem Timer zu vereinen, ohne den (EXTI#) zu 
benutzen?

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Fuer was brauchts Du den EXTI? Der Timer laeuft frei, du sampelst 
kontinuierlich und wertest im Interrupt oder mit DMA aus. Die Flanken 
muss die IRQ/DMA Routine durch Vergleich mit dem letzten gesampelten 
Wert finden.

von Dennis (Gast)


Lesenswert?

Ich muss aber irgendwann zu beginn bei der aller ersten Flanke den timer 
starten, bzw den Counter reseten.
Es kann auch vorkommen, dass sich die Zeiten einwenig ändern. Dann wäre 
es hilfreich irgendwie nach zu trimmen. Ich müsste ab und zu bei einem 
Flankenwechsel den Timer reseten.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Falls dass Signal auf einem Timercapture des benutzten Timers liegt, 
dann kannst Du auch den Zeitpunkt der Flanke erfassen. Braucht auch 
keinen EXTI.

von Dennis (Gast)


Lesenswert?

Den Timer muss ich so einstellen, dass er immer nach 666ns überläuft??

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Meine Idee von 14:20 passt nicht! Vermutlich brauchts Du zwei Timer...

Zunaechst eine weitere Frage: Wie lange koennen den die Sequenzen 
werden?

Und eine weitere neugierige Frage: Was erzeugt das 2-Stufensignal?

von Peter D. (peda)


Lesenswert?

Da das Eingangssignal asynchron ist, mußt Du auch damit rechnen, daß nur 
GPIO1 oder nur GPIO2 für eine Abtastperiode aktiv sind.

von Dennis (Gast)


Lesenswert?

maximal werden 40 bit übertragen.
Das ist ein Sensor Interface für ein Drucksensor.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Gpio1 startet TimA. TimA->ARR gesetzt fuer Ueberlauf alle 666ns. 
TimA->CNT vorbesetzt mit 333ns (Periode/2) . TimA UpdateEvent sampelt 
GPIO1/2. DMA ist fuer 40 Samples gesetzt. Dma Full Transfer stoppt 
Datenaufnahme, startet Auswertung und setzt TimA->CNT wieder auf 
Periode/2.

Damit hast du den Samplepunkt in der Mitte des Taktpulsfensters und 335 
ns Platz fuer Ablage zwischen Sensor- und Auslesetakt.

von Dennis (Gast)


Lesenswert?

Danke für die Hilfe. Ich werde es ausprobieren und mich dann wieder 
melden.

von Dennis (Gast)


Lesenswert?

Ich habe ein Problem mit DMA, es wird immer der transfer error interrupt 
flag "CTEIF0" ausgelöst.
1
HAL_DMA_Start_IT(&hdma_tim3_ch4_up, (uint32_t)&GPIOC->IDR, uint32_t)&gSamples[0], GSAMPLES_SIZE);
2
3
__HAL_TIM_ENABLE_DMA(&htim3, TIM_DMA_UPDATE);
4
5
/* DMA: Clear Interrupt FLAG */
6
__HAL_DMA_CLEAR_FLAG(&hdma_tim3_ch4_up, DMA_FLAG_TCIF0_4);
7
8
HAL_TIM_Base_Start_IT(&htim3);

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Nee, mit HAL setzte ich mich nicht auseinander. Bei HAL muss man nicht 
nur die Registerbelegung kennen, sondern auch noch was HAL macht.

von Dennis (Gast)


Lesenswert?

Hat jemand vielleicht eine Idee?

von Dennis (Gast)


Angehängte Dateien:

Lesenswert?

anbei befindet sich mein code und das STM32CubeMX project file.

Ich habe mir ein einfaches Programm geschrieben, das bei jeder 
steigender Flanke am GPIO PA0 über DMA den Register Inhalt von 
GPIOC->IDR in die Variable gSamples speichert.
Nur leider wird immer das transfer error interrupt flag "CTEIF0" bei 
steigender Flanke ausgelöst.

von Dennis (Gast)


Lesenswert?

Keiner hat eine Idee?

von Dennis (Gast)


Lesenswert?

Ich habe gerade herausgefunden, dass es mit DMA2 funktioniert aber mit 
DMA1 nicht.
Nur leider wird DMA2 bei Timer1 und Timer8 eingesetzt.

Hat jemand eine Erklärung dafür?

von Dennis (Gast)


Lesenswert?

Ist es somit garnicht möglich mit den anderen Timern und DMA1 von 
GPIOC->IDR auf gSamples zuschreiben?

gibt es vielleicht eine andere Möglichkeit?

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Doch, das muss gehen!

Bist Du systematisch vorgegangen?
- Kannst Du Tim2 wie gewollt starten?
- Gehen andere DMA Transfers?
- Stimmen die tatsaechlichen Registerwerte mit den erwartetet Werte 
ueberein?

Vielleicht finde ich Zeit mit Nut/OS SVN Trunk ein Beispiel zu 
programmieren:

- Usr Taster (PA0) startet TIM2
- Tim2 UE sampelt GPIOC->IDR 100 mal
- DMA TC stoppt Timer.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Angehängte Dateien:

Lesenswert?

Beim F4 liegen die GPIO auf dem AHB1 Bus. Nur DMA2 kann einen AHB1 <-> 
Memory (Memory-to-Memory) Transfer machen. Du brauchst also Timer, die 
DMA2 benutzen, um GPIO DMA Transfers mit dem Timer zu triggern.
Das Programm oben  läuft auf einem Nucleo-F411, mit einem Jumper von 
PC13, dem blauen User Button nach PB10 ( TIM1_CH1, Arduino D7). Ich habe 
4 Transfers programmiert. Ich benutze die fallende Flanke, da der 
Userbutton mit einem Kondensator gebrückt ist, und unterschiedliche 
Triggerpegel bei der steigenden  Flanke eine Verzögerung zwischen Taster 
und Logikanalysator vorgaukeln. Der Userbuttom ist Kanal 0, die 
steigende Flanke ist der Abtastzeitpunkt fuer den GPIO und schaltet 
PB11/TIM1_CH2 high. Mit jedem Tastendruck gibt es die angezeigte 
Sequenz.

von Dennis (Gast)


Lesenswert?

VielenDank,
ich werde es mir morgen genauer anschauen und versuchen es umzusetzen.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Lesenswert?

Ich denke, Dein bisheriger Code wird auch gehen, wenn Du einem DMA2 
Timer nimmst...

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
Noch kein Account? Hier anmelden.