Forum: Mikrocontroller und Digitale Elektronik AT91SAM7x RTT zu schnell


von Andy (Gast)


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:
1
inline void RTC_ISR(void)
2
{
3
  // Status lesen -> IRQ zurücksetzen
4
  unsigned long Status = *AT91C_RTTC_RTSR;
5
  if(Status==0) { return; }
6
7
  // Status auswerten
8
  if(Status & AT91C_RTTC_RTTINC) {          // Timer inkrement
9
    InkrementTime();
10
  }
11
  if(Status & AT91C_RTTC_ALMS) {            // Alarm
12
  }
13
14
  // DEBUG
15
  //DBGU_WriteByte(Zeit.sec%10 + 48);
16
  //DBGU_WriteByte(13);
17
}
18
//-----------------------------------------------------------------------------
19
inline void InkrementTime(void)
20
{
21
  // Echtzeit-Uhr weiterzählen
22
  Zeit.sec++;              // Sekunden
23
  if(Zeit.sec==60) {
24
    Zeit.sec = 0;
25
    Zeit.min++;            // Minuten
26
    if(Zeit.min==60) {
27
      Zeit.min = 0;
28
      Zeit.hour++;        // Stunden
29
      if(Zeit.hour==24) {
30
        Zeit.hour = 0;
31
        InkrementDate();
32
      }
33
    }
34
  }
35
36
  // LED blinken
37
  if(Zeit.sec & 1) {
38
    LED_gelb_on();
39
  }
40
  else {
41
    LED_gelb_off();
42
  }
43
}
44
//-----------------------------------------------------------------------------
45
inline void InkrementDate(void)
46
{
47
  // Wochentag inkrementieren
48
  DOW++;
49
  if(DOW==7) {
50
    DOW=0;
51
  }
52
53
  // Datum imkrementieren
54
  Datum.day++;
55
  if(Datum.day>MaxDoM[Datum.day]) {
56
    Datum.day = 1;
57
    Datum.month++;
58
    if(Datum.month>12) {
59
      Datum.month = 1;
60
      Datum.year++;
61
    }
62
  }
63
}

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

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.