mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik STM32 Welcher Timer ?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: rowtag (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte eine Art Lichtschranke mit einem STM32-Nucleo und einem 
Entfernungsmesser bauen. Wenn die Entfernung kleiner wird, also etwas 
die Lichtschranke durchfährt, soll ein Timer starten, und wenn die 
Entfernung wieder normal ist soll der Timer stoppen.
ich weiß nur nicht was für eine Art von Timer da richtig ist.

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Brauchst du den Timer jetzt um die Entfernung aus der Lichtschranke 
auszuwerten oder für was anderes? Wie kommt das Signal der Lichtschranke 
auf den Controller?
Soll der Timer auch was anderes können als Starten/Stoppen? Vielleicht 
die Zeit messen? Nach Ablauf einer Zeit was tun? Wenn du wie beschrieben 
nur Starten&Stoppen willst nutze einfach gar keinen Timer und stell dir 
vor als würde da ein Timer laufen.

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
PS: Wie lange soll der Timer maximal laufen, und was für eine zeitliche 
Auflösung brauchst du?

Autor: rowtag (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will die Zeit messen, wie lange der Gegenstand vor dem Sensor ist.

Autor: rowtag (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
brauche eine Auflösung in Millisekunden, vielleicht sogar kleiner

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und

Dr. Sommer schrieb:
> Wie kommt das Signal der Lichtschranke
> auf den Controller?


Dr. Sommer schrieb:
> Wie lange soll der Timer maximal laufen?

Welcher STM32 ist es genau? Da gibt es einige Unterschiede.

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Eine simple Möglichkeit wäre, denn Systemtimer auf 1kHz zu stellen und 
bei den beiden Ereignissen die Systemzeit in Variablen zu kopieren.

Autor: rowtag (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Controller und Sensor kommunizieren über I2C.
Zeitspanne ist maximal ein paar Sekunden. +
Es ist ein STM32L476RG.

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann nimm einen der General Purpose 16bit Timer, stelle den Prescaler so 
ein dass der Timer mit 10kHz läuft, und starte/stoppe den Timer manuell 
über das CEN Bit. So kommst du auf eine 100us Auflösung und Max 6,5 
Sekunden. Am Besten das Update Event abfangen um Überläufe zu erkennen.

Autor: rowtag (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Wie kann ich den Timer manuell starten/stoppen? Ich blicke bei den 
ganzen Funktionen nicht durch.

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
rowtag schrieb:
> Wie kann ich den Timer manuell starten/stoppen?

Durch Setzen/Löschen des CEN Bits im CR1 Register.

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Controller und Sensor kommunizieren über I2C.

Heisst das, dass der Mikrocontroller den Sensor regelmäßig pollen muss? 
Falls du damit wirklich Abweichungen unter 1ms erreichen willst, wird 
das knapp.

> Wie kann ich den Timer manuell starten/stoppen?

Falls sich die Frage auf den Systemtimer bezieht: Ich weiß nicht ob man 
ihn stoppen kann, aber das sollte man auf jeden Fall tunlichst 
unterlassen. Du hältst ja auch nicht die Wanduhr an, wenn du ein Ei 
kochen willst.

Die Idee des Systemtimer ist, dass da eine Variable fortlaufend 
regelmäßig hochgezählt wird. Typischerweise ein 32bit Integer im 1ms 
Intervall. Das hat auch jeder PC und jedes Smartphone so.

Bei ARM kann man auch andere Intervalle festlegen, zum Beispiel 0.5ms. 
Aber übertreibe es nicht, denn sonst ist der µC übermäßig mit Interrupts 
beschäftigt. Falls du weniger als 0,5ms brauchst, würde ich doch einen 
anderen Timer verwenden.

Bedenke, dass der Timer genug Bits haben muss. Ein 32bit Timer im 1ms 
Intervall kann fast 50 Tage erfassen. Ein 16bit Timer im 0,1ms Intervall 
kann aber nur 6,5 Sekunden erfassen. Reicht das für deine Anwendung?

Wenn du es mit dem Systemtimer machst, dann ungefähr so:
int warte_auf_start=1;
uint32_t start_zeitpunkt;
uint32_t ende_zeitpunkt;
uint32_t zeitspanne;

while (1) // endlos-schleife
{
    if (warte_auf_start && messe_entfernung() < 100) // Beginn der Messung
    {
        warte_auf_start=0;
        start_zeitpunkt=systick_count; // oder wie auch immer dein systemtimer heisst
    }
    if (!warte_auf_start && messe_entfernung() > 120)  // Ende der Messung
    {
        warte_auf_start=1;
        ende_zeitpunkt=systick_count;
        zeitspanne=ende_zeitpunkt-start_zeitpunkt;
    }
}

Die selbe Methode kannst (nicht musst) du auch mit einem schnelleren 
Hardware-Timer anwenden. Den lässt du einfach frei durchlaufen (nicht 
starten und stoppen). Auch damit kannst du die beiden Zeitpunkte 
(start/ende) erfassen und deren Differenz berechnen.

Wichtig ist dabei, dass die verwendeten Variablen (start_zeitpunkt und 
ende_zeitpunkt) den selben Typ haben, wie der Zähler. Denn dann darf der 
Timer zwischendurch sogar einmal (nicht öfter) überlaufen, und das 
Ergebnis bleibt dennoch richtig.

Den Timer durchlaufen zu lassen hat den Vorteil, dass du ihn 
gleichzeitig auch für andere Messungen verwenden kannst. Zum Beispiel, 
wenn du mehrere solcher Sensoren mit einem einzigen µC verwenden willst.

: Bearbeitet durch User
Autor: Dr. Sommer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefanus F. schrieb:
> Die Idee des Systemtimer ist, dass da eine Variable fortlaufend
> regelmäßig hochgezählt wird.

Der Vorteil eines Hardware Timers ist, dass keine ständigen Interrupts 
nötig sind, welche zudem mit etwas Pech nicht zur richtigen Zeit 
abgearbeitet werden. Beim Hardware Timer fragt man einfach zum 
fraglichen Zeitpunkt den Zähler ab und hat direkt den exakten Wert.

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Ja Dr. Sommer, da stimme ich Dir absolut zu. Deswegen habe ich davon 
abgeraten, den Systemtimer auf weniger als 0,5ms Intervall zu stellen.

Autor: Bastler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei einer Lichtschranke muss man doch nur erkennen ob das Signal da ist 
oder weg.
Was du meinst ist ein Lichtlaufzeitsensor. Das ist nicht so einfach.
Überleg dir mal wie lange das Licht benötigt um einen Meter 
zurückzulegen.

Autor: Bastler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder du arbeitest als Empfänger nicht mit einer Photodiode sondern mit 
einem Array, dann kann man über Triangulation messen.

Autor: rowtag (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Meine "Lichtschranke" ist ein vl53l0x Entfernungsmesser, der ständig die 
Entfernung zum Boden misst und an den µC sendet. Wenn der Abstand 
kleiner wird als die Normalhöhe, soll der Timer gestartet werden. Wenn 
der Abstand dann wieder normal ist soll der Timer stoppen.
Danach soll aus der Zeit (und der bekannten Länge des Gegenstandes) die 
Geschwindigkeit berechnet werden.

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Na dann hast du ja jetzt zwei brauchbare Lösungsansätze. Kommst du damit 
weiter?

Autor: rowtag (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Noch nicht wirklich.
Ich wollte es jetzt mit einem General Purpose Timer nehmen. Ich hab aber 
noch nie mit irgendwelchen Registern gearbeitet...

Autor: rowtag (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Kennt sich zufällig jemand mit den HAL Bibliotheken aus und kann mir 
sagen ob es da auch irgendwelche Funktionen gibt um Timer zu 
sarten/stoppen?

Autor: Dr. Sommer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
rowtag schrieb:
> kann mir
> sagen ob es da auch irgendwelche Funktionen gibt um Timer zu
> sarten/stoppen?
Ja gibt es. Sonst wäre die ja komplett nutzlos. Versuch's mal mit 
HAL_TIM_Base_Start und HAL_TIM_Base_Stop. Vorher natürlich mit 
HAL_TIM_Base_Init initialisieren. Takt Einschalten 
(__HAL_RCC_TIM?_CLK_ENABLE) nicht vergessen. Timerstand abfragen mit 
__HAL_TIM_GET_COUNTER .

Autor: Arduino Fanboy D. (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
rowtag schrieb:
> Ich hab aber
> noch nie mit irgendwelchen Registern gearbeitet...

Leitsatz:
> Wir lernen, indem wir es tun!

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde Dir raten, das Referenzhandbuch des µC zu lesen, sowie meine 
Notizen: http://stefanfrings.de/stm32/index.html

Vergiss die HAL, die macht es nicht wirklich einfacher.

Autor: Ductus cochlearis (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert

Autor: Stefanus F. (Firma: Äppel) (stefanus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Link funktioniert nicht

Autor: rowtag (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
[c] while (1)
  {
    HAL_TIM_Base_Start(&htim6);
    //TIM6->CR1 |= TIM_CR1_CEN;

    HAL_Delay(200);

    HAL_TIM_Base_Stop(&htim6);

    time=__HAL_TIM_GET_COUNTER(&htim6);
    test=time;
}
[\c]

ich hab es jetzt so weit. Jetzt weiß ich nur nicht wie man den Timer 
zurücksetzt.

Autor: Ductus cochlearis (Gast) (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert

Autor: rowtag (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
  
while (1)
  {
    HAL_TIM_Base_Start(&htim6);
    //TIM6->CR1 |= TIM_CR1_CEN;
    start=__HAL_TIM_GET_COUNTER(&htim6);
    HAL_Delay(200);

    HAL_TIM_Base_Stop(&htim6);

    stop=__HAL_TIM_GET_COUNTER(&htim6);
    time=stop-start;
    TIM6->SR = 0;
  }
jetzt hab ich es so gelöst. Für Time kommt aber immer 55772 raus. Also 
gehe ich mal davon aus der Timer ist nicht richtig eingestellt.
Wie berechne ich den Prescaler richtig. Der µC ha einen Takt von 80Mhz.

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.