Hallo, ich versuche mit folgender Routine einen Impuls zu messen und wieder auszugeben //Timer0 TIMSK = (1 << TOIE0 ) | (1 <<OCIE1A ); // enable overflow interrupt //TCCR0B = ( 1 << CS02 ); //prescale => cpu clock/256 bei 1Mhz = 256us //TCNT0 = 217; //255 - 217 = 39 x 256us = 9.984ms GIMSK = (1 << PCIE); PCMSK = (1 << PCINT0); sei(); // enable interrupts /*********************************************************************** ***********************/ /* SIGNAL Pin Change Interrupt */ /*********************************************************************** ***********************/ SIGNAL(SIG_PIN_CHANGE) { if ( PINB & (1<<PINB0) ) { TCNT1 = 0; // Timer1 Reset TCCR1 = ( 1 << CS10 | 1 << CS12 ); // Timer1 cpu clock/16 MCU start } if ( !(PINB & (1<<PINB0)) ) { Pulsdauer = TCNT1; // Timer1 Wert = Pulsdauer TCNT1 = 0; // Timer1 Reset OCR1A = Pulsdauer; PORTB |= (1<<PB2); //High } } /*********************************************************************** ***********************/ /* Timer/Counter1 Compare Match A */ /*********************************************************************** ***********************/ SIGNAL(SIG_OUTPUT_COMPARE1A) { TCCR1 = 0x00; // Timer1 Stoppen PORTB &= ~(1<<PB2); } Das Problem ist das mein Timer Wert TCNT1 nicht immer das richtig Ergebnis enthält. Um zu sehen ober der Puls richtig erkannt wird haben ich einfach mal OCR1A = 100; eingebaut, daran sieht man das der Ausgangspuls dann stabil bleibt, d.h irgendwie läuft der Timer1 nicht sauber?? was mache ich Falsch? Gruss Patrick
Ich habe da mal deinen Code ergänzt, so wie ich die Frage verstanden habe und so weit es für die Simulation im AVR Studio notwendig ist. Mit meinem AVR Studio Simulator (4.12 SP2) hatte ich mit Timer1 kein Glück, deshalb habe ich alles auf Timer0 umgeschrieben. Timer0 und Timer1 nimmt sich bei dem Attiny25 nicht viel, denn beide sind nur 8-Bit breit. Allerdings kann man bei Timer0 keinen Prescaler 16 einstellen. Ich habe willkürlich Prescaler 8 genommen. D.h. die maximale Dauer der Highphase, die gemessen werden kann, ist jetzt ca. 2ms statt vorher 4ms (1 MHz). Wenn man die Anzahl der Timer0 Interrupts zählt, könnte man auch längere Pulse verarbeiten. Mich interessiert, warum du das programmierst, also was du damit machst. Darfst du das erzählen? EDIT: Nur damit es gesagt ist :) Durch die Software-Anweisungen in den ISRs wird die Messung natürlich ungenau. Wenn es genauer werden soll, sollte man sich die Timestamps bei Pegelwechsel an Pins per Hardware geben lassen. Habe ich mal gelesen :)
Hallo Stefen, ich hab mir deinen Code mal angeschaut, im Prinzip ist ja nichts neues drin, das Problem ist bei mir dass aus irgend einem Grund der Timerwert TCNT1 nach dem Erkennen der fallenden Flanke sproadisch zu klein ist. Ich hab mal zum Testen folgendes eingefügt: if ( !(TCNT1 <= 10)) { Pulsdauer = TCNT1; // Timer1 Wert = Pulsdauer } mit dieser Zeile geht alles, nur frage ich mich war mir den Wert von TCNT1 verhagelt? Im Sim geht übrigens auch alles, aber real gibts die sporadischen Probleme. Daran sehe ich auch dass das Erkennen der beiden Flanken funktioniert.. Das ganze dient übrigens dazu einen Servoimpuls auszuwerten, ist als nicht Geheim ;-) Gruss Patrick
Patrick schrieb: > Hallo Stefen, > > ich hab mir deinen Code mal angeschaut, im Prinzip ist ja nichts neues > drin, das Problem ist bei mir dass aus irgend einem Grund der Timerwert > TCNT1 nach dem Erkennen der fallenden Flanke sproadisch zu klein ist. Timeroverflow in der Zwischenzeit?
@ Patrick Wie sehen deine Servoimpulse denn aus? Ich habe da keine Vorstellung zu der Dauer der HIGH-Phase und der Dauer der LOW-Phase. Die Messung ist ja auf ca. 4ms HIGH-Phase (2 ms bei meiner Variante) beschränkt. Und laut Programm wird ja zeitversetzt gemessen und ausgegeben. Wenn während der Ausgabe ein neuer Servoimpuls reinkommt, beeinflusst das auch TCNTx. D.h. die LOW-Phase muss länger sein als die HIGH-Phase. Ich habe u.a. deshalb beide Teile stärker getrennt als in deinem Quelltext. Ist das Servosignal ein "sauberes" digitales Signal oder können da Prellen und Spikes die Messung stören?
Karl heinz Buchegger schrieb:
> Timeroverflow in der Zwischenzeit?
eigendlich nicht? nach dem Erkennen der positiven Flanke wird der Timer
gestartet, dann läuft er maximal 150 Ticks, d.h überlaufen dürfte er
nicht.
Könnte mein PreScale nicht passen? der Tiny25 läuft mit dem RC Oszilator
mit 8Mhz, der Standart Teiler ist 8 , dh. meine Basisfrequenz ist 1Mhz.
damit:
TCCR1 = ( 1 << CS10 | 1 << CS12 ); // Timer1 cpu clock/16 MCU start
sollte der Timer1 mit 16us laufen, d.h bei einer Pulslänge von 1ms hätte
ich 63 Ticks bei 2ms 125Ticks, da kann eigendlich nix überlaufen.
Gruss Patrick
Stefan B. schrieb:
> Wie sehen deine Servoimpulse denn aus?
im Prinzip immer 20ms lang mit Pulsen der Länge 1-2ms. Zwischendurch
kommt da nichts.
Gruss Patrick
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.