www.mikrocontroller.net

Forum: Compiler & IDEs 16-Bit Timer läuft zu schnell


Autor: Paul P. (cesupa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte für mein Projekt eine Uhr mit meinem Atmega32 realisieren. 
Der uC läuft mit 16MHz. Für meine Uhr und andere "Systemanwendungen" 
nutze ich einen Grundtakt von 10ms. Lasse ich die Uhr laufen, 
verstreichen die Sekunden jedoch zu schnell. Ungefähr 1/3 schneller, als 
eine Sekunde auf meiner normalen Uhr verstreicht. Woran könnte das 
liegen?
#define TICKS  10      //in ms, max. 1000
#define PRESCALER  64
#define COUNTER  65536

#if(TICKS>1000)
#error "TICKS IS TOO BIG!!!";
#endif

#define F_TIMER (1000/TICKS)
#define LOADER  (COUNTER-(F_CPU/(PRESCALER*F_TIMER)))

ISR(TIMER1_OVF_vect)
{
  /*
...
*/
  TCNT1=(uint16_t)LOADER;     //63036
}

int main()
{

  /*...*/
  
  /*using the 16-bit timer 1*/
  TCCR1B|=(1<<CS11)|(1<<CS10);  //prescaler=64
  TCNT1=(uint16_t)LOADER;      //63036->100ms
  TIMSK|=(1<<TOIE1);    //overflow interrupt

  
  sei();

  while(1)
  {
  }
  return 0;
}

Gruß
Paul

Autor: Thomas Forster (igel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso benutzt du nicht den CTC-Mode anstatt Overflow?
Du musst den Timer beim Überlauf nicht ständig neu laden.
Ich finde dies wesentlich komfortabler.

Thomas

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>   TCNT1=(uint16_t)LOADER;      //63036->100ms

Dieser Kommentar ist verwirrend. Die ISR wird alle 10 ms aufgerufen. 
Vielleicht braucht dein /* ... */ Teil darin zu lange. Kann man aber 
nicht beurteilen, weil die Source fehlt. Ist nur geraten.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas Forster schrieb:
> Wieso benutzt du nicht den CTC-Mode anstatt Overflow?
> Du musst den Timer beim Überlauf nicht ständig neu laden.
> Ich finde dies wesentlich komfortabler.

Nicht nur komfortabler. Wozu so einen ungefähren Murks mit dem Neuladen 
des Timers machen, wenn es einen einfachen und jitterfreien Weg gibt? 
Es lohnt sich nicht, hier den Fehler zu suchen - CTC geht einfach, ist 
exakt und kostet weniger Code (spart das Neuladen).

Autor: Paul P. (cesupa)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Super, hat geklappt, hier noch mein code:
#define TICKS  10      //in ms, max. 1000
#define PRESCALER  64

#if(TICKS>1000)
#error "TICKS IS TOO BIG!!!";
#endif

#define F_TIMER (1000/TICKS)
#define LOADER  ((F_CPU/(PRESCALER*F_TIMER))-1)

ISR(TIMER1_COMPA_vect)
{
  tickTime();
  displayTime();
}

int main()
{
/*...*/
  
  /*using the 16-bit timer 1*/
  TCCR1B|=(1<<CS11)|(1<<CS10)|(1<<WGM12);  //prescaler=64
  OCR1A=(uint16_t)LOADER;      //10ms
  TIMSK|=(1<<OCIE1A);    //ctc interrupt

  
  sei();

  while(1)
  {
  }
  return 0;
}

Gruß
Paul

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.