Forum: Mikrocontroller und Digitale Elektronik STK 500, Timer, Quarzfrequenz


von Onur Demir (Gast)


Lesenswert?

Hallo,

ich habe mir ein STK500 zugelegt, habe schon die LEDs aus- und
einschalten, und die Tasten bedienen können. Soweit so gut. Um mich
weiter in diese Thematik einarbeiten zu können, möchte ich in Assembler
ein Timer realisieren, der die Aufgabe haben soll, alle LEDs an Port B,
in einem Abstand von einer Sekunde aufleuchten soll.

Eifrig wie ich bin, began ich mit der Programmierung, Beispiele gibt es
ja genug. Hat aber nicht geklappt. Am Ende kam ich dann zu dem
Entschluss, dass ich weder wusste, ob der interne Oszillator durch die
Einstellungen vom AVRStudio beeinflusst wird, noch, mit was für eine
Frequenz der Mega8515 wirklich läuft.

Ziel war die Realisierung über den Timer0 und einem 1024'er Prescaler,
nach dem Code von der Seite: "gnomsoft" (Code kann ich anhängen, wenn
gewünscht wird).

Irgendwie, war ich mir am gestrigen Abend so garnicht mehr sicher, was
da lief. Die Breakpoints in der Timerroutine wurden nie
beansprucht.......

Naja, vielleicht können wir ja step-by-step mit der Ursachenforschung
beginnen:

1. Stimmt es, dass nach dem manual vom STK500 die interen Quarzfrequenz
für den Mega8515 by 3,096MHz liegt?

2. Wenn ich im AVRStudio eine Frequenz von 4MHz einstelle, wird dieser
beim Flashen automatisch an den Prozessor mitgeteilt?

3. Ist eine "1s" Timer Realisierung mit einem 8Bit Timer, bei 4MHz
überhaupt möglich?

4. Letzte Frage, der Stack vom Mega8515 besteht immer aus zwei 16Bit
Registern?

Vielleicht komme ich dann einige Schritte weiter.

Danke für die Antworten im Voraus.

Gruß

Onur

von Jens D. (Gast)


Lesenswert?

Also:

Zu deinem TImer Problem haengst du besser den Code an, da kann man
besser helfen..

>>1. Stimmt es, dass nach dem manual vom STK500 die interen
>>Quarzfrequenz
>>für den Mega8515 by 3,096MHz liegt?
Ich glaube du meinst die Frequenz, mit der dein ISP (Programmiergeraet
arbeitet)

>>2. Wenn ich im AVRStudio eine Frequenz von 4MHz einstelle, wird
>>dieser
>>beim Flashen automatisch an den Prozessor mitgeteilt?
Fast:
Du hast fuses (einstellungen im controler) wie zB. welche Clock genutzt
werden soll und noch ein paar andere dinge.
Da waehlst du (wenn vorhanden) externer Quarz Oazilator und dann laeuft
der Controler auf den extern bestuecktem Quarz. Die Fuses sind dann im
Controler, wenn Du unten write drueckst (mit read kannst Du sie
auslesen)

>3. Ist eine "1s" Timer Realisierung mit einem 8Bit Timer, bei 4MHz
>überhaupt möglich?
Jein
Du kannst die 4MHz durch 1024 teilen macht 3906,25 das ganze nocheinmal
durch 256 (timer register) macht 15,258 impulse die Sekunde
nun laesst du ein register immer bis 15 zaehlen und hast so eine fast
genaue sekunde.
Wenn du es genau haben willst brauchst du einen 2ten quarz 32,786kHz
dieser laesst sich dann auf eine sekunde teilen..

>>4. Letzte Frage, der Stack vom Mega8515 besteht immer aus zwei 16Bit
>>Registern?
Da bin ich mal vorsichtig..
Ich meine der Stack ist auch in 8Bit registern egspeichert, welche aber
zusammengefasst werden, und somit ein "16 Bit register" zur verfuegung
steht..

ldi temp, LOW(RAMEND)             ; LOW-Byte der obersten RAM-Adresse
         out SPL, temp
         ldi temp, HIGH(RAMEND)            ; HIGH-Byte der obersten
RAM-Adresse
         out SPH, temp
Evtl mal lesen :) http://www.mikrocontroller.net/tutorial/stack

Gruss

von Rahul D. (rahul)


Lesenswert?

1. Weiß ich nicht, lässt sich aber mit dem AVRStudio herausfinden.
Normalerweise arbeitet das STK500 mit 3,68MHz, einer Baudratenfrequenz.
Die Frequenz des 8515-internen-Oszillators weiß ich auch nicht; ist aber
meistens gerade (1MHz, 4 MHz oder 8MHz...)

2. 4MHz geht nicht mit dem STK500. 3,68MHZ ist die Obergrenze des
Oszillators. Mit dem externen Quarzsockel kann man die Geschwindigkeit
(mit Hilfe eines schnelleren Quarzes) erhöhen.

3. Muß du selbst errechnen...

4. Ich programmiere leider in C... Der Stack selbst besteht aus einem
"Stapel" ("Kellerspeicher...") von aufeinanderfolgenden Adressen.
Die Adressen, die man dem Assembler übergibt (2Stück á 16bit), sind
IMHO die Adressen wo der Stack im Speicher beginnt, und wo er aufhören
muß, weil er sonst in den Datenbereich hineinwachsen würde.

Das Datenblatt ist immer dein Freund, solange es Complete und nicht nur
Summery ist.

Übrigens hilft die AVRStudio-Hilfe auch...

von A.K. (Gast)


Lesenswert?

Wenn es der mitgelieferte 8515 ist, dann dürfte das kein Mega sondern
ein AT90S8515 sein, und der hat keinen internen Oszillator.

von Onur Demir (Gast)


Lesenswert?

Hallo,

erst einmal Danke für die Antworten. Beim STK war der Mega8515 dabei.
Laut DB wird der im 1MHz Zustand geliefert. Also besitzt der einen
internen Oszillator, was für mich für den Anfang genügt.

Aufgrund der STK Frequenz, kann ich keine höhere interne Frequenz als
die öminösen 3,86MHz einstellen? Wir sprechen hier nur von der internen
Frequenz. Ein externer Quarz soll erst später folgen.

Also gehe ich mal davon aus, dass der Prozessor mit 1MHz läuft. Die
Timerprogrammierung möchte ich selber machen.

Wenn diese Fragen geklärt sind, wende ich mich der Timer Programmierung
zu.

Gruß

Onur

von Jens D. (Gast)


Lesenswert?

Die 3,86MHz hat nichts mit der Frequenz von der MCU zu tun.
Du kannst den Internen RC Oszilator auf 8MHz einstellen (siehe Fuse
Bits)
oder Externer Oszilator bis 16MHz
Du musst nur darauf achten, dass die Frequenz zum Programmieren maximal
halb so gross ist, wie die mit der die MCU getaktet ist (wenn ich es so
in erinnerung habe)
Gruss Jens

von Sebastian (Gast)


Lesenswert?

Der Takt der MCU muß mindestestens 4 mal so hoch sein wie der ISP-Takt
meine ich irgendwo gelesen zu haben. --> 4 MHZ MCU wären dann max 1 MHZ
für ISP (Programmierung)

von Olaf K. (Gast)


Lesenswert?

Zur Frage der genauen Sekunde:

Man kann auch bei beliebiger Quarzfrequenz, 8-bit-Timer und großem
Prescaler eine im Mittel bis zu subclockgenaue Sekunde hinbekommen:

Angenommen, der Quarz hat 4000123Hz, und man verwende einen 8-Bit-Timer
mit Prescaler 1024 und OVF-Interrupt (d.h. aller 256 Ticks).

Um in der OVF-Interrupt-Routine eine genaue Sekunde abzuzählen, müßte
man also bis 15.25925827... zählen. Dieser Vergleichswert geht aber
nicht, man kann ja nur ganze Zahlen abzählen.

Mit einem Trick geht es doch: Man verwendet zur Berechnung der Sekunde
immer einen neuen Vergleichswert, d.h. man springt zwischen den beiden
ganzen Vergleichswerten hin und her, wo der krumme Vergleichswert
dazwischen liegt.

Wenn man abwechselnd bei Ende jeder "Sekunde" zwischen 15 und 16 als
Vergleichswert wechselt, ist der Vergleichswert im Mittel bei 15.5.

Wenn man nur einmal in 4 Sekunden den Vergleichswert 16 und ansonsten
15 verwendet, ist man schon bei effektiv 15.25 (= 15 + 1/4)
Die Gangabweichung pro Sekunde läge damit bei 0.6ms oder ca. 1
Minute/Tag.

Das kann man weiter verfeinern: Man verwendet einen 16-bit-Zähler
(0..65535), der die OVF-Interrupts zählt, und setzt in Abhängigkeit vom
Zählerstand als Vergleichswert 15 oder 16. Wenn man in einem
Zählerumlauf 16991-mal den Wert 16 und 48545-mal den Wert 15 verwendet,
ist die mittlere Sekunde bereits auf 0.25µs genau, d.h. wenn die
Quarzfrequenz präzise ist, dann beträgt die Gangabweichung in diesem
Beispiel nur noch ca. 8 Sekunden/Jahr. Das dürfte bereits deutlich
genauer sein, als es der Quarz ohnehin zuläßt.

Wie komm ich auf 16991?
Um im Mittel 15.259258... zu erreichen, müssen von 65536
Vergleichswerten 0.259258..- mal 16 sein, der Rest 15.
65536 * 0.259258 = 16990.75, also rund 16991.

Man kann die Vergleichswerte einfach so bilden, daß immer, wenn der
Zähler <=16990 ist, die 16 genommen wird, drüber die 15. Da der
16-bit-Timer 18 Stunden für einen Umlauf braucht, führt das aber dazu,
daß die Uhr ein paar Stunden kräftig nachgeht, um dann langsam wieder
aufzuholen, bis sie nach 18 Stunden wieder genau geht. Will man das
vermeiden, muß man sich einen Algorithmus einfallen lassen, der die
beiden Vergleichswerte gleichmäßiger verteilt, aber das Verhältnis
beibehält.

Mit dieser (oder ähnlicher) Methode läßt sich aus jeder beliebigen
krummen Quarzfrequenz eine im Mittel sehr genaue Sekunde basteln. Mit
16-bit-Timer und kleinem Prescaler erreicht man auch mit kurzem Zähler
mit Leichtigkeit Subclockgenauigkeit.

Man kann Clockgenauigkeit auch durch Verwendung eines Timers ohne
Prescaler erreichen, indem man die Clocks direkt abzählt und einmal pro
Sekunde einen anderen Compare- bzw. Startwert verwendet, aber erkauft
dies mit entsprechend häufigen Timerinterrupts.

MfG Olaf

MfG Olaf

von Onur Demir (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

die folgenden Einstellungen habe ich bei mir:

- Prozessor Mega8515,
- bei den Fuses ist der default Wert: interner RC Oszillator 1MHz
(Start-up time6CK+64ms) eingestellt

Im Anhang ist der konfigurierte Code für den Timer1. Ziel soll sein,
dass die LEDs, alle am PortB, alle 3 Sekunden leuchten.

Also 1MHz/1024 = 976 -> durch die gewünschte Periodendauer, also / 1/3
= 62260. Das ist mein Startwert.

Eigentlich müsste es doch klappen. Oder?

Gruß

Onur

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.