Timer funktioniert nicht richtig?

OP #630058
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:
1
void trigger(void)
2
{ 
3
     DDRD|= (1<<PD4);
4
     PORTD |= (1<<PD4);
5
     //Der µC wird mit 8Mhz betrieben, Vorteile 8--> Clock Timer = 1Mhz
6
     TCCR0 = (1<<CS01);
7
     //Vergleichwert
8
     OCR0 = 10;
9
     //Output Compare Match interrupt aktivieren
10
     TIMSK = (1<<OCIE0);
11
     //Timer aktivieren
12
     TCNT0 = 0;
13
}
14
ISR (TIMER0_COMP_vect)
15
{
16
    //Timer stoppen
17
    TCCR0 = 0;
18
    //PIND4 auf Low setzen
19
    PORTD &=~(1<<PD4);
20
}
Gast #630108
Lesenswert?
• ▲
▼
zu deinem Code:
1
 TCCR0 = (1<<CS01);
mit dieser Zeile aktivierst du den Timer 0 schon
1
 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.
#630139
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

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.