Forum: Mikrocontroller und Digitale Elektronik ATMEGA128 Timer


von Markus (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Leute,

ich hab hier ein Problem und komme nicht weiter. Mittlerweile werk ich 
schon ein paar Tage daran. Auch google und das Forum können mir 
irgendwie nicht weiterhelfen.

Ich möchte eine Uhr bauen und hab mir dazu ein RTC-Projekt aus dem Forum 
runter geladen. Jetzt muss ich es natürlich auf meinen Controller und 
meinen Takt anpassen. Die Uhrzeit möchte ich dann auf dem LCD ausgeben.

Ich hab mein komplettes Projekt angehängt, weil ich mir nicht ganz 
sicher bin, ob mein Problem ausschließlich mit dem Timer zusammen hängt.

Hier mal meine Beschreibung:

Ich verwende einen ATMEGA128 mit einem 14.7456MHz Quarz. Ich stelle also 
meinen Timer auf einen Prescaler von 1024 ein. Das heißt, mein Timer 
würde 14400 mal in der Sekunde auslösen. OCR0 hab ich auf 144 gesetzt. 
Der Timer löst 100 mal Pro Sekunde aus -> also ein mal pro ms. Jetzt 
erhöhe ich pro Interupt meinen Counter um 1 und wenn dieser 100 erreicht 
hat, wäre eigentlich eine Sekunde verstrichen.

Hier mal ein Auszug aus meinem Code:
1
void rtcInit(void) {
2
         // ... hier Steht noch anderer Code
3
  // Timer initialisieren
4
  TCCR0 = RTC_TPS_VAL;
5
  OCR0 = RTC_TCOMP_VAL;
6
  TIMSK |= (1<<OCIE0);
7
  sei();
8
}
9
10
ISR(SIG_OUTPUT_COMPARE0){
11
  TCNT0 -= RTC_TCOMP_VAL;
12
       
13
    // Zeit inkrementieren
14
    if(++rtcTime.subSec >= RTC_IRQS_SEC) {
15
      rtcTime.subSec = 0;
16
      rtcTime.sec++;
17
    }
18
         //... der Restliche Code zum berechnen der Zeit
19
         //if(rtcTime.sec >= 60) {...
20
}
21
22
void main(void) {
23
     //... Code
24
     rtcInit();
25
26
     //... Code
27
     char Buffer[20];
28
     sprintf(Buffer, "%.2d:%.2d:%.2d.%.3d", rtcTime.hour,
29
          rtcTime.min,
30
          rtcTime.sec,
31
          rtcTime.subSec);
32
33
     lcd_string(Buffer);
34
}

Ich hoffe, Ihr könnt mir weiter helfen.

Danke, Markus

von Markus (Gast)


Lesenswert?

ja ... klar ... hab mein Problem vergessen ... entschuldigt:

Der Timer läuft viel zu schnell. Wenn die Uhr in Wirklichkeit ca. 20 
Sekunden läuft, wird eine Zeit von ca. 3 Minuten angezeigt.

von Markus (Gast)


Lesenswert?

... und hier noch meine Definition ... ich weiß nicht, was heute mit mir 
los ist ...
1
#define RTC_IRQS_SEC    100
2
#define RTC_TCOMP_VAL    144
3
#define RTC_TPS_VAL    (1<<CS00) | (1<<CS02) //1024

von Stefan B. (stefan) Benutzerseite


Lesenswert?

144 Schritte erfordern eine Grenze von 143 (Wert für OCR0).
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR#CTC-Betriebsart_.28Clear_Timer_on_Compare_Match.29

>   TCNT0 -= RTC_TCOMP_VAL;
Das solltest du nicht machen. Das ist im CTC-Modus (Auto-Reload) 
kontraproduktiv.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR#CTC_Clear_Timer_on_Compare_Match_.28Auto_Reload.29

Die Initialisierung des CTC-Modus vermisse ich zum Teil.

Läuft dein Atmega128 tatsächlich mit 14.7456MHz? Wenn nicht, kann das 
Programm nicht korrekt laufen. Ein einfacher Test ist ein Blinkdemo 
einer LED im 1s Takt mit einer Warteschleife. Wenn das 1 Min läuft 
sollte man 60 Blinkzyklen zählen können. Sind es nur 4 ist was faul ;-)

von Oliver J. (skriptkiddy)


Lesenswert?

@Markus:
Warum verwendest du nicht den CTC-Modus? Der ist doch gerade zu 
prädestiniert für deinen Anwendungsfall.

Gruß Skriptkiddy

von Markus (Gast)


Lesenswert?

Ja, klar, 143 ... geht ja bei 0 los. Aber das erklärt nicht den großen 
Unterscheid.

Ich denke, das mit der LED kann ich mir schenken. Ich weiß, dass was 
faul ist ;o) ... sagt mir mein LCD ... oder meinst Du, alles andere erst 
mal raus-schmeißen?

Hmm ... warum sollte mein Controller nicht mit 14.745 MHz laufen? Auf 
dem Quarz stehts drauf (also glaub ich das mal). Die Fuse-Bits sollten 
auch passen CKSEL0, 1, 2 und 3 sind auf 1

von spess53 (Gast)


Lesenswert?

Hi

>#define RTC_TPS_VAL    (1<<CS00) | (1<<CS02) //1024

->#define RTC_TPS_VAL    (1<<WGM01) | (1<<CS00) | (1<<CS02) //1024

  uns diese Zeile '  TCNT0 -= RTC_TCOMP_VAL;' raus.

MfG Spess

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Die Fusebitinfo hast du jetzt erst gegeben.

Nicht rauswerfen. Ich schreibe für kleine Unterfragen gerne ein 
Miniprogramm.

Der große Unterschied kommt (wenn CTC richtig initialisiert ist) durch 
deine Manipulation des Timerzählers in der ISR.

In dem Moment der ISR setzt der AVR den Zähler auf 0. Du ziehst 144 ab. 
Der Zähler steht also auf 112 und läuft hoch. Gleichzeitig steht OCR0 
auf 144 und wartet auf den nächsten Match. Du hast also alle (144-112 = 
33) 34 Takte einen Interrupt statt alle 143 Takte. Du warpst also mit 
Level 4,2!

von Markus (Gast)


Lesenswert?

Das mit dem "Rauswerfen" war eher gemeint mit "ein Programm, das nur 
eine LED zum blinken bringt und sonst nix" ;o)

Ja, das mit dem TCNT0 -= ... ist mir klar. Ich habe nur vergessen, es 
raus zu nehmen, weil ich den Timer auch anders probiert hab, nicht als 
Comp.
1
#define RTC_TPS_VAL    (1<<WGM01) | (1<<CS00) | (1<<CS02) //1024

hat leider auch nicht viel gebracht.

Der Timer läuft immer noch viel zu schnell ...

30 Sekunden in Echt entsprechen ca. 4 Minuten am uC ... (hab ich eine 
Zeitmaschine erfunden? ;o) ... das wäre als etwa Faktor 8.
Hmm ... 8 ... kommt mir ein wenig komisch vor, dass es genau 8 ist ... 
passt vielleicht irgendein Prescaler oder so nicht?


Ich könnte natürlich meine Zähler und dergleichen so lange anpassen, bis 
ich auch mein gewünschtes Ergebnis kommt, aber das kann doch nicht die 
Lösung sein, oder?

von Markus (Gast)


Lesenswert?

Ich denke, ich hab den Fehler gefunden. So funktionierts:
1
#define RTC_TPS_VAL  (1<<WGM01) | (1<<CS00) | (1<<CS01) | (1<<CS02)

Aber laut Datenblatt heißt das doch, dass Clock von einer externen 
Quelle kommt ... kann das sein, dass im Datenblatt da ein Fehler drinnen 
ist ... kann ich mir nicht vorstellen.

Aber hier mal der Link

http://www.atmel.com/dyn/resources/prod_documents/doc2467.pdf

auf Seiten 158 / 159

von Oliver J. (skriptkiddy)


Lesenswert?

Markus schrieb:
> Ich denke, ich hab den Fehler gefunden. So funktionierts:
> #define RTC_TPS_VAL  (1<<WGM01) | (1<<CS00) | (1<<CS01) | (1<<CS02)

Normal dürfte das so nicht funktionieren, weil für einen Prescaler von 
1024 lediglich CS00 und CS02 gesetz werden müssen, wie du ja schon 
richtig aus dem Datenblatt abgelesen hast. Mit CS01 zusätzlich wählst du 
einen externen Takt aus.


Gruß Skriptkiddy

von Markus (Gast)


Lesenswert?

Ja, ich weiß ... ich versteh das auch nicht ganz. Aber wenn ich nur CS00 
und CS02 setze, dann komm ich (rechnerisch) auf einen Prescaler von 128 
-  einen solchen sollte es aber eigentlich nicht geben.

Mein Prozessor ist ein ATMEGA128 16AU, kannst damit was zu tun haben? 
Eher nicht, oder?

Jetzt haben mich die Timer vorher schon ein wenig verwirrt, aber das 
gibt mir jetzt endgültig den Rest ;o)

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Table 56. Clock Select Bit Description
CS02 CS01 CS00 Description
0 0 0 No clock source (Timer/Counter stopped)
0 0 1 clkT0S/(No prescaling)
0 1 0 clkT0S/8 (From prescaler)
0 1 1 clkT0S/32 (From prescaler)
1 0 0 clkT0S/64 (From prescaler)
1 0 1 clkT0S/128 (From prescaler)
1 1 0 clkT0S/256 (From prescaler)
1 1 1 clkT0S/1024 (From prescaler)     <================


===============>
#define RTC_TPS_VAL  ((1<<WGM01) | (1<<CS00) | (1<<CS01) | (1<<CS02))
WGM01 siehe Table 52 Mode 2 CTC

von spess53 (Gast)


Lesenswert?

Hi

Stefan B. schrieb:
> Table 56. Clock Select Bit Description...

Aber nicht beim Timer0 vom ATMega128:

Table 68. Clock Select Bit Description

CS02 CS01 CS00 Description
  0   0    0   No clock source (Timer/Counter stopped)
  0   0    1   clkI/O/(No prescaling)
  0   1    0   clkI/O/8 (From prescaler)
  0   1    1   clkI/O/64 (From prescaler)
  1   0    0   clkI/O/256 (From prescaler)
  1   0    1   clkI/O/1024 (From prescaler)
  1   1    0   External clock source on T0 pin. Clock on falling edge
  1   1    1   External clock source on T0 pin. Clock on rising edge

@Markus (Gast)

Hast du auch den richtigen Controller eingestellt?

MfG Spess

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Table 68 gilt für Timer/Counter2
                               ^

Table 56 für Timer/Counter0 (TCCR0...)
                          ^

(Mein Datenblatt ist Rev. 2467R–AVR–06/08)

von soundsou (Gast)


Lesenswert?

Zitat: Der Timer löst 100 mal Pro Sekunde aus -> also ein mal pro ms.

denk das nochmals durch, vieleicht liegt auch hier der hund begraben :-)

von Markus (Gast)


Lesenswert?

Du meinst im Makefile? Ja, eigentlich schon.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Stimmt in Rev. 2464U–AVR–08/10 ist "lustigerweise" die Reihenfolge der 
Inhalte

...,Timer2, Timer1, Timer0,...

in meinem alten Datenblatt ist die Reihenfolge

...,Timer0, Timer1, Timer2,...

Daher schon mal die unterschiedliche Tabellennummer.

Wenn aber wie oben geschrieben die Zeile
#define RTC_TPS_VAL  ((1<<WGM01) | (1<<CS00) | (1<<CS01) | (1<<CS02))
zu einem funktionierenden Programm führt, wird das neue Datenblatt wohl 
einen Fehler haben.

So ein Kuddelmuddel, ich behalte mal mein altes Datenblatt :-)

von Justus S. (jussa)


Lesenswert?

Stefan B. schrieb:
> Table 68 gilt für Timer/Counter2
>                                ^
>
> Table 56 für Timer/Counter0 (TCCR0...)
>                           ^
>
> (Mein Datenblatt ist Rev. 2467R–AVR–06/08)

ich hab mir grad das Datenblatt für den ATmeag128(L) auf der Atmel-Seite 
geholt und da ist Tabelle 68 für Timer0...

Rev. 2464U–AVR–08/10

von spess53 (Gast)


Lesenswert?

Hi

>(Mein Datenblatt ist Rev. 2467R–AVR–06/08)

Meins Rev. 2464U–AVR–08/10

Und die Tabelle 56 befindet sich bei mir im Kapitel zu Timer2

Table 56. Clock Select Bit Description
CS22 CS21 CS20....

MfG Spess

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Die Datasheet Revision History behandelt das Thema überhaupt nicht :-(
Im Anhang die ältere Version.

von Stefan B. (stefan) Benutzerseite


Angehängte Dateien:

Lesenswert?

Mist beim Bearbeiten kann man nix anhängen.
Also hier die ältere Version...

von spess53 (Gast)


Lesenswert?

Hi

>Die Datasheet Revision History behandelt das Thema überhaupt nicht :-(

Ich kann aber gern heute Abend mal in meiner Sammlung von ATMEL-CDs 
nachsehen. Allerdings hat deine Angabe eine andere Dokumentennummer:

Rev. 2467R–AVR–06/08
        ^
Rev. 2464U–AVR–08/10
        ^

Im Partdescriptionfile ist der Prescaler allerdings wie in deinem 
'alten' Datenblatt:

<....      1 2 3  4   5   6    7
<Prescaler>1:8:32:64:128:256:1024</Prescaler>
</TIMER0>

Mystisch

MfG Spess

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Smile :-)

An der Dokumentnummer habe ich mich auch schon detektivisch ausgelassen.

Man zieht ja vom Atmelserver die doc2467.pdf
                                       ^

Und das passt auch gut zu der Rev. Nummer des alten Datenblatts.

Jetzt hat das neuste Datenblatt die Rev. Nummer 2464... Was könnte die 
doc2464.pdf sein? Es lohnt nicht das auszuprobieren. Es ist eine Appnote 
die mit diesem Thema nix zu tun hat. vermutlich ist es ein weiterer 
Fehler beim Update der Rev.-Nummer.

Mönsch, wenn Atmel das Knuth Versprechen machen würde, wäre ich heute 
reich geworden.

von spess53 (Gast)


Lesenswert?

Hi

Gute Nachricht: Das aktuelle Datenblatt vom ATMega128 ist korrigiert.

MfG Spess

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.