www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer funktioniert nicht richtig?


Autor: Tung Nguyen hoang (sumovd)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

für meine Projekt benutze ich den Atmega16. Um einen Rechteckpuls mit 
einer Pulsbreite 10µs an pin PD4 zu erzeugen kommt der Timer0 zum 
Einsatz.
Die Idee ist folgendes: Ich betreibe den µC bei 8Mhz. Timer Vorteile 
8--> Clock Timer = 1Mhz. Der Pin PD4 wird zunächst auf High gesetzt, 
gleichzeitig wird der Timer gestartet und zählt bis 10 (entsprechend 
10µs), dann wird ein Interuppt ausgelöst, wobei der Pin wieder auf Low 
gesetzt.
Das Problem ist: ich habe den Puls mit einem Osciloscop gemessen. Was 
ich  an dem Pin rauskriege ist ein Puls mit einer Pulsbreite von ca. 100 
µs. Kann jemand mir das erklären? Liegt es daran, dass der Timer nicht 
rechtzeitig gestartet wird oder beim Interrupt wird das Programm 
verzögert?

Unten ist die C-Code als Funktion:
void trigger(void)
{ 
     DDRD|= (1<<PD4);
     PORTD |= (1<<PD4);
     //Der µC wird mit 8Mhz betrieben, Vorteile 8--> Clock Timer = 1Mhz
     TCCR0 = (1<<CS01);
     //Vergleichwert
     OCR0 = 10;
     //Output Compare Match interrupt aktivieren
     TIMSK = (1<<OCIE0);
     //Timer aktivieren
     TCNT0 = 0;
}
ISR (TIMER0_COMP_vect)
{
    //Timer stoppen
    TCCR0 = 0;
    //PIND4 auf Low setzen
    PORTD &=~(1<<PD4);
}

Autor: Kai Franke (kai-) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich weiß nicht wieso du überhaupt einen Rechteckimpuls bekommst...
du setzt in deiner ISR den Pin immer wieder auf Low, aber nicht mehr auf 
high.

Autor: Steffen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zu deinem Code:
 TCCR0 = (1<<CS01); 
mit dieser Zeile aktivierst du den Timer 0 schon
 TCNT0 = 0; 
hier setzt du den Timer 0 einfach nur zurück. Deswegen wird der 
Interrupt später ausgelöst.

versuche doch die Zeile mit dem Prescaler ganz nach unten zu setzen. 
Kurz davor solltest du den PIN an Port D setzen. Das würde ich einfach 
mal ausprobieren und mit dem Oszi nachmessen. Pass aber auch, wenn du 
die globalen Interrupts frei gibst.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Betreib den Timer im CTC-Modus. Dann brauchst Du in der ISR nicht das 
TCNT0 zurückzusetzen. Außerdem ist es sinnvoll, so ein Signal über die 
Compare-Einheit per Hardware zu erzeugen (automatisches Umschalten des 
Pins OC0). Dann brauchst Du eigentlich gar keinen Interrupt mehr. Und 
10µs bekommst Du mit der obigen Version nie. Vom Setzen des Flags bis 
zur Ausführung von "PORTD &=~(1<<PD4);" vergeht auch eine ganze Weile 
(mindestens 10-15 Taktzyklen, also 1-2µs). Außerdem erfolgt das Setzen 
des Pins schon vor der ganzen Timer-Initialisierung. Da kommt noch mal 
einiges an Taktzyklen dazu (abgesehen davon, dass Du [wie Steffen schon 
sagte] das TCNT0 noch mal zurücksetzt).

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.