ATMEGA128 Timer

Gast #1967563
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
Angehängte Dateien:
Persönliche Seite #1967574
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 ;-)
Gast #1967599
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
Persönliche Seite #1967611
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!
Gast #1967640
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?
Gast #1967666
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
#1967687
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
Gast #1967703
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)
Persönliche Seite #1967741
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
Gast #1967758
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
Persönliche Seite #1967799
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 :-)
Gast #1967806
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
Gast #1967831
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
Persönliche Seite #1967844
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.

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