STM32F4: PWM Duty und Periode einlesen

Gast #7219616
Lesenswert?

Hallo,

ich möchte die Pulsweite und Periode eines typischen 50Hz RC-Servo 
Signals über einen Pin einlesen.
Theoretische Auflösung soll 1us betragen.

Dazu lasse den TIM4 (16Bit) mit einer Frequenz von 1MHz laufen und 
verwende die Anleitung aus dem RM0090, siehe Screenshot01.png

Code:
(Die 7 Stichpunkte aus der Anleitung im Screenshot habe ich mit 
Kommentaren 1..7 markiert)

    /* 1. */
    regval = TIM4->CCMR1;
    regval &= ~TIM_CCMR1_CC1S_1;
    regval |= TIM_CCMR1_CC1S_0;
    TIM4->CCMR1 = regval;

    /* 2. */
    regval = TIM4->CCER;
    regval &= ~TIM_CCER_CC1P;
    regval &= ~TIM_CCER_CC1NP;
    TIM4->CCER = regval;

    /* 3. */
    regval = TIM4->CCMR1;
    regval |= TIM_CCMR1_CC2S_1;
    regval &= ~TIM_CCMR1_CC2S_0;
    TIM4->CCMR1 = regval;

    /* 4. */
    regval = TIM4->CCER;
    regval |= TIM_CCER_CC2P;
    regval &= ~TIM_CCER_CC2NP;
    TIM4->CCER = regval;

    /* 5. */
    regval = TIM4->SMCR;
    regval |= TIM_SMCR_TS_2;
    regval &= ~TIM_SMCR_TS_1;
    regval |= TIM_SMCR_TS_0;
    TIM4->SMCR = regval;

    /* 6. */
    regval = TIM4->SMCR;
    regval |= TIM_SMCR_SMS_2;
    regval &= ~TIM_SMCR_SMS_1;
    regval &= ~TIM_SMCR_SMS_0;
    TIM4->SMCR = regval;

    /* 7. */
    regval = TIM4->CCER;
    regval |= TIM_CCER_CC1E;
    regval |= TIM_CCER_CC2E;
    TIM4->CCER = regval;

Periodenmessung:
Fallende Flanke: Timer Reset, erreichten Counter-Wert in das CCR1 
Register schreiben.

Pulsweitenmessung:
Steigende Flanke: aktueller Timer Counter-Wert in das CCR2 Register 
schreiben.

Die Register CCR1 und CCR2 werden asynchron in der main-Schleife 
ausgelesen.

Ergebnis: Pulsweitenmessung (CCR2) enthält den erwarteten Wert, je nach 
RC-Servo Signal zwischen 1000 und 2000.

Problem: Periodenmessung (CCR1) enthält mal die Pulsweite (1000 .. 2000) 
mal die Periodendauer (~20000).

Woran könnte es liegen, dass die Periode falsch gemessen wird?
Nach meinem Verständnis sollte das CCR1 Register nur
bei fallender Flanke aktualisiert werden und somit die Zeit 
(Counter-Wert) zwischen den fallenden Flanken enthalten.
Angehängte Dateien:
Gast #7219779
Lesenswert?

Servotester schrieb:
> ich möchte die Pulsweite und Periode eines typischen 50Hz RC-Servo
> Signals über einen Pin einlesen.

Es gibt einen Modus, bei dem bei einer Flanke des Eingangssignal der 
Zählerwert gespeichert und bei der anderen der Zählerstand gespeichert 
und gelöscht wird. Letzterer Wert ist die Periodendauer, aus dem 
Zwischenwert ergibt sich das Tastverhältnis.
Bei einem 16 Bit Timer mit 1 µs Auflösung funktioniert das ab 16 Hz 
Eingangsfrequenz.

Wenn Du es feiner und genauer haben willst: 
http://mino-elektronik.de/FM_407/fmeter_407.htm#a5
Gast #7219825
Lesenswert?

Hallo,

genau diesen Modus möchte ich verwenden und habe es nach dem Reference 
Manual implementiert,

m.n. schrieb:
> und bei der anderen der Zählerstand gespeichert und gelöscht wird.
> Letzterer Wert ist die Periodendauer,

und dieser Teil funktioniert nicht wie erwartet.
Gast #7224651
Lesenswert?

Hallo,

nur zur Info, falls jemand ebenfalls PWM mit einem STM32 einlesen will: 
Der Code oben ist korrekt und funktioniert.
Mein Problem war, dass ich weiter unten einen weiteren HAL-Lib Aufruf 
auf den betroffenen TIMER hatte, welcher nochmal das CCER Register 
überschrieben hatte.

Viele Grüße

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