Rechenfehler Timerberechnung, Mega128

OP #1634464
Lesenswert?

Hi Leuts, ich habe hier irgendwie einen Rechenfehler, vielleicht kann 
mir jemand helfen:
Ich habe einen Mega128 mit 16 MHz Quarz. Nun möchte ich Timer2 so 
konfigurieren, dass im Abstand von 1 ms ein Interrupt (ich habe mal den 
Compare genommen) ausgelöst wird. Zum Test lasse ich mal eine LED 
blinken. Prinzipiell funktioniert der Code, aber das mit der 1 ms haut 
nicht hin. Derzeit blinkt die LED vielleicht alle 500 ms (geschätzt). 
Ich rechne folgendermaßen:
Bei 16 MHz stelle ich einen Prescaler von 128 ein, womit ich bei 125 kHz 
bin. Das entspricht einer Periodendauer von 8 µs. Wenn ich dann bis 125 
zähle bin ich bei genau 1 ms.
Wo liegt mein Rechenfehler ?

int main()
{
  DDRG = 0xff;   // fuer die LED

  // CTC-Mode einstellen
  TCCR2 =0;
  TCCR2 |= (1<<WGM21) | (0<<WGM20);

  // Prescaler einstellen 128
  TCCR2 |= (1<<CS00) | (1<<CS02);

  // CTC-Vergleichswert
  OCR2 = 125;
  // Compare-Interrupt aktivieren
  TIMSK |= (1<<OCIE2);
  liveled = 0;
  sei();

  while (1)
  {
      // LiveLED steuern
      if (liveled > 0)
      {
          liveled = 0;
    PORTG ^= (1<<PG4);
            }
  }
  return 1;
}

ISR(TIMER2_COMP_vect)
{
  liveled++;
}
Gast #1634479
Lesenswert?

Hi

>Bei 16 MHz stelle ich einen Prescaler von 128 ein,

Hat der Timer nicht.

TCCR2 |= (1<<CS00) | (1<<CS02);   <- Fehler

Abgesehen, das es CS20/CS22 heissen muss, stellt das beim Timer2 einen 
Vorteiler von 1024 ein.

MfG Spess
OP #1634490
Lesenswert?

Stimmt. Aber wenn ich über 64 gehe und bis 250 zähle passiert gar nix 
mehr.
int main()
{

  DDRG = 0xff;

  // 16 bit Counter
//  TCNT2 = 65536-125;    /* aktuellen Zaehlerstand setzen */

  // Einstellungen definieren
//  TCCR2 = 0;

  // Takt = CPU Takt / 128
//  TCCR2 |= (1<<CS00) | (1<<CS02);

  // Normalmode
//  TCCR2 |= (0<<WGM00) | (1<<WGM01) | (0<<COM01) | (0<<COM00);

  // Enable Overflowinterrupt
//  TIMSK |= (1<<TOIE2);
//  TIMSK |= (1<<OCIE0A);

  // CTC-Mode einstellen
  TCCR2 =0;
  TCCR2 |= (1<<WGM21) | (0<<WGM20);

  // Prescaler einstellen 64
  TCCR2 |= (1<<CS20) | (1<<CS21) | (0<<CS22);

  // CTC-Vergleichswert
  OCR2 = 250;
  // Compare-Interrupt aktivieren
  TIMSK |= (1<<OCIE2);
  // Hilfszaehler loeschen
  liveled = 0;
  sei();

  while (1)
  {

    // LiveLED steuern
    if (liveled > 1000)
    {
      liveled = 0;
      PORTG ^= (1<<PG4);
    }
  }
  return 1;
}
OP #1634530
Lesenswert?

volatile uint8_t liveled=0;

int main()
{

  DDRG = 0xff;

  // CTC-Mode einstellen
  TCCR2 =0;
  TCCR2 |= (1<<WGM21) | (0<<WGM20);

  // Prescaler einstellen 64
  TCCR2 |= (1<<CS20) | (1<<CS21) | (0<<CS22);

  // CTC-Vergleichswert
  OCR2 = 250;
  // Compare-Interrupt aktivieren
  TIMSK |= (1<<OCIE2);
  // Hilfszaehler loeschen
  liveled = 0;
  sei();

  while (1)
  {

    // LiveLED steuern
    if (liveled > 10)
    {
      liveled = 0;
      PORTG ^= (1<<PG4);
    }
  }
  return 1;
}



ISR(TIMER2_COMP_vect)
{
  liveled++;
}

Bitte, aber ich denke wie gesagt an einen Denkfehler bei mir :-)
OP #1634635
Lesenswert?

Oh shit, bin ich doof. Da hast Du natürlich recht, aber leider hilft es 
nix.
Der aktuelle Stand ist so, dass die Led ca. alle 1.5 s blinkt. Bei 
folgendem Code:

volatile uint16_t liveled=0;

int main()
{

  DDRG = 0xff;

  // CTC-Mode einstellen
  TCCR2 =0;
  TCCR2 |= (1<<WGM21) | (0<<WGM20);

  // Prescaler einstellen 64
  TCCR2 |= (1<<CS20) | (1<<CS21) | (0<<CS22);

  // CTC-Vergleichswert
  OCR2 = 250;
  // Compare-Interrupt aktivieren
  TIMSK |= (1<<OCIE2);
  // Hilfszaehler loeschen
  liveled = 0;
  sei();

  while (1)
  {

    // LiveLED steuern
    if (liveled > 100)
    {
      liveled = 0;
      PORTG ^= (1<<PG4);
    }
  }
  return 1;
}

/////////////////////////////////////////////////////////////////
//
//
/////////////////////////////////////////////////////////////////
ISR(TIMER2_COMP_vect)
{
  liveled++;
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren