Gast
#7219616
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.
