Hallo, ich habe ein Problem mit meinem ATmega8. Dieser sollte eigentlich mit einem externen Quarz auf 8Mhz laufen (die Fuses sind auf Bild2 zu sehen). Wenn ich allerdings die Frequenz messe ist dieser um den Faktor 10 zu langsam d.h. er läuft nur mit 800 khz (siehe Bild 1). Dieses Ergebnis habe ich bekommen indem ich einfach einen IO Pin toggeln lasse: while(1) { PORTC ^= (1<<0); } Hat da jemand eine Idee an was das liegen könnte ? MfG.
Das togglen erfolgt nicht in einem taktzyklus (und selbst dann hättest du nur 4 mhz), schreib lieber ein proggi das einen timer als ausgabe verwendet (und einen festen Teiler hat)...
Deine Schleife braucht vermutlich 5 Takte pro Duchrlauf.
Peter II schrieb: > Max D. schrieb: >> Das togglen erfolgt nicht in einem taktzyklus > > doch macht es. nachtrag: Wenn man es wirklich toggelt, aber ich sehe gerade das er es ja von hand macht. Dann ist es wirklicht nicht der Fall.
Peter II schrieb: > Max D. schrieb: >> Das togglen erfolgt nicht in einem taktzyklus > > doch macht es. naja, der loop verzögert dann, dann hast du nichtmehr einen zyklus (ich wollts einfach halten)
>doch macht es. >PORTC ^= (1<<0); Nein. XOR ist immer: IN Rxx, PORTC EOR Rxx, 0x01 OUT PORTC, Rxx JMP zurück Aber das sollte man im ASM-Listing erkennen. Da kann man zählen. Diese vier Befehle sollten acht Takte brauchen..
Okey das habe ich mir fast gedacht. Allerdings war mir nicht klar das das so gravierend ist da ja immerhin nur 1/10 der original Taktfrequenz übrig bleiben.
µC Neuling schrieb: > Okey das habe ich mir fast gedacht. > Allerdings war mir nicht klar das das so gravierend ist da ja immerhin > nur 1/10 der original Taktfrequenz übrig bleiben. So
1 | while(1) |
2 | {
|
3 | PORTC |= (1<<0); |
4 | PORTC &= ~(1<<0); |
5 | }
|
sollte es schneller gehen. Das müsste dich fast bis auf 2.6Mhz bringen. Allerdings ist die 'Schwingung' dann leicht asymetrisch. Bis auf 4Mhz kommt man dann nur noch mit dem Einsatz eines Timers, den den Pin in Hardware toggelt.
µC Neuling schrieb: > ich habe ein Problem mit meinem ATmega8. Nein, hast du nicht. Du hast vielmehr ein Problem mit dem Verständnis deiner Programmiersprache. Was allerdings insofern entschuldbar ist, als daß es sich um eine Scheißsprache handelt. Allerdings hast du sie selber ausgewählt und zwar ganz offensichtlich falsch für den beabsichtigten Zweck, der ja wohl die Messung einer Taktfrequenz ist. Dafür sind Hochsprachen grundsätzlich ungeeignet, auch Pseudohochsprachen bzw. aufgedonnerte Makroassembler wie C. Weil man einfach nicht vorhersagen kann, was der gewählte Compiler in der gewählten Version mit den gewählten Optimierungsoptionen letztlich für einen Code produziert. In einer richtigen Sprache (natürlich Assembler) siehst du hingegen jederzeit, was genau du tust. Dieser syntaktisch wunderschön aufgedonnerte Bullshit: > while(1) > { > PORTC ^= (1<<0); > } wird vom Compiler (ohne Optimierung) nämlich (bestenfalls) etwa so ausgedrückt: loop: in reg1,PORTC ;1 ldi reg2,1<<0 ;1 eor reg1,reg2 ;1 out PORTC,reg1 ;1 rjmp loop ;2 d.h.: Du müßtest also zwar keine 8 MHz messen, aber immerhin 8/6, also ca. 1,33 Mhz. Keine Ahnung, wie es dein C-Compiler schafft, die Sache noch suboptimaler umzusetzen, aber von 1,33MHz bis 800kHz ist es nicht mehr allzu weit, ich würde es also auf jeden Fall erstmal dem Compiler anlasten. Übrigens: In Assembler schafft man ohne Änderung des Grundkonzeptes wenigstens 8/5=1,6MHz, einfach indem man die Initialisierung von reg2 aus der Schleife holt. Die meisten Compiler schaffen das inzwischen allerdings auch in irgendeiner Optimierung. Mit einem etwas besseren Ansatz, den einem weder Assembler noch Compiler abnehmen können, (zwei Hilfregister, beide vor dem Eintritt in die Schleife initialisiert) schon 8/4=2MHz und bei Ausnutzung eines Features der neueren AVRs (Hardwaretogglen) 8/3=2,67MHz. Und natürlich: Wenn man einen Timer zu Hilfe nimmt, kommt man auf 8/2=4MHz. Und das Ende der Geschichte ist die Benutzung von CLKO, was die Sache dann endgültig auf 8/1=8MHz bringt. Mehr geht absolut nicht. ;o) > Dieser sollte eigentlich mit > einem externen Quarz auf 8Mhz laufen Das tut er aller Wahrscheinlichkeit nach auch.
@kbuchegg: Wie kommst Du denn auf die 2,6MHz? Deine Schleife compiliert hier zu SBI, CBI, RJMP, mit 1, 1 und 2 Takten, es müßten also 2MHz mit einem Puls-Pausen-Verhältnis von 1:3 herauskommen. @c-hater: Du übersiehst, daß bei der XOR-Variante eine Periode des Ausgangssignals zwei Schleifendurchläufe braucht.
c-hater schrieb: > Du müßtest also zwar keine 8 MHz messen, aber immerhin 8/6, also > ca. 1,33 Mhz Das ist nicht die Frequenz, sondern die halbe Periode. Für eine ganze Periode muss die Schleife 2x durchlaufen werden, das wäre dann 665kHz. Bei 800kHz wurde also noch etwas optimiert. Gruß Dietrich
Hier noch eine Variante, die 1MHz symmetrisch schafft:
1 | uint8_t a = PORTC; |
2 | for (;;) { |
3 | a ^= 1; |
4 | PORTC = a; |
5 | }
|
Die eigentliche Schleife besteht dann nur noch aus EOR (1), OUT (1) und RJMP (2).
R. Max schrieb: > @kbuchegg: Wie kommst Du denn auf die 2,6MHz? > > Deine Schleife compiliert hier zu SBI, CBI, RJMP, mit 1, 1 und 2 Takten, > es müßten also 2MHz mit einem Puls-Pausen-Verhältnis von 1:3 > herauskommen. Ah, richtig. rjmp braucht länger. Ich hatte alles mit 1 Takt angesetzt. Danke für die Korrektur.
> Die meisten Compiler schaffen das inzwischen > allerdings auch in irgendeiner Optimierung. Deine Polemik ist nicht zum aushalten. Wenn du von C wenig Ahnung hast und es nicht magst, dann ist das ok. Aber hör bitte auf, den Unsinn auch noch zu verbreiten.
µC Neuling schrieb: > while(1) > { > PORTC ^= (1<<0); > } Bist du auf den alten ATmega8 angewiesen? Wenn du den Nachfolger seines Nachfolgers nimmst, also den ATmega88A und damit einen einigermaßen aktuellen Mikrocontroller, dann kannst du das Togglen so erreichen:
1 | while(1) |
2 | {
|
3 | PINC= (1<<0); |
4 | }
|
Das läuft ungefähr dreimal so schnell, weil es vom Compiler in ganze zwei Assembler-Befehle übersetzt wird, die insgesamt 3 Takte brauchen:
1 | out PINC,(1<<0) |
2 | rjmp PC-1 |
Karl Heinz Buchegger schrieb: > Wenn du von C wenig Ahnung hast und es nicht magst, dann ist das ok. > Aber hör bitte auf, den Unsinn auch noch zu verbreiten. Naja, da er ja offensichtlich von Assembler genauso wenig Ahnung hat (seine Berechnung der resultierenden Frequenz legen dies zumindest nahe), relativieren sich seine Aussagen entsprechend ;-)
Karl Heinz Buchegger schrieb: > Wenn du von C wenig Ahnung hast und es nicht magst, dann ist das ok. Ich habe durchaus Ahnung von C, aber gerade deshalb mag ich die Sprache nicht. Nur Leute, die es gerade so schaffen in C zu programmieren und auch nix anderes können, die mögen C. > Aber hör bitte auf, den Unsinn auch noch zu verbreiten. Das ist kein Unsinn.
Dietrich L. schrieb: > Das ist nicht die Frequenz, sondern die halbe Periode. Für eine ganze > Periode muss die Schleife 2x durchlaufen werden, das wäre dann 665kHz. Ähem, ja natürlich. Peinlich, peinlich...
c-hater schrieb: > Nur Leute, die es gerade so schaffen in C zu programmieren und > auch nix anderes können, die mögen C. ich habe schon in Assembler programmiert als deine Eltern sich wahrscheinlich noch nicht gekannt haben. Anfangs noch von Hand assembliert Hex-Zahlen eingetippt, später mit Assembler und dann endlich C (zwischendurch noch Algol, Fortran, Pascal, Lisp, PL1, ...) und ich kann Dir sagen alles ist besser als Assembler (den ich nur verwende wenn ich irgendwelche Zyklen zählen muss) Ich möchte dich Mal sehen wenn Du einen Compiler oder ein auch nur leicht komplexes Programm in Assembler schreibst.
c-hater schrieb: >> Das ist nicht die Frequenz, sondern die halbe Periode. Für eine ganze >> Periode muss die Schleife 2x durchlaufen werden, das wäre dann 665kHz. > > Ähem, ja natürlich. Peinlich, peinlich... nicht so schlimm, in Assembler kann das schon Mal passieren ;-)
Markus Weber schrieb: > Bist du auf den alten ATmega8 angewiesen? Wenn du den Nachfolger seines > Nachfolgers nimmst, also den ATmega88A und damit einen einigermaßen > aktuellen Mikrocontroller, dann kannst du das Togglen so erreichen Angewiesen bin ich nicht wirklich auf den ATmega8, ich bin im Moment nur ein bisschen am Ausprobieren und hatte mit dazu ein günstiges Starterkit gekauft wo eben dieser ATmega8 dabei war. Mir geht es auch gar nicht darum einen IO Pin mit 8Mhz toggeln zu lassen sondern mich hatte nur gewundert wie die Differenz zwischen Prozessortakt und der Frequenz des IO Pins zustande kommt. Aber das hat sich ja geklärt ;-) MfG.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.