Forum: Compiler & IDEs timer0 atmega8


von Harald F. (hfine)


Lesenswert?

Hallo zusammen,

ich bin mich gerade am Einarbeiten mit dem Atmega8 und habe folgendes 
Problemchen.
Wenn ich den Timer0 auf das Overflowflag abfrage ist alles in Butter.
Wenn ich aber das Timerzählregister abfrage komme ich nicht klar.

Danke im Vorraus
Harald

hier mein Problemkind:

//----------------------------------------------------------------------
// Titel     : Timer0 testen
//----------------------------------------------------------------------
// Funktion  : gelbe und grüne LED blinken mit Timer0 Flag bzw. 
Vergleich
// Schaltung : LED gelb an PC5, LED grün an PC4
//----------------------------------------------------------------------
// Prozessor : ATmega8  3.6864 MHz
// Sprache   : C
// Datum     : 22.11.2011
// Version   : test
// Autor     : hf
//----------------------------------------------------------------------
#define F_CPU 3686400
#include <avr/io.h>
//----------------------------------------------------------------------
#define LED_green_PC4_toggle PORTC ^= ( 1 << PC4 )
#define LED_yellow_PC5_toggle PORTC ^= ( 1 << PC5 )
//----------------------------------------------------------------------
//----------------------------------------------------------------------
void config_output(void)
{
  DDRC = ((1<<PC4) | (1<<PC5));  // Pins PCx als Ausgang
}
//----------------------------------------------------------------------
//------------ M A I N -------------------------------------------------
//----------------------------------------------------------------------

void main(void)
{
  uint8_t i=0,j=0;

  config_output();

  // Timer 0 konfigurieren
  TCCR0 |= (1<<CS00)|(1<<CS02);   // Timer 0 mit Prescaler 1024

                                  // (3686400/1024)/256 Hz = 14,0625Hz
                                  // bzw.  1/14,0625 s = 71,1 ms

  while (1)
  {
    // Variante 1 mit Overflow Flag

    if (TIFR & (1<<TOV0))    // das sieht so aus,
    {                        // als würde es richtig blinken ca. 1s

      TIFR |= (1<<TOV0);     // Overflow Flag mit "1" löschen
      i++;
      if (i>14)
      {
        i=0;
        LED_green_PC4_toggle;
      }
    }

    // Variante 2 mit Timerzählregister

    if (TCNT0==255)         // das blinkt zu schnell ca.0,6-0,7s
    {                       // wieso ???
      j++;
      if (j>14)
      {
        j=0;
        LED_yellow_PC5_toggle;
      }
    }
  }
}
//---------------------------------------------------------------------- 
--

von Oliver (Gast)


Lesenswert?

>   if (TCNT0==255)

wird für mehrere Schleifendurchläufe hintereinander wahr bleiben, damit 
zählt dein Zähler verkehrt.

Oliver

von Stefan E. (sternst)


Lesenswert?

Harald Fine schrieb:
> if (TCNT0==255)         // das blinkt zu schnell ca.0,6-0,7s
>     {                       // wieso ???

Weil der Timer bei einem Prescaler von 1024 eben 1024 Takte lang 255 
ist. In dieser Zeit wird dein if mehrmals erreicht und ist dann auch 
mehrmals hintereinander true.

von Sergej (Gast)


Lesenswert?

Stefan Ernst schrieb:
> ich bin mich gerade am Einarbeiten mit dem Atmega8

Deutscher oder Ausländer ?

von Düsendieb (Gast)


Lesenswert?

Noch besser ist ein Timer 0 Interrrupt:


ISR (TIMER0_OVF_vect)             //
{
LED_yellow_PC5_toggle;
TCNT0 = 0;    // Die Null könnte man sich auch sparen, aber dann kann 
man hier auch andere Werte eingeben.
}


dann muss aber noch in der Initialisierung der Interrupt freigegeben 
werden:

  // Timer 0 konfigurieren
  TCCR0 |= (1<<CS00)|(1<<CS02);   // Timer 0 mit Prescaler 1024

                                  // (3686400/1024)/256 Hz = 14,0625Hz
                                  // bzw.  1/14,0625 s = 71,1 ms

sei();   // hier wird das gemacht.

von Stefan E. (sternst)


Lesenswert?

Sergej schrieb:
> Stefan Ernst schrieb:
>> ich bin mich gerade am Einarbeiten mit dem Atmega8
>
> Deutscher oder Ausländer ?

Wie wäre es, wenn du erst mal selber richtiges Zitieren lernen würdest, 
bevor du dich über die Grammatik anderer her machst?

von Karl H. (kbuchegg)


Lesenswert?

Nur der Vollständigkeit halber
1
     TIFR |= (1<<TOV0);     // Overflow Flag mit "1" löschen

ist falsch. Das würde alle gesetzten Flags löschen.
Richtig ist
1
     TIFR = (1<<TOV0);     // Overflow Flag mit "1" löschen

von Harald F. (hfine)


Lesenswert?

Vielen Dank, Problem erkannt.
Ich werde an meiner Grammatik arbeiten. Ich bin kein Ausländer sondern 
Saarländer und bitte daher um Nachsicht.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.