mikrocontroller.net

Forum: Compiler & IDEs ATTiny25 Problem mit dem Timer


Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Stefan B. (stefan) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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 :)

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ 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?

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

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.