Discussion:
AVR ATmega 8: Interner RC-Oszillator läuft viel zu schnell
(zu alt für eine Antwort)
Michael Holzt
2005-08-05 16:03:05 UTC
Permalink
Ich habe ein seltsames Problem: Ich habe eine Schaltung mit einem ATmega 8
entwickelt. Da Platz eingespart werden muß, soll die Schaltung mit dem
internen RC-Oszillator bei 8 MHz laufen. Auf einem STK500 Board läuft das
alles auch einwandfrei.

Nun habe ich eine kleine Platine entwickelt, auf der ein ATmega8 im TQFP
Gehäuse sitzt. Wenn ich diese eigentlich korrekt programmiere, also die
Fuses entsprechend einstelle und auch das 8 MHz Kalibrationsbyte auslese
und durch mein Programm in OSCCAL schreiben lasse, dann scheint das Teil
nicht mit 8 MHz sondern deutlich schneller zu laufen.

Folgender Programmcode sollte eigentlich einmal pro Sekunde eine Portleitung
umschalten:

for(;;)
{
PORTD ^= 2;
for (uint8_t x=0; x<20; x++)
_delay_ms(50);
}

Was ich aber feststelle ist, daß in 10 Sekunden etwa 15 mal umgeschaltet
wird. Der Oszillator läuft also offenbar eher mit 12 MHz als mit 8 MHz. Ich
verstehe nicht, wie das sein kann.
--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Klaus Selver
2005-08-05 16:18:02 UTC
Permalink
Post by Michael Holzt
Ich habe ein seltsames Problem: Ich habe eine Schaltung mit einem ATmega 8
entwickelt. Da Platz eingespart werden muß, soll die Schaltung mit dem
internen RC-Oszillator bei 8 MHz laufen. Auf einem STK500 Board läuft das
alles auch einwandfrei.
Nun habe ich eine kleine Platine entwickelt, auf der ein ATmega8 im TQFP
Gehäuse sitzt. Wenn ich diese eigentlich korrekt programmiere, also die
Fuses entsprechend einstelle und auch das 8 MHz Kalibrationsbyte auslese
und durch mein Programm in OSCCAL schreiben lasse, dann scheint das Teil
nicht mit 8 MHz sondern deutlich schneller zu laufen.
Folgender Programmcode sollte eigentlich einmal pro Sekunde eine Portleitung
for(;;)
{
PORTD ^= 2;
for (uint8_t x=0; x<20; x++)
_delay_ms(50);
}
Was ich aber feststelle ist, daß in 10 Sekunden etwa 15 mal umgeschaltet
wird. Der Oszillator läuft also offenbar eher mit 12 MHz als mit 8 MHz. Ich
verstehe nicht, wie das sein kann.
12 Mhz geht eigentlich nur, wenn man 8 Mhz einstellt und mittels OSCCAL
den Takt weiter hochsetzt.
Versuch doch mal rauszukriegen, in welchem Bereich sich der Takt mit
OSCCAL ziehen lässt.
Im Datenblatt auf Seite 276 ist ein "Clock vs OSCCAL"-Diagramm drin.

-Klaus-
Klaus Selver
2005-08-05 16:20:24 UTC
Permalink
Sorry - Seite 271 ist besser...
Thomas Pototschnig
2005-08-06 10:11:53 UTC
Permalink
Post by Michael Holzt
for(;;)
{
PORTD ^= 2;
for (uint8_t x=0; x<20; x++)
_delay_ms(50);
}
Ich glaube mich daran zu erinnern, dass bei 8MHz nur maximal 35ms
Verzögerung mit _delay_ms erreichbar ist.
Kuck mal ins Header-File - da steht es nochmal genau drin.

Mfg
Thomas Pototschnig
www.oxed.de
Klaus Selver
2005-08-06 12:03:50 UTC
Permalink
Post by Thomas Pototschnig
Post by Michael Holzt
for(;;)
{
PORTD ^= 2;
for (uint8_t x=0; x<20; x++)
_delay_ms(50);
}
Ich glaube mich daran zu erinnern, dass bei 8MHz nur maximal 35ms
Verzögerung mit _delay_ms erreichbar ist.
Kuck mal ins Header-File - da steht es nochmal genau drin.
Mfg
Thomas Pototschnig
www.oxed.de
Um das zu testen würde ich dann 5 * _delay_ms(10) versuchen...

-Klaus-
Steffen Koepf
2005-08-06 17:31:48 UTC
Permalink
Post by Thomas Pototschnig
Ich glaube mich daran zu erinnern, dass bei 8MHz nur maximal 35ms
Verzögerung mit _delay_ms erreichbar ist.
Kuck mal ins Header-File - da steht es nochmal genau drin.
Oder am besten eine Int-Routine Schreiben, die einen Port-Pin
toggelt. Dann diese durch einen Timer-Overflow X-Mal in der
Sekunde aufrufen und mit Oszi messen.


cu,

Steffen
Michael Holzt
2005-08-07 14:14:48 UTC
Permalink
Post by Thomas Pototschnig
Ich glaube mich daran zu erinnern, dass bei 8MHz nur maximal 35ms
Verzögerung mit _delay_ms erreichbar ist.
Ja, Du hast leider recht. Das ärgerliche ist, daß das eigentlich nur eine
Testroutine war, um ein anderes Problem (Empfang auf der Seriellen scheint
nicht zu klappen) einzugrenzen.

Nun gut, die Taktfrequenz ist es wohl dann schon mal doch nicht.
--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Matthias Melcher
2005-08-08 07:53:58 UTC
Permalink
Post by Michael Holzt
Ich habe ein seltsames Problem: Ich habe eine Schaltung mit einem ATmega 8
entwickelt. Da Platz eingespart werden muß, soll die Schaltung mit dem
internen RC-Oszillator bei 8 MHz laufen. Auf einem STK500 Board läuft das
alles auch einwandfrei.
RC oszis sind voelling unzuverlaessig. Ich hab das gleiche problem mit
einem PIC gehabt, der angeblich 4MHz hatte, aber bei meiner Charge von
20 STueck liefen die mit allem zwischen 3,2 und 4,4MHz. Von wegen
kalibireit mit 5% Genauigkeit.

Die Loesung war aber recht einfach: ich erwarte als erstes Byte ueber
die serielle Schnittstelle ein 'u'. Das Bitmuster ist 01010101. Ich
zaehle dann einfach die Cycles von der esten Flake bis zum letzten bit,
und schreibe das Ergebnis in die Zahlerregister fuer den RS232
Taktgeber. Und Schon kann ich prima senden und empfangen. Auf die Art
kann mir nicht nur die Taktfrequenz des PIC Wurscht sein, sondern ich
unterstuetze auch gleich noch mehrere Baudraten, naemlich genau die, mit
der das 'u' gesendet worden ist.
Joerg Wunsch
2005-08-08 10:22:36 UTC
Permalink
Post by Matthias Melcher
RC oszis sind voelling unzuverlaessig. Ich hab das gleiche problem
mit einem PIC gehabt, der angeblich 4MHz hatte, aber bei meiner
Charge von 20 STueck liefen die mit allem zwischen 3,2 und
4,4MHz. Von wegen kalibireit mit 5% Genauigkeit.
Michael hat ja auch keinen PIC. ;-)

Nein, der (kalibrierte) RC-Oszillator des AVR wird seinem Anspruch,
dass man damit ,,aus der Dose raus'' eine RS-232 betreiben kann, nach
allen Berichten wohl ganz gut gerecht.
--
cheers, J"org .-.-. --... ...-- -.. . DL8DTL

http://www.sax.de/~joerg/ NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Michael Holzt
2005-08-08 20:10:33 UTC
Permalink
Post by Joerg Wunsch
Nein, der (kalibrierte) RC-Oszillator des AVR wird seinem Anspruch,
dass man damit ,,aus der Dose raus'' eine RS-232 betreiben kann, nach
allen Berichten wohl ganz gut gerecht.
Das entspricht dem was ich hier festgestellt habe. Allerdings mußte ich
heute feststellen, daß auf die von AVR mitgelieferten Kalibrierbytes
offenbar nicht immer Verlass ist. Angegeben war 0xAA für 8 MHz, aber
beim Abgleich mit einem Oszilloskop habe ich einen genauen Takt erst
bei 0xAE erreicht, und dann funktionierte auch die serielle Schnittstelle
sauber.

Bei einem anderen ATmega8 hingegen war das Kalibrierbyte korrekt. Am besten
wohl nicht ganz auf nen Quarz verzichten, sondern zumindest einen kleinen
32.768 kHz Uhrenquarz (braucht keine Cs) anschließen. Damit kann man den
internen RC-Oszillator recht genau kalibrieren.
--
"Erst war es ein Kernel alle halbe Jahre, zum Schluss konnte ich mit
dem Compilieren nicht mehr aufhören." (Torsten Kleinz im IRC)
Alexander Peter
2005-08-08 08:02:44 UTC
Permalink
Post by Michael Holzt
Ich habe ein seltsames Problem: Ich habe eine Schaltung mit einem ATmega 8
entwickelt. Da Platz eingespart werden muß, soll die Schaltung mit dem
internen RC-Oszillator bei 8 MHz laufen. Auf einem STK500 Board läuft das
alles auch einwandfrei.
Hast Du deinen Oszillator mit dem OSCAL kalibriert?
Zum Test reicht es ja, wenn du Dir das passende Byte bei deinem Prüfling
mit dem Programmer ausliest und in der Startup Phase deines Programm
einfach reinschreibst.

Ansonsten gibt's ja genügend Tips.

Noch ein anderer Tip: Schreib dir dein eigened delay_ms() als asm
Unterprogramm, prüfe die Zeiten im Debugger (AvrStudio) und wiederhole
deine Tests.

Genausogut kannst Du natürlich auch erst dein vorhandenes Programm im
Debugger prüfen...

HTH

Alexander
Loading...