mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AT91SAM7x RTT zu schnell


Autor: Andy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,
irgendwie stehe ich momentan total auf dem Schlauch mit dem Real-time 
Timer des AT91SAM7x256.
Ich möchte mit dem Timer eine Echtzeit-Uhr basteln. (Ja ich weiß, läuft 
von RC, nix gut bei Temperatur-Schwankungen etc. Der Timer wird später 
über DCF77 gestellt). Als ich die Routinen gebastelt habe, habe ich bei 
jedem RTT-IRQ eine LED ein- bzw. ausgeschaltet. Das funzte auch, die LED 
blinkte mit ~0,5Hz.

Jetzt habe ich die "Echtzeit"-Uhr ergänzt und lese die Uhrzeit mit einem 
Terminal-Programm aus. DCF77 ist noch nicht dran.
Problem: Die Uhr zählt anscheinend in 5er-Schritten hoch. Zumindest 
kriege ich bei jedem Auslesen x0 oder 05 Sekunden - insgesamt läuft die 
Zeit auch um etwa diesen Faktor zu schnell.
Wenn ich in der ISR die Uhrzeit ausgeben lasse (DEBUG nicht 
auskommentiert), dann läuft plötzlich alles perfekt. Die Sekunden zählen 
normal hoch!
Wahrscheinlich ein total trivialer Fehler, aber ich habe irgendwie 
Tomaten im Hirn und Bohnen auf den Augen.   *lecker!*

Mein Code:
inline void RTC_ISR(void)
{
  // Status lesen -> IRQ zurücksetzen
  unsigned long Status = *AT91C_RTTC_RTSR;
  if(Status==0) { return; }

  // Status auswerten
  if(Status & AT91C_RTTC_RTTINC) {          // Timer inkrement
    InkrementTime();
  }
  if(Status & AT91C_RTTC_ALMS) {            // Alarm
  }

  // DEBUG
  //DBGU_WriteByte(Zeit.sec%10 + 48);
  //DBGU_WriteByte(13);
}
//-----------------------------------------------------------------------------
inline void InkrementTime(void)
{
  // Echtzeit-Uhr weiterzählen
  Zeit.sec++;              // Sekunden
  if(Zeit.sec==60) {
    Zeit.sec = 0;
    Zeit.min++;            // Minuten
    if(Zeit.min==60) {
      Zeit.min = 0;
      Zeit.hour++;        // Stunden
      if(Zeit.hour==24) {
        Zeit.hour = 0;
        InkrementDate();
      }
    }
  }

  // LED blinken
  if(Zeit.sec & 1) {
    LED_gelb_on();
  }
  else {
    LED_gelb_off();
  }
}
//-----------------------------------------------------------------------------
inline void InkrementDate(void)
{
  // Wochentag inkrementieren
  DOW++;
  if(DOW==7) {
    DOW=0;
  }

  // Datum imkrementieren
  Datum.day++;
  if(Datum.day>MaxDoM[Datum.day]) {
    Datum.day = 1;
    Datum.month++;
    if(Datum.month>12) {
      Datum.month = 1;
      Datum.year++;
    }
  }
}

Die ISR wird übrigens von der SYS-ISR (IRQ0) aufgerufen, daher das 
inline. Zeit und Datum sind volatile definiert.
Man muß den RTT doch nicht entprellen, oder?   ;)

Andy

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.