www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Timer im Compare Mode läuft nicht sauber


Autor: Munchos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich habe ein kleines Programm geschrieben, welches prinzipiell später in 
ein größeres eingefügt wird.
Das Programm soll folgendes machen:
Atmega 8, Timer1 16-bit im Compare Match Mode (nicht CTC möglich, da ich 
den Timer später durchlaufen lassen muss, entfällt diese Möglichkeit).
Das Programm soll alle 1024 Timerticks ein Compare Match auslösen und 
eine LED damit toggeln. Hierzu lade ich OCR1A mit TCNT+1024 vor, also 
dem aktuellen Zählerstand + die 1024 Timerticks.
Nun leider toggelt die LED unregelmäßig, sie blinkt etwa 3x in gleicher 
Frequenz, dann 1x eine andere, dann wieder 3x gleich, eigentlich soweit 
ich beurteilen kann periodisch.
Dennoch sollte die LED ja in einem konsanten Takt blinken und nicht ein 
Ausreißer dazwischen.
Zunächst dachte ich, dass es evtl. daran liegt, dass OCR1A und TCNT1 das 
gleiche temp Register verwenden zum Auslesen. Deshalb habe ich eine 
Variable eingefügt, die als temp Register dient, das funktionierte aber 
auch nicht.
Wo ist mein Denkfehler in dem Programm oder der Programmierfehler?
Hier ist der Sourcecode:
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#ifndef F_CPU
#define F_CPU           8000000UL                   // Prozessortakt
#endif

#define LED      PB1    // Pin LED active low
  
ISR (TIMER1_COMPA_vect){
  PORTB ^= (1 << LED);      // LED teoggeln
  OCR1A = TCNT1+1024;        // Compare Match 1024 Timerticks später
  /* auf folgendes geht nicht:
  uint16_t temp = TCNT1
  temp += 1024;
  OCR1A = temp;
  */
}


// main programm
int main()
{

  DDRB = 0x00;                    
  DDRB |= (1 << DDB1);         
  PORTB |= (1 << LED);
  
  OCR1A = 1024;      // erstes Compare Match bei 1024 Timerticks, dann alle weitere 1024
  TCCR1B = (1 << CS00) | (1 << CS01);  // Prescaler 64
  TIMSK |= (1 << OCIE1A);                // Compare Match A enable
  sei();  // globales Interrupt enable
  
  while(1){
  // do nothing interruptgesteuert
  }
}

Desweiteren habe ich noch eine Frage: Welche Werte haben die Register im 
AVR allgemein nach Reset des µC?
Im Datenblatt steht, dass für den normalen Betrieb im Compare Match 
(ohne dass Pin OC1A geschaltet wird) im TCCR1A das Bit COM1A0 und COM1A1 
gelöscht sein muss (0).
Muss man diese vorher explizit löschen?
TCCR1A &= ~ ((1 << COM1A0) | (1 << COM1A1)) 
 oder sind alle Registerbits standardmäßig gelöscht?
Ich habe das auch ausprobiert beim Initialisieren, jedoch auch kein 
Unterschied im Programm.

Bin ratlos, gestern 4h damit verbacht :(

Autor: Hannes Lux (hannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> OCR1A = TCNT1+1024;        // Compare Match 1024 Timerticks später

Ich habe zwar keine Ahnung von C, aber was ich in ASM mache, müsste in C 
so aussehen:

OCR1A = OCR1A+1024;     // nächster Int.-Termin 1024 Timerticks später

Ich lese also die Compare-Register (nicht die Timer-Register) ein, 
addiere das Intervall und schreibe die Summe in die Compare-Register 
zurück. Dies ist jitterfrei, weil mir auch bei verspätetem Int-Aufruf 
der Wert nicht unterm Hintern wegläuft.

...

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.