PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Zeit zwischen steigender und fallender Flanke messen



Cyclon
21.02.2006, 11:56
Ich versuche grade die Signale eines RC-Empfängers auszuwerten (PWM Signale), dabei bin ich auf das Problem gestoßen, das ich die Zeit zwischen der steigenden und fallenden Flanke messen muss.
Hier im Forum hab ich leider nur Beispiele für Bascom gefunden, wo's diesen schönen Befehl 'Pulsein' gibt. Gibt es sowas ähnliches nicht auch vielleicht für C?
Zur Zeit versuche ich das per Interrupt und Timer zu lösen, klappt aber irgendwie nicht so ganz... :-k

ogni42
21.02.2006, 12:19
Du kannst dafür (falls an Deinem Chip vorhanden entweder den Input Capture Pin) oder den INT0 Pin verwenden. Bei ICP musst Du die Flankentriggerung jeweils umschalten, INT0 kann auf beide Flanken triggern.

Vorgehen INT0:
- Triggern auf jede Flanke einschalten
- Einen Timer im Freilaufmodus verwenden
- In der INT0 Interruptroutine jeweils den aktuellen Stand des Timers auslesen: Differenz zwischen zwei Impulsen gibt die Zeit an

SprinterSB
21.02.2006, 13:21
Wie gesage, "das" PulseIn wird es nicht geben, weil es sehr viele Möglichkeiten der Frequqenz-/PWM-Messung gibt. Je nach verfügbaren Ressourcen/Ansprüchen/Signalaufbau sind die von ingo genannten Methoden unterschiedlich gut geeignet.

Wenn die Geschwindigkeit nicht sooo wichtig ist, tut's evtl auch die PWM durch nen Tiefpass (RC-Glied) zu schicken und im A/D-Wandler nachzuschauen.

ogni42
21.02.2006, 13:26
Stimmt, die PWM Messung über ADc hatte ich vergessen.

Cyclon, vielleicht kannst Du uns die Anwendung etwas genauer beschreiben. Dann werden unsere Ratschläge vielleicht auch genauer (so wir denn eine Lösung finden)

Cyclon
24.02.2006, 12:12
Ich hatte vor ein Bremslicht für ein Fernsteuerwagen zu bauen, d.h wenn der Servo in eine Richtung bewegt wird, soll eine rote LED leuchten.
Ich bin jetzt auch schon soweit, das der Interrupt einigermaßen Funktioniert.
Habe dazu 2 LEDs zum testen angeschlossen, die bei jedem Interrupt abwechselnd leuchten.
Das funktioniert aber nur, wenn ich mit dem Kabel, was an INT0 angeschlossen ist, gegen das + Kabel tippe. Sobald ich den Empfänger, an das Kabel anschließe tut sich nix mehr. Wobei der Sever beim selbem Anschluss ohne probleme läuft.



#include <stdio.h>
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
#include <avr/signal.h>

unsigned char a= 0;

SIGNAL (SIG_INTERRUPT0)
{

if(a==0)//if(TCNT0<=50)
{
PORTD |=(1<<1);
PORTD &=~(1<<0);
TCNT0 = 0;
a=1;
}
else //if(TCNT0>=75)
{
PORTD |= (1<<0);
PORTD &= ~(1<<1);
TCNT0 = 0;
a=0;
}
}


int main(void)
{
DDRC =0x00;
DDRD = 0xff;

PORTC = 0x00;
PORTD =0x00;



GICR |= (1<<INT0);
MCUCR |= (1<<ISC00);
TCCR0 |= (1<<CS01) ;
sei();


while(1);

PORTD = 0xff;

return 0;
}


Edit: Hab grade feststellen müssen, das durch den Empfänger garkein Interrupt ausgelöst wird. wodran kann das liegen?
Ich hab sowohl versucht den das Signalkabel direkt an INT0 am µC anzuschließen, als auch das Kabel mit nem 56k Widerstand gegen Masse zu legen und dann zwischen widerstand und kabel zum empfänger das signal abzugreifen, klappt beides nicht.

SprinterSB
24.02.2006, 12:18
An welchem Port hängt denn INT0?
Diesen Port musst du als IN schalten (also rate ich mal, er gehört zu Port C).

Evtl. braucht's nen (internen) PullUp an dem Port?

Cyclon
24.02.2006, 12:24
Warum muss ich den auf IN schalten? :-s
Das läuft doch auch so.
Nur mit dem Signal was vom Empfänger kommt gibts Probleme.

SprinterSB
24.02.2006, 12:32
Wenn du ein Signal auswerten willst, hängst du das Signal an einen µC-Port. Wenn dieser nicht als IN konfiguriert ist, kommen sich die beiden niederohmigen Signale in die Quere. Mindestens ein Signal verliert. Wenn du Pech hast, rauchen beide Signale ab (Signal-Erzeuger und µC-Port).

Kurz: um etwas IN den µC zu bekommen, muss die Tür auch offen (also IN) sein. Ansonsten streiten sich zwei Rammböcke, wer der stärkere ist.

Cyclon
24.02.2006, 12:47
Hattest recht, jetzt läuft es.
Da wär ich nie drauf gekommen.
Danke.